diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2d8cfb37cb764..04cd0d29b76d1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -477,26 +477,31 @@ x-pack/examples/files_example @elastic/kibana-app-services /x-pack/plugins/security_solution/common/detection_engine/schemas/alerts @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/common/field_maps @elastic/security-detections-response-alerts +/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/public/detections/pages/alerts @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/server/lib/detection_engine/migrations @elastic/security-detections-response-alerts -/x-pack/plugins/security_solution/server/lib/detection_engine/notifications @elastic/security-detections-response-alerts -/x-pack/plugins/security_solution/server/lib/detection_engine/schemas @elastic/security-detections-response-alerts +/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/server/lib/detection_engine/rule_types @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/server/lib/detection_engine/signals @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/server/lib/detection_engine/routes/index @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals @elastic/security-detections-response-alerts ## Security Solution sub teams - Detections and Response Rules +/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/common/detection_engine/rule_management @elastic/security-detections-response-rules /x-pack/plugins/security_solution/common/detection_engine/rule_monitoring @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/common/detection_engine/schemas/common @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/common/detection_engine/schemas/request @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/common/detection_engine/schemas/response @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/common/detection_engine/rule_schema @elastic/security-detections-response-rules @elastic/security-detections-response-alerts /x-pack/plugins/security_solution/public/common/components/health_truncate_text @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/common/components/links_to_docs @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/common/components/ml_popover @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/common/components/popover_items @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/public/detection_engine/rule_management @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/detection_engine/rule_monitoring @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/detections/components/callouts @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/detections/components/modals/ml_job_upgrade_modal @elastic/security-detections-response-rules @@ -507,17 +512,12 @@ x-pack/examples/files_example @elastic/kibana-app-services /x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules @elastic/security-detections-response-rules /x-pack/plugins/security_solution/public/rules @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route* @elastic/security-solution-platform -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route* @elastic/security-solution-platform -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route* @elastic/security-solution-platform -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route* @elastic/security-detections-response-alerts -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils @elastic/security-solution-platform -/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management @elastic/security-detections-response-rules /x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/server/lib/detection_engine/rules @elastic/security-detections-response-rules -/x-pack/plugins/security_solution/server/lib/detection_engine/tags @elastic/security-detections-response-rules +/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema @elastic/security-detections-response-rules @elastic/security-detections-response-alerts + /x-pack/plugins/security_solution/server/utils @elastic/security-detections-response-rules ## Security Solution sub teams - Security Platform @@ -527,12 +527,17 @@ x-pack/examples/files_example @elastic/kibana-app-services /x-pack/plugins/security_solution/cypress/e2e/exceptions @elastic/security-solution-platform /x-pack/plugins/security_solution/cypress/e2e/value_lists @elastic/security-solution-platform +/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions @elastic/security-solution-platform + /x-pack/plugins/security_solution/public/detection_engine/rule_exceptions @elastic/security-solution-platform +/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui @elastic/security-solution-platform /x-pack/plugins/security_solution/public/common/components/exceptions @elastic/security-solution-platform /x-pack/plugins/security_solution/public/exceptions @elastic/security-solution-platform /x-pack/plugins/security_solution/public/detections/containers/detection_engine/lists @elastic/security-solution-platform /x-pack/plugins/security_solution/public/common/components/sourcerer @elastic/security-solution-platform +/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy @elastic/security-solution-platform +/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions @elastic/security-solution-platform /x-pack/plugins/security_solution/server/lib/sourcerer @elastic/security-solution-platform ## Security Threat Intelligence - Under Security Platform @@ -595,7 +600,7 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience # Security Intelligence And Analytics -/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules @elastic/security-intelligence-analytics +/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules @elastic/security-intelligence-analytics # Security Asset Management diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/index.ts index 75d5352c9f63e..7a200e4f4c8f9 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/index.ts @@ -20,7 +20,6 @@ export * from './src/default_severity_mapping_array'; export * from './src/default_threat_array'; export * from './src/default_to_string'; export * from './src/default_uuid'; -export * from './src/from'; export * from './src/language'; export * from './src/machine_learning_job_id'; export * from './src/max_signals'; @@ -28,6 +27,7 @@ export * from './src/normalized_ml_job_id'; export * from './src/references_default_array'; export * from './src/risk_score'; export * from './src/risk_score_mapping'; +export * from './src/rule_schedule'; export * from './src/saved_object_attributes'; export * from './src/severity'; export * from './src/severity_mapping'; diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts index 023af9fc7050e..2e0d814bf93c5 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts @@ -6,42 +6,47 @@ * Side Public License, v 1. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import * as t from 'io-ts'; import { saved_object_attributes } from '../saved_object_attributes'; +export type RuleActionGroup = t.TypeOf; +export const RuleActionGroup = t.string; + +export type RuleActionId = t.TypeOf; +export const RuleActionId = t.string; + +export type RuleActionTypeId = t.TypeOf; +export const RuleActionTypeId = t.string; + /** * Params is an "object", since it is a type of RuleActionParams which is action templates. * @see x-pack/plugins/alerting/common/rule.ts */ -export const action_group = t.string; -export const action_id = t.string; -export const action_action_type_id = t.string; -export const action_params = saved_object_attributes; +export type RuleActionParams = t.TypeOf; +export const RuleActionParams = saved_object_attributes; -export const action = t.exact( +export type RuleAction = t.TypeOf; +export const RuleAction = t.exact( t.type({ - group: action_group, - id: action_id, - action_type_id: action_action_type_id, - params: action_params, + group: RuleActionGroup, + id: RuleActionId, + action_type_id: RuleActionTypeId, + params: RuleActionParams, }) ); -export type Action = t.TypeOf; +export type RuleActionArray = t.TypeOf; +export const RuleActionArray = t.array(RuleAction); -export const actions = t.array(action); -export type Actions = t.TypeOf; - -export const actionsCamel = t.array( - t.exact( - t.type({ - group: action_group, - id: action_id, - actionTypeId: action_action_type_id, - params: action_params, - }) - ) +export type RuleActionCamel = t.TypeOf; +export const RuleActionCamel = t.exact( + t.type({ + group: RuleActionGroup, + id: RuleActionId, + actionTypeId: RuleActionTypeId, + params: RuleActionParams, + }) ); -export type ActionsCamel = t.TypeOf; + +export type RuleActionArrayCamel = t.TypeOf; +export const RuleActionArrayCamel = t.array(RuleActionCamel); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_actions_array/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_actions_array/index.ts index 9d741aa65e079..be90cdc0816ef 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_actions_array/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_actions_array/index.ts @@ -8,12 +8,16 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { actions, Actions } from '../actions'; +import { RuleActionArray } from '../actions'; -export const DefaultActionsArray = new t.Type( +export const DefaultActionsArray = new t.Type< + RuleActionArray, + RuleActionArray | undefined, + unknown +>( 'DefaultActionsArray', - actions.is, - (input, context): Either => - input == null ? t.success([]) : actions.validate(input, context), + RuleActionArray.is, + (input, context): Either => + input == null ? t.success([]) : RuleActionArray.validate(input, context), t.identity ); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_from_string/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_from_string/index.ts index 55b76ab7c1a4e..d91499ee36089 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_from_string/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_from_string/index.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { from } from '../from'; +import { From } from '../from'; /** * Types the DefaultFromString as: @@ -21,7 +21,7 @@ export const DefaultFromString = new t.Type if (input == null) { return t.success('now-6m'); } - return from.validate(input, context); + return From.validate(input, context); }, t.identity ); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_risk_score_mapping_array/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_risk_score_mapping_array/index.ts index 8bd913af9255b..6d2314f684f1c 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_risk_score_mapping_array/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_risk_score_mapping_array/index.ts @@ -8,11 +8,11 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { RiskScoreMapping, risk_score_mapping } from '../risk_score_mapping'; +import { RiskScoreMapping } from '../risk_score_mapping'; /** * Types the DefaultStringArray as: - * - If null or undefined, then a default risk_score_mapping array will be set + * - If null or undefined, then a default RiskScoreMapping array will be set */ export const DefaultRiskScoreMappingArray = new t.Type< RiskScoreMapping, @@ -20,8 +20,8 @@ export const DefaultRiskScoreMappingArray = new t.Type< unknown >( 'DefaultRiskScoreMappingArray', - risk_score_mapping.is, + RiskScoreMapping.is, (input, context): Either => - input == null ? t.success([]) : risk_score_mapping.validate(input, context), + input == null ? t.success([]) : RiskScoreMapping.validate(input, context), t.identity ); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_severity_mapping_array/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_severity_mapping_array/index.ts index 58a96eef5a14f..b8e37e45c35f9 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/default_severity_mapping_array/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/default_severity_mapping_array/index.ts @@ -8,11 +8,11 @@ import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; -import { SeverityMapping, severity_mapping } from '../severity_mapping'; +import { SeverityMapping } from '../severity_mapping'; /** * Types the DefaultStringArray as: - * - If null or undefined, then a default severity_mapping array will be set + * - If null or undefined, then a default SeverityMapping array will be set */ export const DefaultSeverityMappingArray = new t.Type< SeverityMapping, @@ -20,8 +20,8 @@ export const DefaultSeverityMappingArray = new t.Type< unknown >( 'DefaultSeverityMappingArray', - severity_mapping.is, + SeverityMapping.is, (input, context): Either => - input == null ? t.success([]) : severity_mapping.validate(input, context), + input == null ? t.success([]) : SeverityMapping.validate(input, context), t.identity ); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/from/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/from/index.ts index 30b3c727d87a2..97747696b90a3 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/from/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/from/index.ts @@ -12,7 +12,8 @@ import { parseScheduleDates } from '@kbn/securitysolution-io-ts-utils'; const stringValidator = (input: unknown): input is string => typeof input === 'string'; -export const from = new t.Type( +export type From = t.TypeOf; +export const From = new t.Type( 'From', t.string.is, (input, context): Either => { @@ -23,7 +24,3 @@ export const from = new t.Type( }, t.identity ); -export type From = t.TypeOf; - -export const fromOrUndefined = t.union([from, t.undefined]); -export type FromOrUndefined = t.TypeOf; diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score/index.ts index 98b9c33e7e3ea..c4f301d6a7c5d 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score/index.ts @@ -6,8 +6,6 @@ * Side Public License, v 1. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import * as t from 'io-ts'; import { Either } from 'fp-ts/lib/Either'; @@ -16,6 +14,7 @@ import { Either } from 'fp-ts/lib/Either'; * - Natural Number (positive integer and not a float), * - Between the values [0 and 100] inclusive. */ +export type RiskScore = t.TypeOf; export const RiskScore = new t.Type( 'RiskScore', t.number.is, @@ -26,11 +25,3 @@ export const RiskScore = new t.Type( }, t.identity ); - -export type RiskScoreC = typeof RiskScore; - -export const risk_score = RiskScore; -export type RiskScore = t.TypeOf; - -export const riskScoreOrUndefined = t.union([risk_score, t.undefined]); -export type RiskScoreOrUndefined = t.TypeOf; diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score_mapping/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score_mapping/index.ts index be07bab64f469..5b56e85cf4e8b 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score_mapping/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/risk_score_mapping/index.ts @@ -6,25 +6,19 @@ * Side Public License, v 1. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import * as t from 'io-ts'; import { operator } from '@kbn/securitysolution-io-ts-types'; -import { riskScoreOrUndefined } from '../risk_score'; +import { RiskScore } from '../risk_score'; -export const risk_score_mapping_field = t.string; -export const risk_score_mapping_value = t.string; -export const risk_score_mapping_item = t.exact( +export type RiskScoreMappingItem = t.TypeOf; +export const RiskScoreMappingItem = t.exact( t.type({ - field: risk_score_mapping_field, - value: risk_score_mapping_value, + field: t.string, + value: t.string, operator, - risk_score: riskScoreOrUndefined, + risk_score: t.union([RiskScore, t.undefined]), }) ); -export const risk_score_mapping = t.array(risk_score_mapping_item); -export type RiskScoreMapping = t.TypeOf; - -export const riskScoreMappingOrUndefined = t.union([risk_score_mapping, t.undefined]); -export type RiskScoreMappingOrUndefined = t.TypeOf; +export type RiskScoreMapping = t.TypeOf; +export const RiskScoreMapping = t.array(RiskScoreMappingItem); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/rule_schedule/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/rule_schedule/index.ts new file mode 100644 index 0000000000000..63fdfafe5631c --- /dev/null +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/rule_schedule/index.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as t from 'io-ts'; +import { From } from '../from'; + +export type RuleInterval = t.TypeOf; +export const RuleInterval = t.string; // we need a more specific schema + +export type RuleIntervalFrom = t.TypeOf; +export const RuleIntervalFrom = From; + +/** + * TODO: Create a regular expression type or custom date math part type here + */ +export type RuleIntervalTo = t.TypeOf; +export const RuleIntervalTo = t.string; // we need a more specific schema diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/severity/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/severity/index.ts index 4caafa6b6ecb2..19a35b56e05b4 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/severity/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/severity/index.ts @@ -8,8 +8,5 @@ import * as t from 'io-ts'; -export const severity = t.keyof({ low: null, medium: null, high: null, critical: null }); -export type Severity = t.TypeOf; - -export const severityOrUndefined = t.union([severity, t.undefined]); -export type SeverityOrUndefined = t.TypeOf; +export type Severity = t.TypeOf; +export const Severity = t.keyof({ low: null, medium: null, high: null, critical: null }); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/severity_mapping/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/severity_mapping/index.ts index 1a3fd50039c29..203f862426c37 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/severity_mapping/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/severity_mapping/index.ts @@ -6,27 +6,20 @@ * Side Public License, v 1. */ -/* eslint-disable @typescript-eslint/naming-convention */ - import * as t from 'io-ts'; import { operator } from '@kbn/securitysolution-io-ts-types'; -import { severity } from '../severity'; +import { Severity } from '../severity'; -export const severity_mapping_field = t.string; -export const severity_mapping_value = t.string; -export const severity_mapping_item = t.exact( +export type SeverityMappingItem = t.TypeOf; +export const SeverityMappingItem = t.exact( t.type({ - field: severity_mapping_field, + field: t.string, operator, - value: severity_mapping_value, - severity, + value: t.string, + severity: Severity, }) ); -export type SeverityMappingItem = t.TypeOf; - -export const severity_mapping = t.array(severity_mapping_item); -export type SeverityMapping = t.TypeOf; -export const severityMappingOrUndefined = t.union([severity_mapping, t.undefined]); -export type SeverityMappingOrUndefined = t.TypeOf; +export type SeverityMapping = t.TypeOf; +export const SeverityMapping = t.array(SeverityMappingItem); diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts index d7d636ad0994e..fbc75ca67693e 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/throttle/index.ts @@ -6,15 +6,12 @@ * Side Public License, v 1. */ -import { TimeDuration } from '@kbn/securitysolution-io-ts-types'; import * as t from 'io-ts'; +import { TimeDuration } from '@kbn/securitysolution-io-ts-types'; -export const throttle = t.union([ +export type RuleActionThrottle = t.TypeOf; +export const RuleActionThrottle = t.union([ t.literal('no_actions'), t.literal('rule'), TimeDuration({ allowedUnits: ['h', 'd'] }), ]); -export type Throttle = t.TypeOf; - -export const throttleOrNull = t.union([throttle, t.null]); -export type ThrottleOrNull = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 7b2c4e034a963..65c5757a1b1bb 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -260,16 +260,12 @@ export const UPDATE_OR_CREATE_LEGACY_ACTIONS = '/internal/api/detection/legacy/n * Detection engine routes */ export const DETECTION_ENGINE_URL = '/api/detection_engine' as const; -export const DETECTION_ENGINE_RULES_URL = `${DETECTION_ENGINE_URL}/rules` as const; -export const DETECTION_ENGINE_PREPACKAGED_URL = - `${DETECTION_ENGINE_RULES_URL}/prepackaged` as const; export const DETECTION_ENGINE_PRIVILEGES_URL = `${DETECTION_ENGINE_URL}/privileges` as const; export const DETECTION_ENGINE_INDEX_URL = `${DETECTION_ENGINE_URL}/index` as const; +export const DETECTION_ENGINE_RULES_URL = `${DETECTION_ENGINE_URL}/rules` as const; export const DETECTION_ENGINE_RULES_URL_FIND = `${DETECTION_ENGINE_RULES_URL}/_find` as const; export const DETECTION_ENGINE_TAGS_URL = `${DETECTION_ENGINE_URL}/tags` as const; -export const DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL = - `${DETECTION_ENGINE_RULES_URL}/prepackaged/_status` as const; export const DETECTION_ENGINE_RULES_BULK_ACTION = `${DETECTION_ENGINE_RULES_URL}/_bulk_action` as const; export const DETECTION_ENGINE_RULES_PREVIEW = `${DETECTION_ENGINE_RULES_URL}/preview` as const; @@ -300,13 +296,9 @@ export const RISK_SCORE_DELETE_STORED_SCRIPT = `${INTERNAL_RISK_SCORE_URL}/store * Internal detection engine routes */ export const INTERNAL_DETECTION_ENGINE_URL = '/internal/detection_engine' as const; -export const INTERNAL_DETECTION_ENGINE_RULES_URL = '/internal/detection_engine/rules' as const; -export const DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL = - `${INTERNAL_DETECTION_ENGINE_URL}/fleet/integrations/installed` as const; export const DETECTION_ENGINE_ALERTS_INDEX_URL = `${INTERNAL_DETECTION_ENGINE_URL}/signal/index` as const; -export const DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL = - `${INTERNAL_DETECTION_ENGINE_RULES_URL}/exceptions/_find_references` as const; + /** * Telemetry detection endpoint for any previews requested of what data we are * providing through UI/UX and for e2e tests. @@ -456,6 +448,7 @@ export const NEW_FEATURES_TOUR_STORAGE_KEYS = { export const RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY = 'securitySolution.ruleDetails.ruleExecutionLog.showMetrics.v8.2'; +// TODO: https://github.com/elastic/kibana/pull/142950 /** * Error codes that can be thrown during _bulk_action API dry_run call and be processed and displayed to end user */ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/get_installed_integrations_response_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/get_installed_integrations/response_schema.ts similarity index 80% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/get_installed_integrations_response_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/get_installed_integrations/response_schema.ts index 882fc3d81828a..d970fb7061a44 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/get_installed_integrations_response_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/get_installed_integrations/response_schema.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { InstalledIntegrationArray } from '../common'; +import type { InstalledIntegrationArray } from '../../model/installed_integrations'; export interface GetInstalledIntegrationsResponse { installed_integrations: InstalledIntegrationArray; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/urls.ts similarity index 53% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/urls.ts index 538348dcc3275..b1216d855284e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/api/urls.ts @@ -5,8 +5,7 @@ * 2.0. */ -import * as t from 'io-ts'; -import { updateRulesSchema } from './rule_schemas'; +import { INTERNAL_DETECTION_ENGINE_URL as INTERNAL_URL } from '../../../constants'; -export const updateRulesBulkSchema = t.array(updateRulesSchema); -export type UpdateRulesBulkSchema = t.TypeOf; +export const GET_INSTALLED_INTEGRATIONS_URL = + `${INTERNAL_URL}/fleet/integrations/installed` as const; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/index.ts similarity index 53% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/index.ts index e877737885925..e79ebecbdb1cd 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/index.ts @@ -5,9 +5,7 @@ * 2.0. */ -import * as t from 'io-ts'; +export * from './api/get_installed_integrations/response_schema'; +export * from './api/urls'; -import { createRulesSchema } from './rule_schemas'; - -export const createRulesBulkSchema = t.array(createRulesSchema); -export type CreateRulesBulkSchema = t.TypeOf; +export * from './model/installed_integrations'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/installed_integrations.ts b/x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/model/installed_integrations.ts similarity index 100% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/installed_integrations.ts rename to x-pack/plugins/security_solution/common/detection_engine/fleet_integrations/model/installed_integrations.ts diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.test.ts similarity index 78% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.test.ts index 8997ecadb36b6..e721e6f41cc19 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.test.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import type { PrePackagedRulesAndTimelinesStatusSchema } from './prepackaged_rules_status_schema'; -import { prePackagedRulesAndTimelinesStatusSchema } from './prepackaged_rules_status_schema'; +import { pipe } from 'fp-ts/lib/pipeable'; import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -describe('prepackaged_rules_schema', () => { +import { GetPrebuiltRulesAndTimelinesStatusResponse } from './response_schema'; + +describe('Get prebuilt rules and timelines status response schema', () => { test('it should validate an empty prepackaged response with defaults', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse = { rules_installed: 0, rules_not_installed: 0, rules_not_updated: 0, @@ -22,7 +22,7 @@ describe('prepackaged_rules_schema', () => { timelines_not_installed: 0, timelines_not_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -31,7 +31,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should not validate an extra invalid field added', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema & { invalid_field: string } = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse & { invalid_field: string } = { rules_installed: 0, rules_not_installed: 0, rules_not_updated: 0, @@ -41,7 +41,7 @@ describe('prepackaged_rules_schema', () => { timelines_not_installed: 0, timelines_not_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -50,7 +50,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response with a negative "rules_installed" number', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse = { rules_installed: -1, rules_not_installed: 0, rules_not_updated: 0, @@ -59,7 +59,7 @@ describe('prepackaged_rules_schema', () => { timelines_not_installed: 0, timelines_not_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -70,7 +70,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response with a negative "rules_not_installed"', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse = { rules_installed: 0, rules_not_installed: -1, rules_not_updated: 0, @@ -79,7 +79,7 @@ describe('prepackaged_rules_schema', () => { timelines_not_installed: 0, timelines_not_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -90,7 +90,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response with a negative "rules_not_updated"', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse = { rules_installed: 0, rules_not_installed: 0, rules_not_updated: -1, @@ -99,7 +99,7 @@ describe('prepackaged_rules_schema', () => { timelines_not_installed: 0, timelines_not_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -110,7 +110,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response with a negative "rules_custom_installed"', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse = { rules_installed: 0, rules_not_installed: 0, rules_not_updated: 0, @@ -119,7 +119,7 @@ describe('prepackaged_rules_schema', () => { timelines_not_installed: 0, timelines_not_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -130,7 +130,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response if "rules_installed" is not there', () => { - const payload: PrePackagedRulesAndTimelinesStatusSchema = { + const payload: GetPrebuiltRulesAndTimelinesStatusResponse = { rules_installed: 0, rules_not_installed: 0, rules_not_updated: 0, @@ -141,7 +141,7 @@ describe('prepackaged_rules_schema', () => { }; // @ts-expect-error delete payload.rules_installed; - const decoded = prePackagedRulesAndTimelinesStatusSchema.decode(payload); + const decoded = GetPrebuiltRulesAndTimelinesStatusResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.ts new file mode 100644 index 0000000000000..f5c26b81682a1 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/response_schema.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { PositiveInteger } from '@kbn/securitysolution-io-ts-types'; + +export type GetPrebuiltRulesAndTimelinesStatusResponse = t.TypeOf< + typeof GetPrebuiltRulesAndTimelinesStatusResponse +>; +export const GetPrebuiltRulesAndTimelinesStatusResponse = t.exact( + t.type({ + rules_custom_installed: PositiveInteger, + rules_installed: PositiveInteger, + rules_not_installed: PositiveInteger, + rules_not_updated: PositiveInteger, + + timelines_installed: PositiveInteger, + timelines_not_installed: PositiveInteger, + timelines_not_updated: PositiveInteger, + }) +); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.test.ts similarity index 76% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.test.ts index 393a071d21b32..6833a5891a2c2 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.test.ts @@ -5,21 +5,21 @@ * 2.0. */ -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import type { PrePackagedRulesAndTimelinesSchema } from './prepackaged_rules_schema'; -import { prePackagedRulesAndTimelinesSchema } from './prepackaged_rules_schema'; +import { pipe } from 'fp-ts/lib/pipeable'; import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -describe('prepackaged_rules_schema', () => { +import { InstallPrebuiltRulesAndTimelinesResponse } from './response_schema'; + +describe('Install prebuilt rules and timelines response schema', () => { test('it should validate an empty prepackaged response with defaults', () => { - const payload: PrePackagedRulesAndTimelinesSchema = { + const payload: InstallPrebuiltRulesAndTimelinesResponse = { rules_installed: 0, rules_updated: 0, timelines_installed: 0, timelines_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesSchema.decode(payload); + const decoded = InstallPrebuiltRulesAndTimelinesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -28,14 +28,14 @@ describe('prepackaged_rules_schema', () => { }); test('it should not validate an extra invalid field added', () => { - const payload: PrePackagedRulesAndTimelinesSchema & { invalid_field: string } = { + const payload: InstallPrebuiltRulesAndTimelinesResponse & { invalid_field: string } = { rules_installed: 0, rules_updated: 0, invalid_field: 'invalid', timelines_installed: 0, timelines_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesSchema.decode(payload); + const decoded = InstallPrebuiltRulesAndTimelinesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -44,13 +44,13 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response with a negative "rules_installed" number', () => { - const payload: PrePackagedRulesAndTimelinesSchema = { + const payload: InstallPrebuiltRulesAndTimelinesResponse = { rules_installed: -1, rules_updated: 0, timelines_installed: 0, timelines_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesSchema.decode(payload); + const decoded = InstallPrebuiltRulesAndTimelinesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -61,13 +61,13 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response with a negative "rules_updated"', () => { - const payload: PrePackagedRulesAndTimelinesSchema = { + const payload: InstallPrebuiltRulesAndTimelinesResponse = { rules_installed: 0, rules_updated: -1, timelines_installed: 0, timelines_updated: 0, }; - const decoded = prePackagedRulesAndTimelinesSchema.decode(payload); + const decoded = InstallPrebuiltRulesAndTimelinesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -78,7 +78,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response if "rules_installed" is not there', () => { - const payload: PrePackagedRulesAndTimelinesSchema = { + const payload: InstallPrebuiltRulesAndTimelinesResponse = { rules_installed: 0, rules_updated: 0, timelines_installed: 0, @@ -86,7 +86,7 @@ describe('prepackaged_rules_schema', () => { }; // @ts-expect-error delete payload.rules_installed; - const decoded = prePackagedRulesAndTimelinesSchema.decode(payload); + const decoded = InstallPrebuiltRulesAndTimelinesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -97,7 +97,7 @@ describe('prepackaged_rules_schema', () => { }); test('it should NOT validate an empty prepackaged response if "rules_updated" is not there', () => { - const payload: PrePackagedRulesAndTimelinesSchema = { + const payload: InstallPrebuiltRulesAndTimelinesResponse = { rules_installed: 0, rules_updated: 0, timelines_installed: 0, @@ -105,7 +105,7 @@ describe('prepackaged_rules_schema', () => { }; // @ts-expect-error delete payload.rules_updated; - const decoded = prePackagedRulesAndTimelinesSchema.decode(payload); + const decoded = InstallPrebuiltRulesAndTimelinesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.ts new file mode 100644 index 0000000000000..7da2d6b1fae03 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/response_schema.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { PositiveInteger } from '@kbn/securitysolution-io-ts-types'; + +export type InstallPrebuiltRulesAndTimelinesResponse = t.TypeOf< + typeof InstallPrebuiltRulesAndTimelinesResponse +>; +export const InstallPrebuiltRulesAndTimelinesResponse = t.exact( + t.type({ + rules_installed: PositiveInteger, + rules_updated: PositiveInteger, + + timelines_installed: PositiveInteger, + timelines_updated: PositiveInteger, + }) +); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/urls.ts similarity index 53% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/urls.ts index 0472c62228c4d..449960916f239 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/api/urls.ts @@ -5,9 +5,7 @@ * 2.0. */ -import * as t from 'io-ts'; +import { DETECTION_ENGINE_RULES_URL as RULES } from '../../../constants'; -import { patchRulesSchema } from './patch_rules_schema'; - -export const patchRulesBulkSchema = t.array(patchRulesSchema); -export type PatchRulesBulkSchema = t.TypeOf; +export const PREBUILT_RULES_URL = `${RULES}/prepackaged` as const; +export const PREBUILT_RULES_STATUS_URL = `${RULES}/prepackaged/_status` as const; diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/index.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/index.ts new file mode 100644 index 0000000000000..5ec8f617f1546 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/index.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/get_prebuilt_rules_and_timelines_status/response_schema'; +export * from './api/install_prebuilt_rules_and_timelines/response_schema'; +export * from './api/urls'; + +export * from './model/prebuilt_rule'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/mocks.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/mocks.ts new file mode 100644 index 0000000000000..2850442ce975c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/mocks.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './model/prebuilt_rule.mock'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.mock.ts similarity index 83% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.mock.ts index 841e0aa5a13da..d81f23cde9966 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.mock.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { AddPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; +import type { PrebuiltRuleToInstall } from './prebuilt_rule'; -export const getAddPrepackagedRulesSchemaMock = (): AddPrepackagedRulesSchema => ({ +export const getPrebuiltRuleMock = (): PrebuiltRuleToInstall => ({ description: 'some description', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', @@ -19,7 +19,7 @@ export const getAddPrepackagedRulesSchemaMock = (): AddPrepackagedRulesSchema => version: 1, }); -export const getAddPrepackagedThreatMatchRulesSchemaMock = (): AddPrepackagedRulesSchema => ({ +export const getPrebuiltThreatMatchRuleMock = (): PrebuiltRuleToInstall => ({ description: 'some description', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.test.ts similarity index 75% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.test.ts index 091ce8bd10fa3..4d08c9391fab8 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.test.ts @@ -5,23 +5,20 @@ * 2.0. */ -import type { AddPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; -import { addPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; - -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import { - getAddPrepackagedRulesSchemaMock, - getAddPrepackagedThreatMatchRulesSchemaMock, -} from './add_prepackaged_rules_schema.mock'; -import { getListArrayMock } from '../types/lists.mock'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { getListArrayMock } from '../../schemas/types/lists.mock'; + +import { PrebuiltRuleToInstall } from './prebuilt_rule'; +import { getPrebuiltRuleMock, getPrebuiltThreatMatchRuleMock } from './prebuilt_rule.mock'; -describe('add prepackaged rules schema', () => { +describe('Prebuilt rule schema', () => { test('empty objects do not validate', () => { - const payload: Partial = {}; + const payload: Partial = {}; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -46,12 +43,12 @@ describe('add prepackaged rules schema', () => { }); test('made up values do not validate', () => { - const payload: AddPrepackagedRulesSchema & { madeUp: string } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall & { madeUp: string } = { + ...getPrebuiltRuleMock(), madeUp: 'hi', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); @@ -59,11 +56,11 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -85,12 +82,12 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -109,13 +106,13 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -134,14 +131,14 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', to: 'now', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -160,7 +157,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, name] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -168,7 +165,7 @@ describe('add prepackaged rules schema', () => { name: 'some-name', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -184,7 +181,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, name, severity] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -193,7 +190,7 @@ describe('add prepackaged rules schema', () => { severity: 'low', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -206,7 +203,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -216,7 +213,7 @@ describe('add prepackaged rules schema', () => { type: 'query', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -227,7 +224,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -238,7 +235,7 @@ describe('add prepackaged rules schema', () => { type: 'query', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -249,7 +246,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -261,7 +258,7 @@ describe('add prepackaged rules schema', () => { index: ['index-1'], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -272,7 +269,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, query, index, interval, version] does validate', () => { - const payload: AddPrepackagedRulesSchema = { + const payload: PrebuiltRuleToInstall = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -287,14 +284,14 @@ describe('add prepackaged rules schema', () => { version: 1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -309,7 +306,7 @@ describe('add prepackaged rules schema', () => { risk_score: 50, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -319,7 +316,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, version] does validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -335,14 +332,14 @@ describe('add prepackaged rules schema', () => { version: 1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does not validate', () => { - const payload: Partial & { output_index: string } = { + const payload: Partial & { output_index: string } = { rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -358,7 +355,7 @@ describe('add prepackaged rules schema', () => { language: 'kuery', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -368,7 +365,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, version] does validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -382,38 +379,38 @@ describe('add prepackaged rules schema', () => { version: 1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can send in a namespace', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), namespace: 'a namespace', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can send in an empty array to threat', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), threat: [], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { - const payload: AddPrepackagedRulesSchema = { + const payload: PrebuiltRuleToInstall = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -444,31 +441,31 @@ describe('add prepackaged rules schema', () => { version: 1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('allows references to be sent as valid', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), references: ['index-1'], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('immutable cannot be set in a pre-packaged rule', () => { - const payload: AddPrepackagedRulesSchema & { immutable: boolean } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall & { immutable: boolean } = { + ...getPrebuiltRuleMock(), immutable: true, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "immutable"']); @@ -476,11 +473,11 @@ describe('add prepackaged rules schema', () => { }); test('rule_id is required', () => { - const payload: AddPrepackagedRulesSchema = getAddPrepackagedRulesSchemaMock(); + const payload: PrebuiltRuleToInstall = getPrebuiltRuleMock(); // @ts-expect-error delete payload.rule_id; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -490,12 +487,12 @@ describe('add prepackaged rules schema', () => { }); test('references cannot be numbers', () => { - const payload: Omit & { references: number[] } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { references: number[] } = { + ...getPrebuiltRuleMock(), references: [5], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); @@ -503,12 +500,12 @@ describe('add prepackaged rules schema', () => { }); test('indexes cannot be numbers', () => { - const payload: Omit & { index: number[] } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { index: number[] } = { + ...getPrebuiltRuleMock(), index: [5], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); @@ -517,23 +514,23 @@ describe('add prepackaged rules schema', () => { test('saved_query type can have filters with it', () => { const payload = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), filters: [], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('filters cannot be a string', () => { - const payload: Omit & { filters: string } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { filters: string } = { + ...getPrebuiltRuleMock(), filters: 'some string', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -544,11 +541,11 @@ describe('add prepackaged rules schema', () => { test('language validates with kuery', () => { const payload = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), language: 'kuery', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -556,23 +553,23 @@ describe('add prepackaged rules schema', () => { test('language validates with lucene', () => { const payload = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), language: 'lucene', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('language does not validate with something made up', () => { - const payload: Omit & { language: string } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { language: string } = { + ...getPrebuiltRuleMock(), language: 'something-made-up', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -582,12 +579,12 @@ describe('add prepackaged rules schema', () => { }); test('max_signals cannot be negative', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), max_signals: -1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -597,12 +594,12 @@ describe('add prepackaged rules schema', () => { }); test('max_signals cannot be zero', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), max_signals: 0, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); @@ -610,36 +607,36 @@ describe('add prepackaged rules schema', () => { }); test('max_signals can be 1', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), max_signals: 1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can optionally send in an array of tags', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), tags: ['tag_1', 'tag_2'], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot send in an array of tags that are numbers', () => { - const payload: Omit & { tags: number[] } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { tags: number[] } = { + ...getPrebuiltRuleMock(), tags: [0, 1, 2], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -651,10 +648,10 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of threat that are missing "framework"', () => { - const payload: Omit & { - threat: Array>>; + const payload: Omit & { + threat: Array>>; } = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), threat: [ { tactic: { @@ -673,7 +670,7 @@ describe('add prepackaged rules schema', () => { ], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -683,10 +680,10 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of threat that are missing "tactic"', () => { - const payload: Omit & { - threat: Array>>; + const payload: Omit & { + threat: Array>>; } = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), threat: [ { framework: 'fake', @@ -701,7 +698,7 @@ describe('add prepackaged rules schema', () => { ], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -711,10 +708,10 @@ describe('add prepackaged rules schema', () => { }); test('You can send in an array of threat that are missing "technique"', () => { - const payload: Omit & { - threat: Array>>; + const payload: Omit & { + threat: Array>>; } = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), threat: [ { framework: 'fake', @@ -727,33 +724,33 @@ describe('add prepackaged rules schema', () => { ], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can optionally send in an array of false positives', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), false_positives: ['false_1', 'false_2'], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot send in an array of false positives that are numbers', () => { - const payload: Omit & { + const payload: Omit & { false_positives: number[]; } = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), false_positives: [5, 4], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -763,12 +760,12 @@ describe('add prepackaged rules schema', () => { expect(message.schema).toEqual({}); }); test('You cannot set the risk_score to 101', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), risk_score: 101, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -778,12 +775,12 @@ describe('add prepackaged rules schema', () => { }); test('You cannot set the risk_score to -1', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), risk_score: -1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); @@ -791,50 +788,50 @@ describe('add prepackaged rules schema', () => { }); test('You can set the risk_score to 0', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), risk_score: 0, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can set the risk_score to 100', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), risk_score: 100, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can set meta to any object you want', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), meta: { somethingMadeUp: { somethingElse: true }, }, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot create meta as a string', () => { - const payload: Omit & { meta: string } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { meta: string } = { + ...getPrebuiltRuleMock(), meta: 'should not work', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -844,25 +841,25 @@ describe('add prepackaged rules schema', () => { }); test('validates with timeline_id and timeline_title', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), timeline_id: 'timeline-id', timeline_title: 'timeline-title', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot set the severity to a value other than low, medium, high, or critical', () => { - const payload: Omit & { severity: string } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { severity: string } = { + ...getPrebuiltRuleMock(), severity: 'junk', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); @@ -870,12 +867,12 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of actions that are missing "group"', () => { - const payload: Omit = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit = { + ...getPrebuiltRuleMock(), actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -885,12 +882,12 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of actions that are missing "id"', () => { - const payload: Omit = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit = { + ...getPrebuiltRuleMock(), actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -900,12 +897,12 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of actions that are missing "action_type_id"', () => { - const payload: Omit = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit = { + ...getPrebuiltRuleMock(), actions: [{ group: 'group', id: 'id', params: {} }], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -915,12 +912,12 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of actions that are missing "params"', () => { - const payload: Omit = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit = { + ...getPrebuiltRuleMock(), actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -930,8 +927,8 @@ describe('add prepackaged rules schema', () => { }); test('You cannot send in an array of actions that are including "actionTypeId"', () => { - const payload: Omit = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit = { + ...getPrebuiltRuleMock(), actions: [ { group: 'group', @@ -942,7 +939,7 @@ describe('add prepackaged rules schema', () => { ], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -953,38 +950,38 @@ describe('add prepackaged rules schema', () => { describe('note', () => { test('You can set note to a string', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), note: '# documentation markdown here', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can set note to an empty string', () => { - const payload: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), note: '', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot create note as an object', () => { - const payload: Omit & { note: {} } = { - ...getAddPrepackagedRulesSchemaMock(), + const payload: Omit & { note: {} } = { + ...getPrebuiltRuleMock(), note: { somethingHere: 'something else', }, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -994,7 +991,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { - const payload: AddPrepackagedRulesSchema = { + const payload: PrebuiltRuleToInstall = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1009,7 +1006,7 @@ describe('add prepackaged rules schema', () => { version: 1, }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1018,7 +1015,7 @@ describe('add prepackaged rules schema', () => { describe('exception_list', () => { test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, version, and exceptions_list] does validate', () => { - const payload: AddPrepackagedRulesSchema = { + const payload: PrebuiltRuleToInstall = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1035,14 +1032,14 @@ describe('add prepackaged rules schema', () => { exceptions_list: getListArrayMock(), }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, version, and empty exceptions_list] does validate', () => { - const payload: AddPrepackagedRulesSchema = { + const payload: PrebuiltRuleToInstall = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1059,7 +1056,7 @@ describe('add prepackaged rules schema', () => { exceptions_list: [], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1083,7 +1080,7 @@ describe('add prepackaged rules schema', () => { exceptions_list: [{ id: 'uuid_here', namespace_type: 'not a namespace type' }], }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1095,7 +1092,7 @@ describe('add prepackaged rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, version, and non-existent exceptions_list] does validate with empty exceptions_list', () => { - const payload: AddPrepackagedRulesSchema = { + const payload: PrebuiltRuleToInstall = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1111,7 +1108,7 @@ describe('add prepackaged rules schema', () => { note: '# some markdown', }; - const decoded = addPrepackagedRulesSchema.decode(payload); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1120,8 +1117,8 @@ describe('add prepackaged rules schema', () => { describe('threat_mapping', () => { test('You can set a threat query, index, mapping, filters on a pre-packaged rule', () => { - const payload = getAddPrepackagedThreatMatchRulesSchemaMock(); - const decoded = addPrepackagedRulesSchema.decode(payload); + const payload = getPrebuiltThreatMatchRuleMock(); + const decoded = PrebuiltRuleToInstall.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.ts similarity index 53% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.ts index a836fc2ba2c10..e46615ee992b7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule.ts @@ -6,23 +6,33 @@ */ import * as t from 'io-ts'; - -import { version } from '@kbn/securitysolution-io-ts-types'; - -import { rule_id, RelatedIntegrationArray, RequiredFieldArray, SetupGuide } from '../common'; -import { baseCreateParams, createTypeSpecific } from './rule_schemas'; +import { + RelatedIntegrationArray, + RequiredFieldArray, + SetupGuide, + RuleSignatureId, + RuleVersion, + BaseCreateProps, + TypeSpecificCreateProps, +} from '../../rule_schema'; /** * Big differences between this schema and the createRulesSchema * - rule_id is required here * - version is a required field that must exist */ -export const addPrepackagedRulesSchema = t.intersection([ - baseCreateParams, - createTypeSpecific, - // version is required in addPrepackagedRulesSchema, so this supercedes the defaultable +export type PrebuiltRuleToInstall = t.TypeOf; +export const PrebuiltRuleToInstall = t.intersection([ + BaseCreateProps, + TypeSpecificCreateProps, + // version is required in PrebuiltRuleToInstall, so this supercedes the defaultable // version in baseParams - t.exact(t.type({ rule_id, version })), + t.exact( + t.type({ + rule_id: RuleSignatureId, + version: RuleVersion, + }) + ), t.exact( t.partial({ related_integrations: RelatedIntegrationArray, @@ -31,4 +41,3 @@ export const addPrepackagedRulesSchema = t.intersection([ }) ), ]); -export type AddPrepackagedRulesSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule_validate_type_dependents.test.ts similarity index 74% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule_validate_type_dependents.test.ts index f9fd09d0a956b..33021d0fc9a1e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule_validate_type_dependents.test.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { AddPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; -import { addPrepackagedRuleValidateTypeDependents } from './add_prepackaged_rules_type_dependents'; -import { getAddPrepackagedRulesSchemaMock } from './add_prepackaged_rules_schema.mock'; +import type { PrebuiltRuleToInstall } from './prebuilt_rule'; +import { addPrepackagedRuleValidateTypeDependents } from './prebuilt_rule_validate_type_dependents'; +import { getPrebuiltRuleMock } from './prebuilt_rule.mock'; -describe('add_prepackaged_rules_type_dependents', () => { +describe('addPrepackagedRuleValidateTypeDependents', () => { test('You cannot omit timeline_title when timeline_id is present', () => { - const schema: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const schema: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), timeline_id: '123', }; delete schema.timeline_title; @@ -21,8 +21,8 @@ describe('add_prepackaged_rules_type_dependents', () => { }); test('You cannot have empty string for timeline_title when timeline_id is present', () => { - const schema: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const schema: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), timeline_id: '123', timeline_title: '', }; @@ -31,8 +31,8 @@ describe('add_prepackaged_rules_type_dependents', () => { }); test('You cannot have timeline_title with an empty timeline_id', () => { - const schema: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const schema: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), timeline_id: '', timeline_title: 'some-title', }; @@ -41,8 +41,8 @@ describe('add_prepackaged_rules_type_dependents', () => { }); test('You cannot have timeline_title without timeline_id', () => { - const schema: AddPrepackagedRulesSchema = { - ...getAddPrepackagedRulesSchemaMock(), + const schema: PrebuiltRuleToInstall = { + ...getPrebuiltRuleMock(), timeline_title: 'some-title', }; delete schema.timeline_id; @@ -52,33 +52,33 @@ describe('add_prepackaged_rules_type_dependents', () => { test('threshold.value is required and has to be bigger than 0 when type is threshold and validates with it', () => { const schema = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), type: 'threshold', threshold: { field: '', value: -1, }, }; - const errors = addPrepackagedRuleValidateTypeDependents(schema as AddPrepackagedRulesSchema); + const errors = addPrepackagedRuleValidateTypeDependents(schema as PrebuiltRuleToInstall); expect(errors).toEqual(['"threshold.value" has to be bigger than 0']); }); test('threshold.field should contain 3 items or less', () => { const schema = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), type: 'threshold', threshold: { field: ['field-1', 'field-2', 'field-3', 'field-4'], value: 1, }, }; - const errors = addPrepackagedRuleValidateTypeDependents(schema as AddPrepackagedRulesSchema); + const errors = addPrepackagedRuleValidateTypeDependents(schema as PrebuiltRuleToInstall); expect(errors).toEqual(['Number of fields must be 3 or less']); }); test('threshold.cardinality[0].field should not be in threshold.field', () => { const schema = { - ...getAddPrepackagedRulesSchemaMock(), + ...getPrebuiltRuleMock(), type: 'threshold', threshold: { field: ['field-1', 'field-2', 'field-3'], @@ -91,7 +91,7 @@ describe('add_prepackaged_rules_type_dependents', () => { ], }, }; - const errors = addPrepackagedRuleValidateTypeDependents(schema as AddPrepackagedRulesSchema); + const errors = addPrepackagedRuleValidateTypeDependents(schema as PrebuiltRuleToInstall); expect(errors).toEqual(['Cardinality of a field that is being aggregated on is always 1']); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule_validate_type_dependents.ts similarity index 79% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.ts rename to x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule_validate_type_dependents.ts index c2595163b83be..3d9264b3f0556 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/add_prepackaged_rules_type_dependents.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/prebuilt_rules/model/prebuilt_rule_validate_type_dependents.ts @@ -5,9 +5,13 @@ * 2.0. */ -import type { AddPrepackagedRulesSchema } from './add_prepackaged_rules_schema'; +import type { PrebuiltRuleToInstall } from './prebuilt_rule'; -export const validateTimelineId = (rule: AddPrepackagedRulesSchema): string[] => { +export const addPrepackagedRuleValidateTypeDependents = (rule: PrebuiltRuleToInstall): string[] => { + return [...validateTimelineId(rule), ...validateTimelineTitle(rule), ...validateThreshold(rule)]; +}; + +const validateTimelineId = (rule: PrebuiltRuleToInstall): string[] => { if (rule.timeline_id != null) { if (rule.timeline_title == null) { return ['when "timeline_id" exists, "timeline_title" must also exist']; @@ -20,7 +24,7 @@ export const validateTimelineId = (rule: AddPrepackagedRulesSchema): string[] => return []; }; -export const validateTimelineTitle = (rule: AddPrepackagedRulesSchema): string[] => { +const validateTimelineTitle = (rule: PrebuiltRuleToInstall): string[] => { if (rule.timeline_title != null) { if (rule.timeline_id == null) { return ['when "timeline_title" exists, "timeline_id" must also exist']; @@ -33,7 +37,7 @@ export const validateTimelineTitle = (rule: AddPrepackagedRulesSchema): string[] return []; }; -export const validateThreshold = (rule: AddPrepackagedRulesSchema): string[] => { +const validateThreshold = (rule: PrebuiltRuleToInstall): string[] => { const errors: string[] = []; if (rule.type === 'threshold') { if (!rule.threshold) { @@ -55,9 +59,3 @@ export const validateThreshold = (rule: AddPrepackagedRulesSchema): string[] => } return errors; }; - -export const addPrepackagedRuleValidateTypeDependents = ( - rule: AddPrepackagedRulesSchema -): string[] => { - return [...validateTimelineId(rule), ...validateTimelineTitle(rule), ...validateThreshold(rule)]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rule_exception_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.test.ts similarity index 62% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rule_exception_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.test.ts index b76d8cd7cfe4a..93b4e9f128a7b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rule_exception_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.test.ts @@ -5,19 +5,47 @@ * 2.0. */ -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import { createRuleExceptionsSchema } from './create_rule_exception_schema'; -import type { CreateRuleExceptionSchema } from './create_rule_exception_schema'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; import { getCreateExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_item_schema.mock'; +import { + CreateRuleExceptionsRequestBody, + CreateRuleExceptionsRequestParams, +} from './request_schema'; + +describe('CreateRuleExceptionsRequestParams', () => { + test('empty objects do not validate', () => { + const payload: Partial = {}; + + const decoded = CreateRuleExceptionsRequestParams.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); + expect(message.schema).toEqual({}); + }); + + test('validates string for id', () => { + const payload: Partial = { + id: '4656dc92-5832-11ea-8e2d-0242ac130003', + }; + + const decoded = CreateRuleExceptionsRequestParams.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual({ + id: '4656dc92-5832-11ea-8e2d-0242ac130003', + }); + }); +}); -describe('createRuleExceptionsSchema', () => { +describe('CreateRuleExceptionsRequestBody', () => { test('empty objects do not validate', () => { - const payload: CreateRuleExceptionSchema = {} as CreateRuleExceptionSchema; + const payload: CreateRuleExceptionsRequestBody = {} as CreateRuleExceptionsRequestBody; - const decoded = createRuleExceptionsSchema.decode(payload); + const decoded = CreateRuleExceptionsRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -27,7 +55,7 @@ describe('createRuleExceptionsSchema', () => { }); test('items without list_id validate', () => { - const payload: CreateRuleExceptionSchema = { + const payload: CreateRuleExceptionsRequestBody = { items: [ { description: 'Exception item for rule default exception list', @@ -45,12 +73,12 @@ describe('createRuleExceptionsSchema', () => { ], }; - const decoded = createRuleExceptionsSchema.decode(payload); + const decoded = CreateRuleExceptionsRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as CreateRuleExceptionSchema).items[0]).toEqual( + expect((message.schema as CreateRuleExceptionsRequestBody).items[0]).toEqual( expect.objectContaining({ comments: [], description: 'Exception item for rule default exception list', @@ -73,9 +101,9 @@ describe('createRuleExceptionsSchema', () => { test('items with list_id do not validate', () => { const payload = { items: [getCreateExceptionListItemSchemaMock()], - } as unknown as CreateRuleExceptionSchema; + } as unknown as CreateRuleExceptionsRequestBody; - const decoded = createRuleExceptionsSchema.decode(payload); + const decoded = CreateRuleExceptionsRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -85,7 +113,7 @@ describe('createRuleExceptionsSchema', () => { }); test('made up parameters do not validate', () => { - const payload: Partial & { madeUp: string } = { + const payload: Partial & { madeUp: string } = { items: [ { description: 'Exception item for rule default exception list', @@ -104,7 +132,7 @@ describe('createRuleExceptionsSchema', () => { madeUp: 'invalid value', }; - const decoded = createRuleExceptionsSchema.decode(payload); + const decoded = CreateRuleExceptionsRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.ts new file mode 100644 index 0000000000000..e5777f9725383 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/create_rule_exceptions/request_schema.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +import type { CreateRuleExceptionListItemSchemaDecoded } from '@kbn/securitysolution-io-ts-list-types'; +import { createRuleExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; +import type { RequiredKeepUndefined } from '@kbn/osquery-plugin/common/types'; + +import { RuleObjectId } from '../../../rule_schema'; + +/** + * URL path parameters of the API route. + */ +export type CreateRuleExceptionsRequestParams = t.TypeOf; +export const CreateRuleExceptionsRequestParams = t.exact( + t.type({ + id: RuleObjectId, + }) +); + +export type CreateRuleExceptionsRequestParamsDecoded = CreateRuleExceptionsRequestParams; + +/** + * Request body parameters of the API route. + */ +export type CreateRuleExceptionsRequestBody = t.TypeOf; +export const CreateRuleExceptionsRequestBody = t.exact( + t.type({ + items: t.array(createRuleExceptionListItemSchema), + }) +); + +/** + * This type is used after a decode since some things are defaults after a decode. + */ +export type CreateRuleExceptionsRequestBodyDecoded = Omit< + RequiredKeepUndefined, + 'items' +> & { + items: CreateRuleExceptionListItemSchemaDecoded[]; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_exception_list_references_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/request_schema.test.ts similarity index 92% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_exception_list_references_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/request_schema.test.ts index 60b7fd9141b29..644924e362d08 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_exception_list_references_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/request_schema.test.ts @@ -6,10 +6,10 @@ */ import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils'; -import { findExceptionReferencesOnRuleSchema } from './find_exception_list_references_schema'; -import type { FindExceptionReferencesOnRuleSchema } from './find_exception_list_references_schema'; +import { findExceptionReferencesOnRuleSchema } from './request_schema'; +import type { FindExceptionReferencesOnRuleSchema } from './request_schema'; -describe('find_exception_list_references_schema', () => { +describe('Find exception list references schema', () => { test('validates all fields', () => { const payload: FindExceptionReferencesOnRuleSchema = { ids: 'abc,def', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_exception_list_references_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/request_schema.ts similarity index 100% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_exception_list_references_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/request_schema.ts diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_exception_list_references_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.test.ts similarity index 97% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_exception_list_references_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.test.ts index d8ab3d64fe783..c899ad46c3628 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_exception_list_references_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.test.ts @@ -6,17 +6,17 @@ */ import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils'; +import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; import { exceptionListRuleReferencesSchema, rulesReferencedByExceptionListsSchema, -} from './find_exception_list_references_schema'; +} from './response_schema'; import type { ExceptionListRuleReferencesSchema, RulesReferencedByExceptionListsSchema, -} from './find_exception_list_references_schema'; -import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; +} from './response_schema'; -describe('find_exception_list_references_schema', () => { +describe('Find exception list references response schema', () => { describe('exceptionListRuleReferencesSchema', () => { test('validates all fields', () => { const payload: ExceptionListRuleReferencesSchema = { diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_exception_list_references_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.ts similarity index 89% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_exception_list_references_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.ts index 2bdcd0ba4cc2b..32589e2d165ea 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/find_exception_list_references_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/find_exception_references/response_schema.ts @@ -6,16 +6,14 @@ */ import * as t from 'io-ts'; - import { exceptionListSchema, listArray, list_id } from '@kbn/securitysolution-io-ts-list-types'; - -import { rule_id, id, name } from '../common/schemas'; +import { RuleName, RuleObjectId, RuleSignatureId } from '../../../rule_schema'; export const ruleReferenceRuleInfoSchema = t.exact( t.type({ - name, - id, - rule_id, + name: RuleName, + id: RuleObjectId, + rule_id: RuleSignatureId, exception_lists: listArray, }) ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/urls.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/urls.ts new file mode 100644 index 0000000000000..1cc8e2ded7483 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/api/urls.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + DETECTION_ENGINE_RULES_URL as PUBLIC_RULES_URL, + INTERNAL_DETECTION_ENGINE_URL as INTERNAL_URL, +} from '../../../constants'; + +const INTERNAL_RULES_URL = `${INTERNAL_URL}/rules`; + +export const CREATE_RULE_EXCEPTIONS_URL = `${PUBLIC_RULES_URL}/{id}/exceptions`; +export const DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL = + `${INTERNAL_RULES_URL}/exceptions/_find_references` as const; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/index.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/index.ts new file mode 100644 index 0000000000000..d4b2fa83a4c58 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_exceptions/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/create_rule_exceptions/request_schema'; +export * from './api/find_exception_references/request_schema'; +export * from './api/find_exception_references/response_schema'; +export * from './api/urls'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.mock.ts similarity index 75% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.mock.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.mock.ts index 1768acc8dfbfa..548d8b571660e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.mock.ts @@ -5,16 +5,16 @@ * 2.0. */ -import { BulkAction, BulkActionEditType } from './perform_bulk_action_schema'; -import type { PerformBulkActionSchema } from './perform_bulk_action_schema'; +import { BulkAction, BulkActionEditType } from './request_schema'; +import type { PerformBulkActionRequestBody } from './request_schema'; -export const getPerformBulkActionSchemaMock = (): PerformBulkActionSchema => ({ +export const getPerformBulkActionSchemaMock = (): PerformBulkActionRequestBody => ({ query: '', ids: undefined, action: BulkAction.disable, }); -export const getPerformBulkActionEditSchemaMock = (): PerformBulkActionSchema => ({ +export const getPerformBulkActionEditSchemaMock = (): PerformBulkActionRequestBody => ({ query: '', ids: undefined, action: BulkAction.edit, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts similarity index 94% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts index e8b276fa44ace..63de1d45ec3cb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts @@ -5,26 +5,21 @@ * 2.0. */ -import type { PerformBulkActionSchema } from './perform_bulk_action_schema'; -import { - performBulkActionSchema, - BulkAction, - BulkActionEditType, -} from './perform_bulk_action_schema'; -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; import { left } from 'fp-ts/lib/Either'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; +import { PerformBulkActionRequestBody, BulkAction, BulkActionEditType } from './request_schema'; const retrieveValidationMessage = (payload: unknown) => { - const decoded = performBulkActionSchema.decode(payload); + const decoded = PerformBulkActionRequestBody.decode(payload); const checked = exactCheck(payload, decoded); return foldLeftRight(checked); }; -describe('perform_bulk_action_schema', () => { +describe('Perform bulk action request schema', () => { describe('cases common to every bulk action', () => { // missing query means it will request for all rules test('valid request: missing query', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: undefined, action: BulkAction.enable, }; @@ -35,7 +30,7 @@ describe('perform_bulk_action_schema', () => { }); test('invalid request: missing action', () => { - const payload: Omit = { + const payload: Omit = { query: 'name: test', }; const message = retrieveValidationMessage(payload); @@ -48,7 +43,7 @@ describe('perform_bulk_action_schema', () => { }); test('invalid request: unknown action', () => { - const payload: Omit & { action: 'unknown' } = { + const payload: Omit & { action: 'unknown' } = { query: 'name: test', action: 'unknown', }; @@ -87,7 +82,7 @@ describe('perform_bulk_action_schema', () => { describe('bulk enable', () => { test('valid request', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.enable, }; @@ -99,7 +94,7 @@ describe('perform_bulk_action_schema', () => { describe('bulk disable', () => { test('valid request', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.disable, }; @@ -111,7 +106,7 @@ describe('perform_bulk_action_schema', () => { describe('bulk export', () => { test('valid request', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.export, }; @@ -123,7 +118,7 @@ describe('perform_bulk_action_schema', () => { describe('bulk delete', () => { test('valid request', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.delete, }; @@ -135,7 +130,7 @@ describe('perform_bulk_action_schema', () => { describe('bulk duplicate', () => { test('valid request', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.duplicate, }; @@ -271,7 +266,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: set_index_patterns edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [{ type: BulkActionEditType.set_index_patterns, value: ['logs-*'] }], @@ -284,7 +279,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: add_index_patterns edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [{ type: BulkActionEditType.add_index_patterns, value: ['logs-*'] }], @@ -297,7 +292,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: delete_index_patterns edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [ @@ -356,7 +351,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: set_timeline edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [ @@ -408,7 +403,7 @@ describe('perform_bulk_action_schema', () => { }, }, ], - } as PerformBulkActionSchema; + } as PerformBulkActionRequestBody; const message = retrieveValidationMessage(payload); @@ -434,7 +429,7 @@ describe('perform_bulk_action_schema', () => { }, }, ], - } as PerformBulkActionSchema; + } as PerformBulkActionRequestBody; const message = retrieveValidationMessage(payload); @@ -460,7 +455,7 @@ describe('perform_bulk_action_schema', () => { }, }, ], - } as PerformBulkActionSchema; + } as PerformBulkActionRequestBody; const message = retrieveValidationMessage(payload); @@ -475,7 +470,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: set_schedule edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [ @@ -487,7 +482,7 @@ describe('perform_bulk_action_schema', () => { }, }, ], - } as PerformBulkActionSchema; + } as PerformBulkActionRequestBody; const message = retrieveValidationMessage(payload); @@ -590,7 +585,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: add_rule_actions edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [ @@ -621,7 +616,7 @@ describe('perform_bulk_action_schema', () => { }); test('valid request: set_rule_actions edit action', () => { - const payload: PerformBulkActionSchema = { + const payload: PerformBulkActionRequestBody = { query: 'name: test', action: BulkAction.edit, [BulkAction.edit]: [ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts similarity index 59% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts index 0140e5f8d9262..6e5248075b7dc 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/perform_bulk_action_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts @@ -6,15 +6,21 @@ */ import * as t from 'io-ts'; -import { NonEmptyArray, TimeDuration, enumeration } from '@kbn/securitysolution-io-ts-types'; +import { NonEmptyArray, TimeDuration } from '@kbn/securitysolution-io-ts-types'; import { - action_group as actionGroup, - action_params as actionParams, - action_id as actionId, + RuleActionGroup, + RuleActionId, + RuleActionParams, } from '@kbn/securitysolution-io-ts-alerting-types'; -import { queryOrUndefined, tags, index, timeline_id, timeline_title } from '../common/schemas'; +import { + IndexPatternArray, + RuleQuery, + RuleTagArray, + TimelineTemplateId, + TimelineTemplateTitle, +} from '../../../../rule_schema'; export enum BulkAction { 'enable' = 'enable', @@ -25,8 +31,6 @@ export enum BulkAction { 'edit' = 'edit', } -export const bulkAction = enumeration('BulkAction', BulkAction); - export enum BulkActionEditType { 'add_tags' = 'add_tags', 'delete_tags' = 'delete_tags', @@ -40,7 +44,8 @@ export enum BulkActionEditType { 'set_schedule' = 'set_schedule', } -export const throttleForBulkActions = t.union([ +export type ThrottleForBulkActions = t.TypeOf; +export const ThrottleForBulkActions = t.union([ t.literal('rule'), TimeDuration({ allowedDurations: [ @@ -50,88 +55,81 @@ export const throttleForBulkActions = t.union([ ], }), ]); -export type ThrottleForBulkActions = t.TypeOf; -const bulkActionEditPayloadTags = t.type({ +type BulkActionEditPayloadTags = t.TypeOf; +const BulkActionEditPayloadTags = t.type({ type: t.union([ t.literal(BulkActionEditType.add_tags), t.literal(BulkActionEditType.delete_tags), t.literal(BulkActionEditType.set_tags), ]), - value: tags, + value: RuleTagArray, }); -export type BulkActionEditPayloadTags = t.TypeOf; - -const bulkActionEditPayloadIndexPatterns = t.intersection([ +type BulkActionEditPayloadIndexPatterns = t.TypeOf; +const BulkActionEditPayloadIndexPatterns = t.intersection([ t.type({ type: t.union([ t.literal(BulkActionEditType.add_index_patterns), t.literal(BulkActionEditType.delete_index_patterns), t.literal(BulkActionEditType.set_index_patterns), ]), - value: index, + value: IndexPatternArray, }), t.exact(t.partial({ overwrite_data_views: t.boolean })), ]); -export type BulkActionEditPayloadIndexPatterns = t.TypeOf< - typeof bulkActionEditPayloadIndexPatterns ->; - -const bulkActionEditPayloadTimeline = t.type({ +type BulkActionEditPayloadTimeline = t.TypeOf; +const BulkActionEditPayloadTimeline = t.type({ type: t.literal(BulkActionEditType.set_timeline), value: t.type({ - timeline_id, - timeline_title, + timeline_id: TimelineTemplateId, + timeline_title: TimelineTemplateTitle, }), }); -export type BulkActionEditPayloadTimeline = t.TypeOf; - /** * per rulesClient.bulkEdit rules actions operation contract (x-pack/plugins/alerting/server/rules_client/rules_client.ts) * normalized rule action object is expected (NormalizedAlertAction) as value for the edit operation */ -const normalizedRuleAction = t.exact( +type NormalizedRuleAction = t.TypeOf; +const NormalizedRuleAction = t.exact( t.type({ - group: actionGroup, - id: actionId, - params: actionParams, + group: RuleActionGroup, + id: RuleActionId, + params: RuleActionParams, }) ); -const bulkActionEditPayloadRuleActions = t.type({ +export type BulkActionEditPayloadRuleActions = t.TypeOf; +export const BulkActionEditPayloadRuleActions = t.type({ type: t.union([ t.literal(BulkActionEditType.add_rule_actions), t.literal(BulkActionEditType.set_rule_actions), ]), value: t.type({ - throttle: throttleForBulkActions, - actions: t.array(normalizedRuleAction), + throttle: ThrottleForBulkActions, + actions: t.array(NormalizedRuleAction), }), }); -export type BulkActionEditPayloadRuleActions = t.TypeOf; - -const bulkActionEditPayloadSchedule = t.type({ +type BulkActionEditPayloadSchedule = t.TypeOf; +const BulkActionEditPayloadSchedule = t.type({ type: t.literal(BulkActionEditType.set_schedule), value: t.type({ interval: TimeDuration({ allowedUnits: ['s', 'm', 'h'] }), lookback: TimeDuration({ allowedUnits: ['s', 'm', 'h'] }), }), }); -export type BulkActionEditPayloadSchedule = t.TypeOf; - -export const bulkActionEditPayload = t.union([ - bulkActionEditPayloadTags, - bulkActionEditPayloadIndexPatterns, - bulkActionEditPayloadTimeline, - bulkActionEditPayloadRuleActions, - bulkActionEditPayloadSchedule, -]); -export type BulkActionEditPayload = t.TypeOf; +export type BulkActionEditPayload = t.TypeOf; +export const BulkActionEditPayload = t.union([ + BulkActionEditPayloadTags, + BulkActionEditPayloadIndexPatterns, + BulkActionEditPayloadTimeline, + BulkActionEditPayloadRuleActions, + BulkActionEditPayloadSchedule, +]); /** * actions that modify rules attributes @@ -149,10 +147,14 @@ export type BulkActionEditForRuleParams = | BulkActionEditPayloadTimeline | BulkActionEditPayloadSchedule; -export const performBulkActionSchema = t.intersection([ +/** + * Request body parameters of the API route. + */ +export type PerformBulkActionRequestBody = t.TypeOf; +export const PerformBulkActionRequestBody = t.intersection([ t.exact( t.type({ - query: queryOrUndefined, + query: t.union([RuleQuery, t.undefined]), }) ), t.exact(t.partial({ ids: NonEmptyArray(t.string) })), @@ -171,16 +173,18 @@ export const performBulkActionSchema = t.intersection([ t.exact( t.type({ action: t.literal(BulkAction.edit), - [BulkAction.edit]: NonEmptyArray(bulkActionEditPayload), + [BulkAction.edit]: NonEmptyArray(BulkActionEditPayload), }) ), ]), ]); -export const performBulkActionQuerySchema = t.exact( +/** + * Query string parameters of the API route. + */ +export type PerformBulkActionRequestQuery = t.TypeOf; +export const PerformBulkActionRequestQuery = t.exact( t.partial({ dry_run: t.union([t.literal('true'), t.literal('false')]), }) ); - -export type PerformBulkActionSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.test.ts similarity index 77% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.test.ts index 5155b593583f9..d2c297d401edb 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.test.ts @@ -5,19 +5,18 @@ * 2.0. */ -import type { CreateRulesBulkSchema } from './create_rules_bulk_schema'; -import { createRulesBulkSchema } from './create_rules_bulk_schema'; +import { BulkCreateRulesRequestBody } from './request_schema'; import { exactCheck, foldLeftRight, formatErrors } from '@kbn/securitysolution-io-ts-utils'; -import { getCreateRulesSchemaMock } from './rule_schemas.mock'; +import { getCreateRulesSchemaMock } from '../../../../../rule_schema/mocks'; // only the basics of testing are here. // see: rule_schemas.test.ts for the bulk of the validation tests // this just wraps createRulesSchema in an array -describe('create_rules_bulk_schema', () => { +describe('Bulk create rules request schema', () => { test('can take an empty array and validate it', () => { - const payload: CreateRulesBulkSchema = []; + const payload: BulkCreateRulesRequestBody = []; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(output.errors).toEqual([]); @@ -27,7 +26,7 @@ describe('create_rules_bulk_schema', () => { test('made up values do not validate for a single element', () => { const payload: Array<{ madeUp: string }> = [{ madeUp: 'hi' }]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toContain( @@ -44,9 +43,9 @@ describe('create_rules_bulk_schema', () => { }); test('single array element does validate', () => { - const payload: CreateRulesBulkSchema = [getCreateRulesSchemaMock()]; + const payload: BulkCreateRulesRequestBody = [getCreateRulesSchemaMock()]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -54,9 +53,12 @@ describe('create_rules_bulk_schema', () => { }); test('two array elements do validate', () => { - const payload: CreateRulesBulkSchema = [getCreateRulesSchemaMock(), getCreateRulesSchemaMock()]; + const payload: BulkCreateRulesRequestBody = [ + getCreateRulesSchemaMock(), + getCreateRulesSchemaMock(), + ]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -67,9 +69,9 @@ describe('create_rules_bulk_schema', () => { const singleItem = getCreateRulesSchemaMock(); // @ts-expect-error delete singleItem.risk_score; - const payload: CreateRulesBulkSchema = [singleItem]; + const payload: BulkCreateRulesRequestBody = [singleItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -83,9 +85,9 @@ describe('create_rules_bulk_schema', () => { const secondItem = getCreateRulesSchemaMock(); // @ts-expect-error delete secondItem.risk_score; - const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkCreateRulesRequestBody = [singleItem, secondItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -99,9 +101,9 @@ describe('create_rules_bulk_schema', () => { const secondItem = getCreateRulesSchemaMock(); // @ts-expect-error delete singleItem.risk_score; - const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkCreateRulesRequestBody = [singleItem, secondItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -117,9 +119,9 @@ describe('create_rules_bulk_schema', () => { delete singleItem.risk_score; // @ts-expect-error delete secondItem.risk_score; - const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkCreateRulesRequestBody = [singleItem, secondItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -134,9 +136,9 @@ describe('create_rules_bulk_schema', () => { madeUpValue: 'something', }; const secondItem = getCreateRulesSchemaMock(); - const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkCreateRulesRequestBody = [singleItem, secondItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); @@ -149,9 +151,9 @@ describe('create_rules_bulk_schema', () => { ...getCreateRulesSchemaMock(), madeUpValue: 'something', }; - const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkCreateRulesRequestBody = [singleItem, secondItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); @@ -167,9 +169,9 @@ describe('create_rules_bulk_schema', () => { ...getCreateRulesSchemaMock(), madeUpValue: 'something', }; - const payload: CreateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkCreateRulesRequestBody = [singleItem, secondItem]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue,madeUpValue"']); @@ -180,7 +182,7 @@ describe('create_rules_bulk_schema', () => { const badSeverity = { ...getCreateRulesSchemaMock(), severity: 'madeup' }; const payload = [badSeverity]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['Invalid value "madeup" supplied to "severity"']); @@ -188,11 +190,11 @@ describe('create_rules_bulk_schema', () => { }); test('You can set "note" to a string', () => { - const payload: CreateRulesBulkSchema = [ + const payload: BulkCreateRulesRequestBody = [ { ...getCreateRulesSchemaMock(), note: '# test markdown' }, ]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -200,9 +202,9 @@ describe('create_rules_bulk_schema', () => { }); test('You can set "note" to an empty string', () => { - const payload: CreateRulesBulkSchema = [{ ...getCreateRulesSchemaMock(), note: '' }]; + const payload: BulkCreateRulesRequestBody = [{ ...getCreateRulesSchemaMock(), note: '' }]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -219,7 +221,7 @@ describe('create_rules_bulk_schema', () => { }, ]; - const decoded = createRulesBulkSchema.decode(payload); + const decoded = BulkCreateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.ts new file mode 100644 index 0000000000000..846da78b4cbba --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_create_rules/request_schema.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { RuleCreateProps } from '../../../../../rule_schema'; + +/** + * Request body parameters of the API route. + */ +export type BulkCreateRulesRequestBody = t.TypeOf; +export const BulkCreateRulesRequestBody = t.array(RuleCreateProps); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.test.ts similarity index 73% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.test.ts index dfbb168f24520..6a709db317109 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.test.ts @@ -5,18 +5,17 @@ * 2.0. */ -import type { QueryRulesBulkSchema } from './query_rules_bulk_schema'; -import { queryRulesBulkSchema } from './query_rules_bulk_schema'; import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils'; +import { BulkDeleteRulesRequestBody } from './request_schema'; // only the basics of testing are here. // see: query_rules_schema.test.ts for the bulk of the validation tests // this just wraps queryRulesSchema in an array -describe('query_rules_bulk_schema', () => { +describe('Bulk delete rules request schema', () => { test('can take an empty array and validate it', () => { - const payload: QueryRulesBulkSchema = []; + const payload: BulkDeleteRulesRequestBody = []; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -24,13 +23,13 @@ describe('query_rules_bulk_schema', () => { }); test('non uuid being supplied to id does not validate', () => { - const payload: QueryRulesBulkSchema = [ + const payload: BulkDeleteRulesRequestBody = [ { id: '1', }, ]; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['Invalid value "1" supplied to "id"']); @@ -38,14 +37,14 @@ describe('query_rules_bulk_schema', () => { }); test('both rule_id and id being supplied do validate', () => { - const payload: QueryRulesBulkSchema = [ + const payload: BulkDeleteRulesRequestBody = [ { rule_id: '1', id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f', }, ]; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -53,12 +52,12 @@ describe('query_rules_bulk_schema', () => { }); test('only id validates with two elements', () => { - const payload: QueryRulesBulkSchema = [ + const payload: BulkDeleteRulesRequestBody = [ { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, ]; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -66,9 +65,11 @@ describe('query_rules_bulk_schema', () => { }); test('only rule_id validates', () => { - const payload: QueryRulesBulkSchema = [{ rule_id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }]; + const payload: BulkDeleteRulesRequestBody = [ + { rule_id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, + ]; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -76,12 +77,12 @@ describe('query_rules_bulk_schema', () => { }); test('only rule_id validates with two elements', () => { - const payload: QueryRulesBulkSchema = [ + const payload: BulkDeleteRulesRequestBody = [ { rule_id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, { rule_id: '2' }, ]; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -89,12 +90,12 @@ describe('query_rules_bulk_schema', () => { }); test('both id and rule_id validates with two separate elements', () => { - const payload: QueryRulesBulkSchema = [ + const payload: BulkDeleteRulesRequestBody = [ { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' }, { rule_id: '2' }, ]; - const decoded = queryRulesBulkSchema.decode(payload); + const decoded = BulkDeleteRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.ts new file mode 100644 index 0000000000000..e290b57b4c404 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_delete_rules/request_schema.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { QueryRuleByIds } from '../../crud/read_rule/query_rule_by_ids'; + +/** + * Request body parameters of the API route. + */ +export type BulkDeleteRulesRequestBody = t.TypeOf; +export const BulkDeleteRulesRequestBody = t.array(QueryRuleByIds); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.test.ts similarity index 72% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.test.ts index 1b9b1f92faf2f..3d466d7d23894 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.test.ts @@ -5,19 +5,18 @@ * 2.0. */ -import type { PatchRulesBulkSchema } from './patch_rules_bulk_schema'; -import { patchRulesBulkSchema } from './patch_rules_bulk_schema'; import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils'; -import type { PatchRulesSchema } from './patch_rules_schema'; +import type { PatchRuleRequestBody } from '../../crud/patch_rule/request_schema'; +import { BulkPatchRulesRequestBody } from './request_schema'; // only the basics of testing are here. // see: patch_rules_schema.test.ts for the bulk of the validation tests // this just wraps patchRulesSchema in an array -describe('patch_rules_bulk_schema', () => { +describe('Bulk patch rules request schema', () => { test('can take an empty array and validate it', () => { - const payload: PatchRulesBulkSchema = []; + const payload: BulkPatchRulesRequestBody = []; - const decoded = patchRulesBulkSchema.decode(payload); + const decoded = BulkPatchRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(output.errors).toEqual([]); @@ -25,9 +24,9 @@ describe('patch_rules_bulk_schema', () => { }); test('single array of [id] does validate', () => { - const payload: PatchRulesBulkSchema = [{ id: '4125761e-51da-4de9-a0c8-42824f532ddb' }]; + const payload: BulkPatchRulesRequestBody = [{ id: '4125761e-51da-4de9-a0c8-42824f532ddb' }]; - const decoded = patchRulesBulkSchema.decode(payload); + const decoded = BulkPatchRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -35,12 +34,12 @@ describe('patch_rules_bulk_schema', () => { }); test('two arrays of [id] validate', () => { - const payload: PatchRulesBulkSchema = [ + const payload: BulkPatchRulesRequestBody = [ { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, { id: '192f403d-b285-4251-9e8b-785fcfcf22e8' }, ]; - const decoded = patchRulesBulkSchema.decode(payload); + const decoded = BulkPatchRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -48,12 +47,12 @@ describe('patch_rules_bulk_schema', () => { }); test('can set "note" to be a string', () => { - const payload: PatchRulesBulkSchema = [ + const payload: BulkPatchRulesRequestBody = [ { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, { note: 'hi' }, ]; - const decoded = patchRulesBulkSchema.decode(payload); + const decoded = BulkPatchRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -61,12 +60,12 @@ describe('patch_rules_bulk_schema', () => { }); test('can set "note" to be an empty string', () => { - const payload: PatchRulesBulkSchema = [ + const payload: BulkPatchRulesRequestBody = [ { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, { note: '' }, ]; - const decoded = patchRulesBulkSchema.decode(payload); + const decoded = BulkPatchRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -74,12 +73,12 @@ describe('patch_rules_bulk_schema', () => { }); test('cannot set "note" to be anything other than a string', () => { - const payload: Array & { note?: object }> = [ + const payload: Array & { note?: object }> = [ { id: '4125761e-51da-4de9-a0c8-42824f532ddb' }, { note: { someprop: 'some value here' } }, ]; - const decoded = patchRulesBulkSchema.decode(payload); + const decoded = BulkPatchRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.ts new file mode 100644 index 0000000000000..2dcd0c2a22d4b --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_patch_rules/request_schema.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { PatchRuleRequestBody } from '../../crud/patch_rule/request_schema'; + +/** + * Request body parameters of the API route. + */ +export type BulkPatchRulesRequestBody = t.TypeOf; +export const BulkPatchRulesRequestBody = t.array(PatchRuleRequestBody); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.test.ts similarity index 74% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.test.ts index 416e43ccfa967..f2b3437273d01 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.test.ts @@ -5,20 +5,19 @@ * 2.0. */ -import type { UpdateRulesBulkSchema } from './update_rules_bulk_schema'; -import { updateRulesBulkSchema } from './update_rules_bulk_schema'; import { exactCheck, formatErrors, foldLeftRight } from '@kbn/securitysolution-io-ts-utils'; -import { getUpdateRulesSchemaMock } from './rule_schemas.mock'; -import type { UpdateRulesSchema } from './rule_schemas'; +import type { RuleUpdateProps } from '../../../../../rule_schema'; +import { getUpdateRulesSchemaMock } from '../../../../../rule_schema/mocks'; +import { BulkUpdateRulesRequestBody } from './request_schema'; // only the basics of testing are here. // see: update_rules_schema.test.ts for the bulk of the validation tests // this just wraps updateRulesSchema in an array -describe('update_rules_bulk_schema', () => { +describe('Bulk update rules request schema', () => { test('can take an empty array and validate it', () => { - const payload: UpdateRulesBulkSchema = []; + const payload: BulkUpdateRulesRequestBody = []; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(output.errors).toEqual([]); @@ -28,7 +27,7 @@ describe('update_rules_bulk_schema', () => { test('made up values do not validate for a single element', () => { const payload: Array<{ madeUp: string }> = [{ madeUp: 'hi' }]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toContain( @@ -45,9 +44,9 @@ describe('update_rules_bulk_schema', () => { }); test('single array element does validate', () => { - const payload: UpdateRulesBulkSchema = [getUpdateRulesSchemaMock()]; + const payload: BulkUpdateRulesRequestBody = [getUpdateRulesSchemaMock()]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -55,9 +54,12 @@ describe('update_rules_bulk_schema', () => { }); test('two array elements do validate', () => { - const payload: UpdateRulesBulkSchema = [getUpdateRulesSchemaMock(), getUpdateRulesSchemaMock()]; + const payload: BulkUpdateRulesRequestBody = [ + getUpdateRulesSchemaMock(), + getUpdateRulesSchemaMock(), + ]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -68,9 +70,9 @@ describe('update_rules_bulk_schema', () => { const singleItem = getUpdateRulesSchemaMock(); // @ts-expect-error delete singleItem.risk_score; - const payload: UpdateRulesBulkSchema = [singleItem]; + const payload: BulkUpdateRulesRequestBody = [singleItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -84,9 +86,9 @@ describe('update_rules_bulk_schema', () => { const secondItem = getUpdateRulesSchemaMock(); // @ts-expect-error delete secondItem.risk_score; - const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkUpdateRulesRequestBody = [singleItem, secondItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -100,9 +102,9 @@ describe('update_rules_bulk_schema', () => { const secondItem = getUpdateRulesSchemaMock(); // @ts-expect-error delete singleItem.risk_score; - const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkUpdateRulesRequestBody = [singleItem, secondItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -118,9 +120,9 @@ describe('update_rules_bulk_schema', () => { delete singleItem.risk_score; // @ts-expect-error delete secondItem.risk_score; - const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkUpdateRulesRequestBody = [singleItem, secondItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ @@ -130,14 +132,14 @@ describe('update_rules_bulk_schema', () => { }); test('two array elements where the first is invalid (extra key and value) but the second is valid will not validate', () => { - const singleItem: UpdateRulesSchema & { madeUpValue: string } = { + const singleItem: RuleUpdateProps & { madeUpValue: string } = { ...getUpdateRulesSchemaMock(), madeUpValue: 'something', }; const secondItem = getUpdateRulesSchemaMock(); const payload = [singleItem, secondItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); @@ -145,14 +147,14 @@ describe('update_rules_bulk_schema', () => { }); test('two array elements where the second is invalid (extra key and value) but the first is valid will not validate', () => { - const singleItem: UpdateRulesSchema = getUpdateRulesSchemaMock(); - const secondItem: UpdateRulesSchema & { madeUpValue: string } = { + const singleItem: RuleUpdateProps = getUpdateRulesSchemaMock(); + const secondItem: RuleUpdateProps & { madeUpValue: string } = { ...getUpdateRulesSchemaMock(), madeUpValue: 'something', }; - const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkUpdateRulesRequestBody = [singleItem, secondItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue"']); @@ -160,17 +162,17 @@ describe('update_rules_bulk_schema', () => { }); test('two array elements where both are invalid (extra key and value) will not validate', () => { - const singleItem: UpdateRulesSchema & { madeUpValue: string } = { + const singleItem: RuleUpdateProps & { madeUpValue: string } = { ...getUpdateRulesSchemaMock(), madeUpValue: 'something', }; - const secondItem: UpdateRulesSchema & { madeUpValue: string } = { + const secondItem: RuleUpdateProps & { madeUpValue: string } = { ...getUpdateRulesSchemaMock(), madeUpValue: 'something', }; - const payload: UpdateRulesBulkSchema = [singleItem, secondItem]; + const payload: BulkUpdateRulesRequestBody = [singleItem, secondItem]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['invalid keys "madeUpValue,madeUpValue"']); @@ -181,7 +183,7 @@ describe('update_rules_bulk_schema', () => { const badSeverity = { ...getUpdateRulesSchemaMock(), severity: 'madeup' }; const payload = [badSeverity]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual(['Invalid value "madeup" supplied to "severity"']); @@ -189,11 +191,11 @@ describe('update_rules_bulk_schema', () => { }); test('You can set "namespace" to a string', () => { - const payload: UpdateRulesBulkSchema = [ + const payload: BulkUpdateRulesRequestBody = [ { ...getUpdateRulesSchemaMock(), namespace: 'a namespace' }, ]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -201,11 +203,11 @@ describe('update_rules_bulk_schema', () => { }); test('You can set "note" to a string', () => { - const payload: UpdateRulesBulkSchema = [ + const payload: BulkUpdateRulesRequestBody = [ { ...getUpdateRulesSchemaMock(), note: '# test markdown' }, ]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -213,9 +215,9 @@ describe('update_rules_bulk_schema', () => { }); test('You can set "note" to an empty string', () => { - const payload: UpdateRulesBulkSchema = [{ ...getUpdateRulesSchemaMock(), note: '' }]; + const payload: BulkUpdateRulesRequestBody = [{ ...getUpdateRulesSchemaMock(), note: '' }]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([]); @@ -232,7 +234,7 @@ describe('update_rules_bulk_schema', () => { }, ]; - const decoded = updateRulesBulkSchema.decode(payload); + const decoded = BulkUpdateRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const output = foldLeftRight(checked); expect(formatErrors(output.errors)).toEqual([ diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.ts new file mode 100644 index 0000000000000..5409e7b2bda43 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/bulk_update_rules/request_schema.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { RuleUpdateProps } from '../../../../../rule_schema'; + +/** + * Request body parameters of the API route. + */ +export type BulkUpdateRulesRequestBody = t.TypeOf; +export const BulkUpdateRulesRequestBody = t.array(RuleUpdateProps); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.test.ts similarity index 70% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.test.ts index 69e31522ef40a..044af119f99ec 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.test.ts @@ -7,20 +7,19 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; - -import type { RulesBulkSchema } from './rules_bulk_schema'; -import { rulesBulkSchema } from './rules_bulk_schema'; -import type { ErrorSchema } from './error_schema'; import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { getRulesSchemaMock } from './rules_schema.mocks'; -import { getErrorSchemaMock } from './error_schema.mocks'; -import type { FullResponseSchema } from '../request'; +import type { RuleResponse } from '../../../../rule_schema'; +import { getRulesSchemaMock } from '../../../../rule_schema/mocks'; +import type { ErrorSchema } from '../../../../schemas/response/error_schema'; +import { getErrorSchemaMock } from '../../../../schemas/response/error_schema.mocks'; + +import { BulkCrudRulesResponse } from './response_schema'; -describe('prepackaged_rule_schema', () => { +describe('Bulk CRUD rules response schema', () => { test('it should validate a regular message and and error together with a uuid', () => { - const payload: RulesBulkSchema = [getRulesSchemaMock(), getErrorSchemaMock()]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [getRulesSchemaMock(), getErrorSchemaMock()]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -29,8 +28,8 @@ describe('prepackaged_rule_schema', () => { }); test('it should validate a regular message and and error together when the error has a non UUID', () => { - const payload: RulesBulkSchema = [getRulesSchemaMock(), getErrorSchemaMock('fake id')]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [getRulesSchemaMock(), getErrorSchemaMock('fake id')]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -39,8 +38,8 @@ describe('prepackaged_rule_schema', () => { }); test('it should validate an error', () => { - const payload: RulesBulkSchema = [getErrorSchemaMock('fake id')]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [getErrorSchemaMock('fake id')]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -52,8 +51,8 @@ describe('prepackaged_rule_schema', () => { const rule = getRulesSchemaMock(); // @ts-expect-error delete rule.name; - const payload: RulesBulkSchema = [rule]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [rule]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -68,8 +67,8 @@ describe('prepackaged_rule_schema', () => { const error = getErrorSchemaMock('fake id'); // @ts-expect-error delete error.error; - const payload: RulesBulkSchema = [error]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [error]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -80,10 +79,10 @@ describe('prepackaged_rule_schema', () => { }); test('it should NOT validate a type of "query" when it has extra data', () => { - const rule: FullResponseSchema & { invalid_extra_data?: string } = getRulesSchemaMock(); + const rule: RuleResponse & { invalid_extra_data?: string } = getRulesSchemaMock(); rule.invalid_extra_data = 'invalid_extra_data'; - const payload: RulesBulkSchema = [rule]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [rule]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -92,10 +91,10 @@ describe('prepackaged_rule_schema', () => { }); test('it should NOT validate a type of "query" when it has extra data next to a valid error', () => { - const rule: FullResponseSchema & { invalid_extra_data?: string } = getRulesSchemaMock(); + const rule: RuleResponse & { invalid_extra_data?: string } = getRulesSchemaMock(); rule.invalid_extra_data = 'invalid_extra_data'; - const payload: RulesBulkSchema = [getErrorSchemaMock(), rule]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [getErrorSchemaMock(), rule]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -107,8 +106,8 @@ describe('prepackaged_rule_schema', () => { type InvalidError = ErrorSchema & { invalid_extra_data?: string }; const error: InvalidError = getErrorSchemaMock(); error.invalid_extra_data = 'invalid'; - const payload: RulesBulkSchema = [error]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [error]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -120,8 +119,8 @@ describe('prepackaged_rule_schema', () => { type InvalidError = ErrorSchema & { invalid_extra_data?: string }; const error: InvalidError = getErrorSchemaMock(); error.invalid_extra_data = 'invalid'; - const payload: RulesBulkSchema = [getRulesSchemaMock(), error]; - const decoded = rulesBulkSchema.decode(payload); + const payload: BulkCrudRulesResponse = [getRulesSchemaMock(), error]; + const decoded = BulkCrudRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.ts new file mode 100644 index 0000000000000..9a0144e2cf758 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_crud/response_schema.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +import { RuleResponse } from '../../../../rule_schema'; +import { errorSchema } from '../../../../schemas/response/error_schema'; + +export type BulkCrudRulesResponse = t.TypeOf; +export const BulkCrudRulesResponse = t.array(t.union([RuleResponse, errorSchema])); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.test.ts similarity index 68% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.test.ts index 1fecd82cc2708..39ed8b028f054 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.test.ts @@ -5,78 +5,81 @@ * 2.0. */ -import { getCreateRulesSchemaMock, getCreateThreatMatchRulesSchemaMock } from './rule_schemas.mock'; -import type { CreateRulesSchema } from './rule_schemas'; -import { createRuleValidateTypeDependents } from './create_rules_type_dependents'; +import type { RuleCreateProps } from '../../../../../rule_schema'; +import { + getCreateRulesSchemaMock, + getCreateThreatMatchRulesSchemaMock, +} from '../../../../../rule_schema/mocks'; +import { validateCreateRuleProps } from './request_schema_validation'; -describe('create_rules_type_dependents', () => { +describe('Create rule request schema, additional validation', () => { test('You cannot omit timeline_title when timeline_id is present', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateRulesSchemaMock(), timeline_id: '123', }; delete schema.timeline_title; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); }); test('You cannot have empty string for timeline_title when timeline_id is present', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateRulesSchemaMock(), timeline_id: '123', timeline_title: '', }; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual(['"timeline_title" cannot be an empty string']); }); test('You cannot have timeline_title with an empty timeline_id', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateRulesSchemaMock(), timeline_id: '', timeline_title: 'some-title', }; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual(['"timeline_id" cannot be an empty string']); }); test('You cannot have timeline_title without timeline_id', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateRulesSchemaMock(), timeline_title: 'some-title', }; delete schema.timeline_id; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); }); test('validates that both "items_per_search" and "concurrent_searches" works when together', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateThreatMatchRulesSchemaMock(), concurrent_searches: 10, items_per_search: 10, }; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual([]); }); test('does NOT validate when only "items_per_search" is present', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateThreatMatchRulesSchemaMock(), items_per_search: 10, }; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual([ 'when "items_per_search" exists, "concurrent_searches" must also exist', ]); }); test('does NOT validate when only "concurrent_searches" is present', () => { - const schema: CreateRulesSchema = { + const schema: RuleCreateProps = { ...getCreateThreatMatchRulesSchemaMock(), concurrent_searches: 10, }; - const errors = createRuleValidateTypeDependents(schema); + const errors = validateCreateRuleProps(schema); expect(errors).toEqual([ 'when "concurrent_searches" exists, "items_per_search" must also exist', ]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.ts new file mode 100644 index 0000000000000..fd2e4b06b63d6 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/create_rule/request_schema_validation.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RuleCreateProps } from '../../../../../rule_schema'; + +/** + * Additional validation that is implemented outside of the schema itself. + */ +export const validateCreateRuleProps = (props: RuleCreateProps): string[] => { + return [ + ...validateTimelineId(props), + ...validateTimelineTitle(props), + ...validateThreatMapping(props), + ...validateThreshold(props), + ]; +}; + +const validateTimelineId = (props: RuleCreateProps): string[] => { + if (props.timeline_id != null) { + if (props.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (props.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +const validateTimelineTitle = (props: RuleCreateProps): string[] => { + if (props.timeline_title != null) { + if (props.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (props.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +const validateThreatMapping = (props: RuleCreateProps): string[] => { + const errors: string[] = []; + if (props.type === 'threat_match') { + if (props.concurrent_searches != null && props.items_per_search == null) { + errors.push('when "concurrent_searches" exists, "items_per_search" must also exist'); + } + if (props.concurrent_searches == null && props.items_per_search != null) { + errors.push('when "items_per_search" exists, "concurrent_searches" must also exist'); + } + } + return errors; +}; + +const validateThreshold = (props: RuleCreateProps): string[] => { + const errors: string[] = []; + if (props.type === 'threshold') { + if (!props.threshold) { + errors.push('when "type" is "threshold", "threshold" is required'); + } else { + if ( + props.threshold.cardinality?.length && + props.threshold.field.includes(props.threshold.cardinality[0].field) + ) { + errors.push('Cardinality of a field that is being aggregated on is always 1'); + } + if (Array.isArray(props.threshold.field) && props.threshold.field.length > 3) { + errors.push('Number of fields must be 3 or less'); + } + } + } + return errors; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.mock.ts similarity index 81% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.mock.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.mock.ts index 1b3dab2e00691..285e773456d98 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.mock.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { PatchRulesSchema, ThresholdPatchSchema } from './patch_rules_schema'; +import type { PatchRuleRequestBody, ThresholdPatchRuleRequestBody } from './request_schema'; -export const getPatchRulesSchemaMock = (): PatchRulesSchema => ({ +export const getPatchRulesSchemaMock = (): PatchRuleRequestBody => ({ description: 'some description', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', @@ -18,7 +18,7 @@ export const getPatchRulesSchemaMock = (): PatchRulesSchema => ({ rule_id: 'rule-1', }); -export const getPatchThresholdRulesSchemaMock = (): ThresholdPatchSchema => ({ +export const getPatchThresholdRulesSchemaMock = (): ThresholdPatchRuleRequestBody => ({ description: 'some description', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.test.ts similarity index 80% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.test.ts index 2084f11ed4efa..36613736e3274 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.test.ts @@ -5,56 +5,56 @@ * 2.0. */ -import type { PatchRulesSchema } from './patch_rules_schema'; -import { patchRulesSchema } from './patch_rules_schema'; -import { getPatchRulesSchemaMock } from './patch_rules_schema.mock'; -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import { getListArrayMock } from '../types/lists.mock'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { getListArrayMock } from '../../../../../schemas/types/lists.mock'; +import { PatchRuleRequestBody } from './request_schema'; +import { getPatchRulesSchemaMock } from './request_schema.mock'; -describe('patch_rules_schema', () => { +describe('Patch rule request schema', () => { test('[id] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', }; expect(message.schema).toEqual(expected); }); test('[rule_id] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', }; expect(message.schema).toEqual(expected); }); test('[rule_id, description] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', }; @@ -62,16 +62,16 @@ describe('patch_rules_schema', () => { }); test('[id, description] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', }; @@ -79,16 +79,16 @@ describe('patch_rules_schema', () => { }); test('[id, risk_score] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', risk_score: 10, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', risk_score: 10, }; @@ -96,17 +96,17 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -115,18 +115,18 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', to: 'now', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -136,18 +136,18 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', to: 'now', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -157,7 +157,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, name] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -165,11 +165,11 @@ describe('patch_rules_schema', () => { name: 'some-name', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -180,7 +180,7 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to, name] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -188,11 +188,11 @@ describe('patch_rules_schema', () => { name: 'some-name', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -203,7 +203,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, name, severity] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -212,11 +212,11 @@ describe('patch_rules_schema', () => { severity: 'low', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -228,7 +228,7 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to, name, severity] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -237,11 +237,11 @@ describe('patch_rules_schema', () => { severity: 'low', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -253,7 +253,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, name, severity, type] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -263,11 +263,11 @@ describe('patch_rules_schema', () => { type: 'query', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -280,7 +280,7 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to, name, severity, type] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -290,11 +290,11 @@ describe('patch_rules_schema', () => { type: 'query', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -307,7 +307,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -318,11 +318,11 @@ describe('patch_rules_schema', () => { type: 'query', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -336,7 +336,7 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to, name, severity, type, interval] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -347,11 +347,11 @@ describe('patch_rules_schema', () => { type: 'query', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -365,7 +365,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -378,11 +378,11 @@ describe('patch_rules_schema', () => { query: 'some query', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -398,7 +398,7 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to, index, name, severity, interval, type, query, language] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -411,11 +411,11 @@ describe('patch_rules_schema', () => { language: 'kuery', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -431,7 +431,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -439,11 +439,11 @@ describe('patch_rules_schema', () => { name: 'some-name', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -454,7 +454,7 @@ describe('patch_rules_schema', () => { }); test('[id, description, from, to, index, name, severity, type, filters] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -466,11 +466,11 @@ describe('patch_rules_schema', () => { filters: [], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -485,7 +485,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, index, name, severity, type, filters] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -497,11 +497,11 @@ describe('patch_rules_schema', () => { filters: [], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -516,7 +516,7 @@ describe('patch_rules_schema', () => { }); test('allows references to be sent as a valid value to patch with', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -531,11 +531,11 @@ describe('patch_rules_schema', () => { language: 'kuery', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', description: 'some description', from: 'now-5m', @@ -553,48 +553,48 @@ describe('patch_rules_schema', () => { }); test('does not default references to an array', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as PatchRulesSchema).references).toEqual(undefined); + expect((message.schema as PatchRuleRequestBody).references).toEqual(undefined); }); test('does not default interval', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as PatchRulesSchema).interval).toEqual(undefined); + expect((message.schema as PatchRuleRequestBody).interval).toEqual(undefined); }); test('does not default max_signals', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as PatchRulesSchema).max_signals).toEqual(undefined); + expect((message.schema as PatchRuleRequestBody).max_signals).toEqual(undefined); }); test('references cannot be numbers', () => { - const payload: Omit & { references: number[] } = { + const payload: Omit & { references: number[] } = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', references: [5], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); @@ -602,13 +602,13 @@ describe('patch_rules_schema', () => { }); test('indexes cannot be numbers', () => { - const payload: Omit & { index: number[] } = { + const payload: Omit & { index: number[] } = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', type: 'query', index: [5], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -619,16 +619,16 @@ describe('patch_rules_schema', () => { }); test('saved_id is not required when type is saved_query and will validate without it', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', type: 'saved_query', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', type: 'saved_query', }; @@ -642,7 +642,7 @@ describe('patch_rules_schema', () => { saved_id: 'some id', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -661,7 +661,7 @@ describe('patch_rules_schema', () => { filters: [], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -680,7 +680,7 @@ describe('patch_rules_schema', () => { language: 'kuery', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -699,7 +699,7 @@ describe('patch_rules_schema', () => { language: 'lucene', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -719,7 +719,7 @@ describe('patch_rules_schema', () => { language: 'something-made-up', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -735,7 +735,7 @@ describe('patch_rules_schema', () => { max_signals: -1, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -751,7 +751,7 @@ describe('patch_rules_schema', () => { max_signals: 0, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); @@ -765,7 +765,7 @@ describe('patch_rules_schema', () => { max_signals: 1, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -778,16 +778,16 @@ describe('patch_rules_schema', () => { }); test('meta can be patched', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { ...getPatchRulesSchemaMock(), meta: { whateverYouWant: 'anything_at_all' }, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { ...getPatchRulesSchemaMock(), meta: { whateverYouWant: 'anything_at_all' }, }; @@ -795,12 +795,12 @@ describe('patch_rules_schema', () => { }); test('You cannot patch meta as a string', () => { - const payload: Omit & { meta: string } = { + const payload: Omit & { meta: string } = { ...getPatchRulesSchemaMock(), meta: 'should not work', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -810,12 +810,12 @@ describe('patch_rules_schema', () => { }); test('filters cannot be a string', () => { - const payload: Omit & { filters: string } = { + const payload: Omit & { filters: string } = { ...getPatchRulesSchemaMock(), filters: 'should not work', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -825,12 +825,12 @@ describe('patch_rules_schema', () => { }); test('name cannot be an empty string', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { ...getPatchRulesSchemaMock(), name: '', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "name"']); @@ -838,12 +838,12 @@ describe('patch_rules_schema', () => { }); test('description cannot be an empty string', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { ...getPatchRulesSchemaMock(), description: '', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "description"']); @@ -851,32 +851,32 @@ describe('patch_rules_schema', () => { }); test('threat is not defaulted to empty array on patch', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as PatchRulesSchema).threat).toEqual(undefined); + expect((message.schema as PatchRuleRequestBody).threat).toEqual(undefined); }); test('threat is not defaulted to undefined on patch with empty array', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', threat: [], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as PatchRulesSchema).threat).toEqual([]); + expect((message.schema as PatchRuleRequestBody).threat).toEqual([]); }); test('threat is valid when updated with all sub-objects', () => { - const threat: PatchRulesSchema['threat'] = [ + const threat: PatchRuleRequestBody['threat'] = [ { framework: 'fake', tactic: { @@ -893,12 +893,12 @@ describe('patch_rules_schema', () => { ], }, ]; - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', threat, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -906,7 +906,7 @@ describe('patch_rules_schema', () => { }); test('threat is invalid when updated with missing property framework', () => { - const threat: Omit = [ + const threat: Omit = [ { tactic: { id: 'fakeId', @@ -922,12 +922,12 @@ describe('patch_rules_schema', () => { ], }, ]; - const payload: Omit = { + const payload: Omit = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', threat, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -937,7 +937,7 @@ describe('patch_rules_schema', () => { }); test('threat is invalid when updated with missing tactic sub-object', () => { - const threat: Omit = [ + const threat: Omit = [ { framework: 'fake', technique: [ @@ -950,12 +950,12 @@ describe('patch_rules_schema', () => { }, ]; - const payload: Omit = { + const payload: Omit = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', threat, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -965,7 +965,7 @@ describe('patch_rules_schema', () => { }); test('threat is valid when updated with missing technique', () => { - const threat: Omit = [ + const threat: Omit = [ { framework: 'fake', tactic: { @@ -976,12 +976,12 @@ describe('patch_rules_schema', () => { }, ]; - const payload: Omit = { + const payload: Omit = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', threat, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -989,17 +989,17 @@ describe('patch_rules_schema', () => { }); test('validates with timeline_id and timeline_title', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { ...getPatchRulesSchemaMock(), timeline_id: 'some-id', timeline_title: 'some-title', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { ...getPatchRulesSchemaMock(), timeline_id: 'some-id', timeline_title: 'some-title', @@ -1008,12 +1008,12 @@ describe('patch_rules_schema', () => { }); test('You cannot set the severity to a value other than low, medium, high, or critical', () => { - const payload: Omit & { severity: string } = { + const payload: Omit & { severity: string } = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', severity: 'junk', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); @@ -1022,7 +1022,7 @@ describe('patch_rules_schema', () => { describe('note', () => { test('[rule_id, description, from, to, index, name, severity, interval, type, note] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1035,11 +1035,11 @@ describe('patch_rules_schema', () => { note: '# some documentation markdown', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1055,16 +1055,16 @@ describe('patch_rules_schema', () => { }); test('note can be patched', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', note: '# new documentation markdown', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', note: '# new documentation markdown', }; @@ -1072,14 +1072,14 @@ describe('patch_rules_schema', () => { }); test('You cannot patch note as an object', () => { - const payload: Omit & { note: object } = { + const payload: Omit & { note: object } = { id: 'b8f95e17-681f-407f-8a5e-b832a77d3831', note: { someProperty: 'something else here', }, }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1090,12 +1090,12 @@ describe('patch_rules_schema', () => { }); test('You cannot send in an array of actions that are missing "group"', () => { - const payload: Omit = { + const payload: Omit = { ...getPatchRulesSchemaMock(), actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1105,12 +1105,12 @@ describe('patch_rules_schema', () => { }); test('You cannot send in an array of actions that are missing "id"', () => { - const payload: Omit = { + const payload: Omit = { ...getPatchRulesSchemaMock(), actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1120,12 +1120,12 @@ describe('patch_rules_schema', () => { }); test('You cannot send in an array of actions that are missing "params"', () => { - const payload: Omit = { + const payload: Omit = { ...getPatchRulesSchemaMock(), actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1135,7 +1135,7 @@ describe('patch_rules_schema', () => { }); test('You cannot send in an array of actions that are including "actionTypeId"', () => { - const payload: Omit = { + const payload: Omit = { ...getPatchRulesSchemaMock(), actions: [ { @@ -1147,7 +1147,7 @@ describe('patch_rules_schema', () => { ], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1158,7 +1158,7 @@ describe('patch_rules_schema', () => { describe('exception_list', () => { test('[rule_id, description, from, to, index, name, severity, interval, type, filters, note, and exceptions_list] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1173,11 +1173,11 @@ describe('patch_rules_schema', () => { exceptions_list: getListArrayMock(), }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1208,7 +1208,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1224,11 +1224,11 @@ describe('patch_rules_schema', () => { exceptions_list: [], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1263,7 +1263,7 @@ describe('patch_rules_schema', () => { exceptions_list: [{ id: 'uuid_here', namespace_type: 'not a namespace type' }], }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1275,7 +1275,7 @@ describe('patch_rules_schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => { - const payload: PatchRulesSchema = { + const payload: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1290,11 +1290,11 @@ describe('patch_rules_schema', () => { note: '# some markdown', }; - const decoded = patchRulesSchema.decode(payload); + const decoded = PatchRuleRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: PatchRulesSchema = { + const expected: PatchRuleRequestBody = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.ts new file mode 100644 index 0000000000000..27a1f14687aa4 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RulePatchProps, ThresholdRulePatchProps } from '../../../../../rule_schema'; + +/** + * Request body parameters of the API route. + * All of the patch elements should default to undefined if not set. + */ +export type PatchRuleRequestBody = RulePatchProps; +export const PatchRuleRequestBody = RulePatchProps; + +export type ThresholdPatchRuleRequestBody = ThresholdRulePatchProps; +export const ThresholdPatchRuleRequestBody = ThresholdRulePatchProps; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.test.ts new file mode 100644 index 0000000000000..c00e3c38fb91b --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.test.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PatchRuleRequestBody, ThresholdPatchRuleRequestBody } from './request_schema'; +import { getPatchRulesSchemaMock, getPatchThresholdRulesSchemaMock } from './request_schema.mock'; +import { validatePatchRuleRequestBody } from './request_schema_validation'; + +describe('Patch rule request schema, additional validation', () => { + describe('validatePatchRuleRequestBody', () => { + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: PatchRuleRequestBody = { + ...getPatchRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: PatchRuleRequestBody = { + ...getPatchRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: PatchRuleRequestBody = { + ...getPatchRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: PatchRuleRequestBody = { + ...getPatchRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); + + test('You cannot have both an id and a rule_id', () => { + const schema: PatchRuleRequestBody = { + ...getPatchRulesSchemaMock(), + id: 'some-id', + rule_id: 'some-rule-id', + }; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); + }); + + test('You must set either an id or a rule_id', () => { + const schema: PatchRuleRequestBody = { + ...getPatchRulesSchemaMock(), + }; + delete schema.id; + delete schema.rule_id; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['either "id" or "rule_id" must be set']); + }); + + test('threshold.value is required and has to be bigger than 0 when type is threshold and validates with it', () => { + const schema: ThresholdPatchRuleRequestBody = { + ...getPatchThresholdRulesSchemaMock(), + threshold: { + field: '', + value: -1, + }, + }; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['"threshold.value" has to be bigger than 0']); + }); + + test('threshold.field should contain 3 items or less', () => { + const schema: ThresholdPatchRuleRequestBody = { + ...getPatchThresholdRulesSchemaMock(), + threshold: { + field: ['field-1', 'field-2', 'field-3', 'field-4'], + value: 1, + }, + }; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['Number of fields must be 3 or less']); + }); + + test('threshold.cardinality[0].field should not be in threshold.field', () => { + const schema: ThresholdPatchRuleRequestBody = { + ...getPatchThresholdRulesSchemaMock(), + threshold: { + field: ['field-1', 'field-2', 'field-3'], + value: 1, + cardinality: [ + { + field: 'field-1', + value: 2, + }, + ], + }, + }; + const errors = validatePatchRuleRequestBody(schema); + expect(errors).toEqual(['Cardinality of a field that is being aggregated on is always 1']); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.ts similarity index 80% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.ts index 263f28e28ac30..72d10bf5e58de 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/patch_rule/request_schema_validation.ts @@ -5,9 +5,31 @@ * 2.0. */ -import type { PatchRulesSchema } from './patch_rules_schema'; +import type { PatchRuleRequestBody } from './request_schema'; -export const validateTimelineId = (rule: PatchRulesSchema): string[] => { +/** + * Additional validation that is implemented outside of the schema itself. + */ +export const validatePatchRuleRequestBody = (rule: PatchRuleRequestBody): string[] => { + return [ + ...validateId(rule), + ...validateTimelineId(rule), + ...validateTimelineTitle(rule), + ...validateThreshold(rule), + ]; +}; + +const validateId = (rule: PatchRuleRequestBody): string[] => { + if (rule.id != null && rule.rule_id != null) { + return ['both "id" and "rule_id" cannot exist, choose one or the other']; + } else if (rule.id == null && rule.rule_id == null) { + return ['either "id" or "rule_id" must be set']; + } else { + return []; + } +}; + +const validateTimelineId = (rule: PatchRuleRequestBody): string[] => { if (rule.timeline_id != null) { if (rule.timeline_title == null) { return ['when "timeline_id" exists, "timeline_title" must also exist']; @@ -20,7 +42,7 @@ export const validateTimelineId = (rule: PatchRulesSchema): string[] => { return []; }; -export const validateTimelineTitle = (rule: PatchRulesSchema): string[] => { +const validateTimelineTitle = (rule: PatchRuleRequestBody): string[] => { if (rule.timeline_title != null) { if (rule.timeline_id == null) { return ['when "timeline_title" exists, "timeline_id" must also exist']; @@ -33,17 +55,7 @@ export const validateTimelineTitle = (rule: PatchRulesSchema): string[] => { return []; }; -export const validateId = (rule: PatchRulesSchema): string[] => { - if (rule.id != null && rule.rule_id != null) { - return ['both "id" and "rule_id" cannot exist, choose one or the other']; - } else if (rule.id == null && rule.rule_id == null) { - return ['either "id" or "rule_id" must be set']; - } else { - return []; - } -}; - -export const validateThreshold = (rule: PatchRulesSchema): string[] => { +const validateThreshold = (rule: PatchRuleRequestBody): string[] => { const errors: string[] = []; if (rule.type === 'threshold') { if (!rule.threshold) { @@ -65,12 +77,3 @@ export const validateThreshold = (rule: PatchRulesSchema): string[] => { } return errors; }; - -export const patchRuleValidateTypeDependents = (rule: PatchRulesSchema): string[] => { - return [ - ...validateId(rule), - ...validateTimelineId(rule), - ...validateTimelineTitle(rule), - ...validateThreshold(rule), - ]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.test.ts similarity index 72% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.test.ts index faccffb1e6864..d5ba9b37ae65a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.test.ts @@ -5,17 +5,16 @@ * 2.0. */ -import type { QueryRulesSchema } from './query_rules_schema'; -import { queryRulesSchema } from './query_rules_schema'; -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; +import { QueryRuleByIds } from './query_rule_by_ids'; -describe('query_rules_schema', () => { +describe('Query rule by IDs schema', () => { test('empty objects do validate', () => { - const payload: Partial = {}; + const payload: Partial = {}; - const decoded = queryRulesSchema.decode(payload); + const decoded = QueryRuleByIds.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.ts similarity index 56% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.ts index 704c2307181b9..d52d8c66125e6 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids.ts @@ -6,15 +6,12 @@ */ import * as t from 'io-ts'; +import { RuleObjectId, RuleSignatureId } from '../../../../../rule_schema'; -import { rule_id, id } from '../common/schemas'; - -export const queryRulesSchema = t.exact( +export type QueryRuleByIds = t.TypeOf; +export const QueryRuleByIds = t.exact( t.partial({ - rule_id, - id, + rule_id: RuleSignatureId, + id: RuleObjectId, }) ); - -export type QueryRulesSchema = t.TypeOf; -export type QueryRulesSchemaDecoded = QueryRulesSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.test.ts similarity index 61% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.test.ts index 060fd189a40a9..1d0981df5f411 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.test.ts @@ -5,22 +5,22 @@ * 2.0. */ -import type { QueryRulesSchema } from './query_rules_schema'; -import { queryRuleValidateTypeDependents } from './query_rules_type_dependents'; +import type { QueryRuleByIds } from './query_rule_by_ids'; +import { validateQueryRuleByIds } from './query_rule_by_ids_validation'; -describe('query_rules_type_dependents', () => { +describe('Query rule by IDs schema, additional validation', () => { test('You cannot have both an id and a rule_id', () => { - const schema: QueryRulesSchema = { + const schema: QueryRuleByIds = { id: 'some-id', rule_id: 'some-rule-id', }; - const errors = queryRuleValidateTypeDependents(schema); + const errors = validateQueryRuleByIds(schema); expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); }); test('You must set either an id or a rule_id', () => { - const schema: QueryRulesSchema = {}; - const errors = queryRuleValidateTypeDependents(schema); + const schema: QueryRuleByIds = {}; + const errors = validateQueryRuleByIds(schema); expect(errors).toEqual(['either "id" or "rule_id" must be set']); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.ts similarity index 66% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.ts index a646d0e97f96a..4f0a7eedc71dd 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_type_dependents.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/read_rule/query_rule_by_ids_validation.ts @@ -5,9 +5,16 @@ * 2.0. */ -import type { QueryRulesSchema } from './query_rules_schema'; +import type { QueryRuleByIds } from './query_rule_by_ids'; -export const validateId = (rule: QueryRulesSchema): string[] => { +/** + * Additional validation that is implemented outside of the schema itself. + */ +export const validateQueryRuleByIds = (schema: QueryRuleByIds): string[] => { + return [...validateId(schema)]; +}; + +const validateId = (rule: QueryRuleByIds): string[] => { if (rule.id != null && rule.rule_id != null) { return ['both "id" and "rule_id" cannot exist, choose one or the other']; } else if (rule.id == null && rule.rule_id == null) { @@ -16,7 +23,3 @@ export const validateId = (rule: QueryRulesSchema): string[] => { return []; } }; - -export const queryRuleValidateTypeDependents = (schema: QueryRulesSchema): string[] => { - return [...validateId(schema)]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.test.ts similarity index 68% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.test.ts index e2f5024418005..f6a8d0bb39340 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.test.ts @@ -5,68 +5,68 @@ * 2.0. */ -import { getUpdateRulesSchemaMock } from './rule_schemas.mock'; -import type { UpdateRulesSchema } from './rule_schemas'; -import { updateRuleValidateTypeDependents } from './update_rules_type_dependents'; +import type { RuleUpdateProps } from '../../../../../rule_schema'; +import { getUpdateRulesSchemaMock } from '../../../../../rule_schema/mocks'; +import { validateUpdateRuleProps } from './request_schema_validation'; -describe('update_rules_type_dependents', () => { +describe('Update rule request schema, additional validation', () => { test('You cannot omit timeline_title when timeline_id is present', () => { - const schema: UpdateRulesSchema = { + const schema: RuleUpdateProps = { ...getUpdateRulesSchemaMock(), timeline_id: '123', }; delete schema.timeline_title; - const errors = updateRuleValidateTypeDependents(schema); + const errors = validateUpdateRuleProps(schema); expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); }); test('You cannot have empty string for timeline_title when timeline_id is present', () => { - const schema: UpdateRulesSchema = { + const schema: RuleUpdateProps = { ...getUpdateRulesSchemaMock(), timeline_id: '123', timeline_title: '', }; - const errors = updateRuleValidateTypeDependents(schema); + const errors = validateUpdateRuleProps(schema); expect(errors).toEqual(['"timeline_title" cannot be an empty string']); }); test('You cannot have timeline_title with an empty timeline_id', () => { - const schema: UpdateRulesSchema = { + const schema: RuleUpdateProps = { ...getUpdateRulesSchemaMock(), timeline_id: '', timeline_title: 'some-title', }; - const errors = updateRuleValidateTypeDependents(schema); + const errors = validateUpdateRuleProps(schema); expect(errors).toEqual(['"timeline_id" cannot be an empty string']); }); test('You cannot have timeline_title without timeline_id', () => { - const schema: UpdateRulesSchema = { + const schema: RuleUpdateProps = { ...getUpdateRulesSchemaMock(), timeline_title: 'some-title', }; delete schema.timeline_id; - const errors = updateRuleValidateTypeDependents(schema); + const errors = validateUpdateRuleProps(schema); expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); }); test('You cannot have both an id and a rule_id', () => { - const schema: UpdateRulesSchema = { + const schema: RuleUpdateProps = { ...getUpdateRulesSchemaMock(), id: 'some-id', rule_id: 'some-rule-id', }; - const errors = updateRuleValidateTypeDependents(schema); + const errors = validateUpdateRuleProps(schema); expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); }); test('You must set either an id or a rule_id', () => { - const schema: UpdateRulesSchema = { + const schema: RuleUpdateProps = { ...getUpdateRulesSchemaMock(), }; delete schema.id; delete schema.rule_id; - const errors = updateRuleValidateTypeDependents(schema); + const errors = validateUpdateRuleProps(schema); expect(errors).toEqual(['either "id" or "rule_id" must be set']); }); }); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.ts new file mode 100644 index 0000000000000..09d1e1e7b0a99 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/crud/update_rule/request_schema_validation.ts @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RuleUpdateProps } from '../../../../../rule_schema'; + +/** + * Additional validation that is implemented outside of the schema itself. + */ +export const validateUpdateRuleProps = (props: RuleUpdateProps): string[] => { + return [ + ...validateId(props), + ...validateTimelineId(props), + ...validateTimelineTitle(props), + ...validateThreshold(props), + ]; +}; + +const validateId = (props: RuleUpdateProps): string[] => { + if (props.id != null && props.rule_id != null) { + return ['both "id" and "rule_id" cannot exist, choose one or the other']; + } else if (props.id == null && props.rule_id == null) { + return ['either "id" or "rule_id" must be set']; + } else { + return []; + } +}; + +const validateTimelineId = (props: RuleUpdateProps): string[] => { + if (props.timeline_id != null) { + if (props.timeline_title == null) { + return ['when "timeline_id" exists, "timeline_title" must also exist']; + } else if (props.timeline_id === '') { + return ['"timeline_id" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +const validateTimelineTitle = (props: RuleUpdateProps): string[] => { + if (props.timeline_title != null) { + if (props.timeline_id == null) { + return ['when "timeline_title" exists, "timeline_id" must also exist']; + } else if (props.timeline_title === '') { + return ['"timeline_title" cannot be an empty string']; + } else { + return []; + } + } + return []; +}; + +const validateThreshold = (props: RuleUpdateProps): string[] => { + const errors: string[] = []; + if (props.type === 'threshold') { + if (!props.threshold) { + errors.push('when "type" is "threshold", "threshold" is required'); + } else { + if ( + props.threshold.cardinality?.length && + props.threshold.field.includes(props.threshold.cardinality[0].field) + ) { + errors.push('Cardinality of a field that is being aggregated on is always 1'); + } + if (Array.isArray(props.threshold.field) && props.threshold.field.length > 3) { + errors.push('Number of fields must be 3 or less'); + } + } + } + return errors; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.test.ts similarity index 72% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.test.ts index d2b29a5152e96..0e0ec3cbaca3b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.test.ts @@ -5,22 +5,19 @@ * 2.0. */ -import type { - ExportRulesSchema, - ExportRulesQuerySchema, - ExportRulesQuerySchemaDecoded, -} from './export_rules_schema'; -import { exportRulesQuerySchema, exportRulesSchema } from './export_rules_schema'; -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { ExportRulesRequestBody, ExportRulesRequestQuery } from './request_schema'; +import type { ExportRulesRequestQueryDecoded } from './request_schema'; -describe('create rules schema', () => { - describe('exportRulesSchema', () => { +describe('Export rules request schema', () => { + describe('ExportRulesRequestBody', () => { test('null value or absent values validate', () => { - const payload: Partial = null; + const payload: Partial = null; - const decoded = exportRulesSchema.decode(payload); + const decoded = ExportRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -30,7 +27,7 @@ describe('create rules schema', () => { test('empty object does not validate', () => { const payload = {}; - const decoded = exportRulesSchema.decode(payload); + const decoded = ExportRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -41,9 +38,9 @@ describe('create rules schema', () => { }); test('empty object array does validate', () => { - const payload: ExportRulesSchema = { objects: [] }; + const payload: ExportRulesRequestBody = { objects: [] }; - const decoded = exportRulesSchema.decode(payload); + const decoded = ExportRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -51,9 +48,9 @@ describe('create rules schema', () => { }); test('array with rule_id validates', () => { - const payload: ExportRulesSchema = { objects: [{ rule_id: 'test-1' }] }; + const payload: ExportRulesRequestBody = { objects: [{ rule_id: 'test-1' }] }; - const decoded = exportRulesSchema.decode(payload); + const decoded = ExportRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -61,11 +58,11 @@ describe('create rules schema', () => { }); test('array with id does not validate as we do not allow that on purpose since we export rule_id', () => { - const payload: Omit & { objects: [{ id: string }] } = { + const payload: Omit & { objects: [{ id: string }] } = { objects: [{ id: '4a7ff83d-3055-4bb2-ba68-587b9c6c15a4' }], }; - const decoded = exportRulesSchema.decode(payload); + const decoded = ExportRulesRequestBody.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -76,15 +73,15 @@ describe('create rules schema', () => { }); }); - describe('exportRulesQuerySchema', () => { + describe('ExportRulesRequestQuery', () => { test('default value for file_name is export.ndjson and default for exclude_export_details is false', () => { - const payload: Partial = {}; + const payload: Partial = {}; - const decoded = exportRulesQuerySchema.decode(payload); + const decoded = ExportRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: ExportRulesQuerySchemaDecoded = { + const expected: ExportRulesRequestQueryDecoded = { file_name: 'export.ndjson', exclude_export_details: false, }; @@ -93,15 +90,15 @@ describe('create rules schema', () => { }); test('file_name validates', () => { - const payload: ExportRulesQuerySchema = { + const payload: ExportRulesRequestQuery = { file_name: 'test.ndjson', }; - const decoded = exportRulesQuerySchema.decode(payload); + const decoded = ExportRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: ExportRulesQuerySchemaDecoded = { + const expected: ExportRulesRequestQueryDecoded = { file_name: 'test.ndjson', exclude_export_details: false, }; @@ -110,11 +107,11 @@ describe('create rules schema', () => { }); test('file_name does not validate with a number', () => { - const payload: Omit & { file_name: number } = { + const payload: Omit & { file_name: number } = { file_name: 10, }; - const decoded = exportRulesQuerySchema.decode(payload); + const decoded = ExportRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -124,15 +121,15 @@ describe('create rules schema', () => { }); test('exclude_export_details validates with a boolean true', () => { - const payload: ExportRulesQuerySchema = { + const payload: ExportRulesRequestQuery = { exclude_export_details: true, }; - const decoded = exportRulesQuerySchema.decode(payload); + const decoded = ExportRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - const expected: ExportRulesQuerySchemaDecoded = { + const expected: ExportRulesRequestQueryDecoded = { exclude_export_details: true, file_name: 'export.ndjson', }; @@ -140,13 +137,13 @@ describe('create rules schema', () => { }); test('exclude_export_details does not validate with a string', () => { - const payload: Omit & { + const payload: Omit & { exclude_export_details: string; } = { exclude_export_details: 'invalid string', }; - const decoded = exportRulesQuerySchema.decode(payload); + const decoded = ExportRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.ts new file mode 100644 index 0000000000000..682e69e55d5a4 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/export_rules/request_schema.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { DefaultExportFileName } from '@kbn/securitysolution-io-ts-alerting-types'; +import { DefaultStringBooleanFalse } from '@kbn/securitysolution-io-ts-types'; + +import type { FileName, ExcludeExportDetails } from '../../../../schemas/common/schemas'; +import { RuleSignatureId } from '../../../../rule_schema'; + +const ObjectsWithRuleId = t.array(t.exact(t.type({ rule_id: RuleSignatureId }))); + +/** + * Request body parameters of the API route. + */ +export type ExportRulesRequestBody = t.TypeOf; +export const ExportRulesRequestBody = t.union([ + t.exact(t.type({ objects: ObjectsWithRuleId })), + t.null, +]); + +/** + * Query string parameters of the API route. + */ +export type ExportRulesRequestQuery = t.TypeOf; +export const ExportRulesRequestQuery = t.exact( + t.partial({ file_name: DefaultExportFileName, exclude_export_details: DefaultStringBooleanFalse }) +); + +export type ExportRulesRequestQueryDecoded = Omit< + ExportRulesRequestQuery, + 'file_name' | 'exclude_export_details' +> & { + file_name: FileName; + exclude_export_details: ExcludeExportDetails; +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.test.ts similarity index 63% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.test.ts index 41e765c8c268b..67a3d045d746d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.test.ts @@ -5,17 +5,17 @@ * 2.0. */ -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import type { FindRulesSchema } from './find_rules_schema'; -import { findRulesSchema } from './find_rules_schema'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { FindRulesRequestQuery } from './request_schema'; -describe('find_rules_schema', () => { +describe('Find rules request schema', () => { test('empty objects do validate', () => { - const payload: FindRulesSchema = {}; + const payload: FindRulesRequestQuery = {}; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -26,7 +26,7 @@ describe('find_rules_schema', () => { }); test('all values validate', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { per_page: 5, page: 1, sort_field: 'some field', @@ -35,7 +35,7 @@ describe('find_rules_schema', () => { sort_order: 'asc', }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -43,9 +43,11 @@ describe('find_rules_schema', () => { }); test('made up parameters do not validate', () => { - const payload: Partial & { madeUp: string } = { madeUp: 'invalid value' }; + const payload: Partial & { madeUp: string } = { + madeUp: 'invalid value', + }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); @@ -53,71 +55,71 @@ describe('find_rules_schema', () => { }); test('per_page validates', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { per_page: 5, }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).per_page).toEqual(payload.per_page); + expect((message.schema as FindRulesRequestQuery).per_page).toEqual(payload.per_page); }); test('page validates', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { page: 5, }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).page).toEqual(payload.page); + expect((message.schema as FindRulesRequestQuery).page).toEqual(payload.page); }); test('sort_field validates', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { sort_field: 'value', }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).sort_field).toEqual('value'); + expect((message.schema as FindRulesRequestQuery).sort_field).toEqual('value'); }); test('fields validates with a string', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { fields: ['some value'], }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).fields).toEqual(payload.fields); + expect((message.schema as FindRulesRequestQuery).fields).toEqual(payload.fields); }); test('fields validates with multiple strings', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { fields: ['some value 1', 'some value 2'], }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).fields).toEqual(payload.fields); + expect((message.schema as FindRulesRequestQuery).fields).toEqual(payload.fields); }); test('fields does not validate with a number', () => { - const payload: Omit & { fields: number } = { + const payload: Omit & { fields: number } = { fields: 5, }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "fields"']); @@ -125,43 +127,43 @@ describe('find_rules_schema', () => { }); test('per_page has a default of 20', () => { - const payload: FindRulesSchema = {}; + const payload: FindRulesRequestQuery = {}; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).per_page).toEqual(20); + expect((message.schema as FindRulesRequestQuery).per_page).toEqual(20); }); test('page has a default of 1', () => { - const payload: FindRulesSchema = {}; + const payload: FindRulesRequestQuery = {}; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).page).toEqual(1); + expect((message.schema as FindRulesRequestQuery).page).toEqual(1); }); test('filter works with a string', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { filter: 'some value 1', }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).filter).toEqual(payload.filter); + expect((message.schema as FindRulesRequestQuery).filter).toEqual(payload.filter); }); test('filter does not work with a number', () => { - const payload: Omit & { filter: number } = { + const payload: Omit & { filter: number } = { filter: 5, }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "filter"']); @@ -169,26 +171,26 @@ describe('find_rules_schema', () => { }); test('sort_order validates with desc and sort_field', () => { - const payload: FindRulesSchema = { + const payload: FindRulesRequestQuery = { sort_order: 'desc', sort_field: 'some field', }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); - expect((message.schema as FindRulesSchema).sort_order).toEqual(payload.sort_order); - expect((message.schema as FindRulesSchema).sort_field).toEqual(payload.sort_field); + expect((message.schema as FindRulesRequestQuery).sort_order).toEqual(payload.sort_order); + expect((message.schema as FindRulesRequestQuery).sort_field).toEqual(payload.sort_field); }); test('sort_order does not validate with a string other than asc and desc', () => { - const payload: Omit & { sort_order: string } = { + const payload: Omit & { sort_order: string } = { sort_order: 'some other string', sort_field: 'some field', }; - const decoded = findRulesSchema.decode(payload); + const decoded = FindRulesRequestQuery.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.ts similarity index 59% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.ts index 39f0105a2a88f..9b321d443b2de 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema.ts @@ -6,12 +6,15 @@ */ import * as t from 'io-ts'; - import { DefaultPerPage, DefaultPage } from '@kbn/securitysolution-io-ts-alerting-types'; -import type { PerPage, Page } from '../common'; -import { queryFilter, fields, SortField, SortOrder } from '../common'; +import type { PerPage, Page } from '../../../../schemas/common'; +import { queryFilter, fields, SortField, SortOrder } from '../../../../schemas/common'; -export const findRulesSchema = t.exact( +/** + * Query string parameters of the API route. + */ +export type FindRulesRequestQuery = t.TypeOf; +export const FindRulesRequestQuery = t.exact( t.partial({ fields, filter: queryFilter, @@ -22,8 +25,7 @@ export const findRulesSchema = t.exact( }) ); -export type FindRulesSchema = t.TypeOf; -export type FindRulesSchemaDecoded = Omit & { +export type FindRulesRequestQueryDecoded = Omit & { page: Page; per_page: PerPage; }; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema_validation.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema_validation.test.ts new file mode 100644 index 0000000000000..862bf7cc1a350 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema_validation.test.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FindRulesRequestQuery } from './request_schema'; +import { validateFindRulesRequestQuery } from './request_schema_validation'; + +describe('Find rules request schema, additional validation', () => { + describe('validateFindRulesRequestQuery', () => { + test('You can have an empty sort_field and empty sort_order', () => { + const schema: FindRulesRequestQuery = {}; + const errors = validateFindRulesRequestQuery(schema); + expect(errors).toEqual([]); + }); + + test('You can have both a sort_field and and a sort_order', () => { + const schema: FindRulesRequestQuery = { + sort_field: 'some field', + sort_order: 'asc', + }; + const errors = validateFindRulesRequestQuery(schema); + expect(errors).toEqual([]); + }); + + test('You cannot have sort_field without sort_order', () => { + const schema: FindRulesRequestQuery = { + sort_field: 'some field', + }; + const errors = validateFindRulesRequestQuery(schema); + expect(errors).toEqual([ + 'when "sort_order" and "sort_field" must exist together or not at all', + ]); + }); + + test('You cannot have sort_order without sort_field', () => { + const schema: FindRulesRequestQuery = { + sort_order: 'asc', + }; + const errors = validateFindRulesRequestQuery(schema); + expect(errors).toEqual([ + 'when "sort_order" and "sort_field" must exist together or not at all', + ]); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema_validation.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema_validation.ts new file mode 100644 index 0000000000000..a8ceb09dea5b4 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/find_rules/request_schema_validation.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { FindRulesRequestQuery } from './request_schema'; + +/** + * Additional validation that is implemented outside of the schema itself. + */ +export const validateFindRulesRequestQuery = (query: FindRulesRequestQuery): string[] => { + return [...validateSortOrder(query)]; +}; + +const validateSortOrder = (query: FindRulesRequestQuery): string[] => { + if (query.sort_order != null || query.sort_field != null) { + if (query.sort_order == null || query.sort_field == null) { + return ['when "sort_order" and "sort_field" must exist together or not at all']; + } else { + return []; + } + } else { + return []; + } +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/request_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/request_schema.test.ts new file mode 100644 index 0000000000000..bd63dd7472aaf --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/request_schema.test.ts @@ -0,0 +1,52 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { left } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { ImportRulesRequestBody } from './request_schema'; + +describe('Import rules schema', () => { + describe('ImportRulesRequestBody', () => { + test('does not validate with an empty object', () => { + const payload = {}; + + const decoded = ImportRulesRequestBody.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "file"', + ]); + expect(message.schema).toEqual({}); + }); + + test('does not validate with a made string', () => { + const payload: Omit & { madeUpKey: string } = { + madeUpKey: 'madeupstring', + }; + + const decoded = ImportRulesRequestBody.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([ + 'Invalid value "undefined" supplied to "file"', + ]); + expect(message.schema).toEqual({}); + }); + + test('does validate with a file object', () => { + const payload: ImportRulesRequestBody = { file: {} }; + + const decoded = ImportRulesRequestBody.decode(payload); + const checked = exactCheck(payload, decoded); + const message = pipe(checked, foldLeftRight); + expect(getPaths(left(message.errors))).toEqual([]); + expect(message.schema).toEqual(payload); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rule_by_id_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/request_schema.ts similarity index 56% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rule_by_id_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/request_schema.ts index 44b9692e7977f..8f64df3ea71b1 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rule_by_id_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/request_schema.ts @@ -7,13 +7,12 @@ import * as t from 'io-ts'; -import { id } from '../common/schemas'; - -export const queryRuleByIdSchema = t.exact( +/** + * Request body parameters of the API route. + */ +export type ImportRulesRequestBody = t.TypeOf; +export const ImportRulesRequestBody = t.exact( t.type({ - id, + file: t.object, }) ); - -export type QueryRuleByIdSchema = t.TypeOf; -export type QueryRuleByIdSchemaDecoded = QueryRuleByIdSchema; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.test.ts similarity index 82% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.test.ts index db1fc33e9d44e..2f11e1a9c120f 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.test.ts @@ -8,15 +8,15 @@ import { pipe } from 'fp-ts/lib/pipeable'; import type { Either } from 'fp-ts/lib/Either'; import { left } from 'fp-ts/lib/Either'; -import type { ImportRulesSchema } from './import_rules_schema'; -import { importRulesSchema } from './import_rules_schema'; -import type { ErrorSchema } from './error_schema'; import type { Errors } from 'io-ts'; + import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; +import type { ErrorSchema } from '../../../../schemas/response/error_schema'; +import { ImportRulesResponse } from './response_schema'; -describe('import_rules_schema', () => { +describe('Import rules response schema', () => { test('it should validate an empty import response with no errors', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: true, success_count: 0, rules_count: 0, @@ -25,7 +25,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -34,7 +34,7 @@ describe('import_rules_schema', () => { }); test('it should validate an empty import response with a single error', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: false, success_count: 0, rules_count: 0, @@ -43,7 +43,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -52,7 +52,7 @@ describe('import_rules_schema', () => { }); test('it should validate an empty import response with a single exceptions error', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: false, success_count: 0, rules_count: 0, @@ -61,7 +61,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -70,7 +70,7 @@ describe('import_rules_schema', () => { }); test('it should validate an empty import response with two errors', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: false, success_count: 0, rules_count: 0, @@ -82,7 +82,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -91,7 +91,7 @@ describe('import_rules_schema', () => { }); test('it should validate an empty import response with two exception errors', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: false, success_count: 0, rules_count: 0, @@ -103,7 +103,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -112,7 +112,7 @@ describe('import_rules_schema', () => { }); test('it should NOT validate a success_count that is a negative number', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: false, success_count: -1, rules_count: 0, @@ -121,7 +121,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -132,7 +132,7 @@ describe('import_rules_schema', () => { }); test('it should NOT validate a exceptions_success_count that is a negative number', () => { - const payload: ImportRulesSchema = { + const payload: ImportRulesResponse = { success: false, success_count: 0, rules_count: 0, @@ -141,7 +141,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: -1, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -170,7 +170,7 @@ describe('import_rules_schema', () => { >; } >; - const payload: Omit & { success: string } = { + const payload: Omit & { success: string } = { success: 'hello', success_count: 0, rules_count: 0, @@ -179,7 +179,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded as UnsafeCastForTest); const message = pipe(checked, foldLeftRight); @@ -207,17 +207,18 @@ describe('import_rules_schema', () => { >; } >; - const payload: Omit & { exceptions_success: string } = - { - success: true, - success_count: 0, - rules_count: 0, - errors: [], - exceptions_errors: [], - exceptions_success: 'hello', - exceptions_success_count: 0, - }; - const decoded = importRulesSchema.decode(payload); + const payload: Omit & { + exceptions_success: string; + } = { + success: true, + success_count: 0, + rules_count: 0, + errors: [], + exceptions_errors: [], + exceptions_success: 'hello', + exceptions_success_count: 0, + }; + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded as UnsafeCastForTest); const message = pipe(checked, foldLeftRight); @@ -228,7 +229,7 @@ describe('import_rules_schema', () => { }); test('it should NOT validate a success an extra invalid field', () => { - const payload: ImportRulesSchema & { invalid_field: string } = { + const payload: ImportRulesResponse & { invalid_field: string } = { success: true, success_count: 0, rules_count: 0, @@ -238,7 +239,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -248,7 +249,7 @@ describe('import_rules_schema', () => { test('it should NOT validate an extra field in the second position of the errors array', () => { type InvalidError = ErrorSchema & { invalid_data?: string }; - const payload: Omit & { + const payload: Omit & { errors: InvalidError[]; } = { success: true, @@ -262,7 +263,7 @@ describe('import_rules_schema', () => { exceptions_success: true, exceptions_success_count: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = ImportRulesResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.ts similarity index 69% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.ts index d577b2135d58d..77ccd0812c2c9 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/import_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/import_rules/response_schema.ts @@ -5,22 +5,19 @@ * 2.0. */ -import { PositiveInteger } from '@kbn/securitysolution-io-ts-types'; import * as t from 'io-ts'; +import { PositiveInteger } from '@kbn/securitysolution-io-ts-types'; +import { errorSchema } from '../../../../schemas/response/error_schema'; -import { success, success_count } from '../common/schemas'; -import { errorSchema } from './error_schema'; - -export const importRulesSchema = t.exact( +export type ImportRulesResponse = t.TypeOf; +export const ImportRulesResponse = t.exact( t.type({ exceptions_success: t.boolean, exceptions_success_count: PositiveInteger, exceptions_errors: t.array(errorSchema), rules_count: PositiveInteger, - success, - success_count, + success: t.boolean, + success_count: PositiveInteger, errors: t.array(errorSchema), }) ); - -export type ImportRulesSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/urls.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/urls.ts new file mode 100644 index 0000000000000..1fec1c76430eb --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/urls.ts @@ -0,0 +1,6 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/index.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/index.ts new file mode 100644 index 0000000000000..266a7e30d311c --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/index.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/rules/bulk_crud/bulk_create_rules/request_schema'; +export * from './api/rules/bulk_crud/bulk_delete_rules/request_schema'; +export * from './api/rules/bulk_crud/bulk_patch_rules/request_schema'; +export * from './api/rules/bulk_crud/bulk_update_rules/request_schema'; +export * from './api/rules/bulk_crud/response_schema'; + +export * from './api/rules/crud/create_rule/request_schema_validation'; +export * from './api/rules/crud/patch_rule/request_schema_validation'; +export * from './api/rules/crud/patch_rule/request_schema'; +export * from './api/rules/crud/read_rule/query_rule_by_ids_validation'; +export * from './api/rules/crud/read_rule/query_rule_by_ids'; +export * from './api/rules/crud/update_rule/request_schema_validation'; + +export * from './api/rules/export_rules/request_schema'; +export * from './api/rules/find_rules/request_schema_validation'; +export * from './api/rules/find_rules/request_schema'; +export * from './api/rules/import_rules/request_schema'; +export * from './api/rules/import_rules/response_schema'; + +// TODO: https://github.com/elastic/kibana/pull/142950 +// export * from './api/urls'; + +export * from './model/export/export_rules_details_schema'; +export * from './model/import/rule_to_import_validation'; +export * from './model/import/rule_to_import'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/mocks.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/mocks.ts new file mode 100644 index 0000000000000..6827236f8dcbf --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/mocks.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/rules/bulk_actions/request_schema.mock'; +export * from './api/rules/crud/patch_rule/request_schema.mock'; + +export * from './model/export/export_rules_details_schema.mock'; +export * from './model/import/rule_to_import.mock'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.mock.ts similarity index 100% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.mock.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.mock.ts index 9b79238bef6c7..64b82abdb3755 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.mock.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { ExportRulesDetails } from './export_rules_details_schema'; -import type { ExportExceptionDetailsMock } from '@kbn/lists-plugin/common/schemas/response/exception_export_details_schema.mock'; import { getExceptionExportDetailsMock } from '@kbn/lists-plugin/common/schemas/response/exception_export_details_schema.mock'; +import type { ExportExceptionDetailsMock } from '@kbn/lists-plugin/common/schemas/response/exception_export_details_schema.mock'; +import type { ExportRulesDetails } from './export_rules_details_schema'; interface RuleDetailsMock { totalCount?: number; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.test.ts similarity index 100% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.test.ts diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.ts similarity index 96% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.ts index 05df728aa3f5c..85b423135566b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/export_rules_details_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/export/export_rules_details_schema.ts @@ -16,7 +16,7 @@ const createSchema = ( return t.intersection([t.exact(t.type(requiredFields)), t.exact(t.partial(optionalFields))]); }; -export const exportRulesDetails = { +const exportRulesDetails = { exported_count: t.number, exported_rules_count: t.number, missing_rules: t.array( diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.mock.ts similarity index 88% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.mock.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.mock.ts index c469926104131..d1dc9e8ac4663 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.mock.ts @@ -5,9 +5,9 @@ * 2.0. */ -import type { ImportRulesSchema } from './import_rules_schema'; +import type { RuleToImport } from './rule_to_import'; -export const getImportRulesSchemaMock = (ruleId = 'rule-1'): ImportRulesSchema => ({ +export const getImportRulesSchemaMock = (ruleId = 'rule-1'): RuleToImport => ({ description: 'some description', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', @@ -18,7 +18,7 @@ export const getImportRulesSchemaMock = (ruleId = 'rule-1'): ImportRulesSchema = rule_id: ruleId, }); -export const getImportRulesWithIdSchemaMock = (ruleId = 'rule-1'): ImportRulesSchema => ({ +export const getImportRulesWithIdSchemaMock = (ruleId = 'rule-1'): RuleToImport => ({ id: '6afb8ce1-ea94-4790-8653-fd0b021d2113', description: 'some description', name: 'Query with a rule id', @@ -35,7 +35,7 @@ export const getImportRulesWithIdSchemaMock = (ruleId = 'rule-1'): ImportRulesSc * as we might import/export * @param rules Array of rule objects with which to generate rule JSON */ -export const rulesToNdJsonString = (rules: ImportRulesSchema[]) => { +export const rulesToNdJsonString = (rules: RuleToImport[]) => { return rules.map((rule) => JSON.stringify(rule)).join('\r\n'); }; @@ -49,7 +49,7 @@ export const ruleIdsToNdJsonString = (ruleIds: string[]) => { return rulesToNdJsonString(rules); }; -export const getImportThreatMatchRulesSchemaMock = (ruleId = 'rule-1'): ImportRulesSchema => ({ +export const getImportThreatMatchRulesSchemaMock = (ruleId = 'rule-1'): RuleToImport => ({ description: 'some description', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.test.ts similarity index 78% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.test.ts index 1c119e696e7b7..84478b4af27fe 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.test.ts @@ -5,22 +5,22 @@ * 2.0. */ -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; -import type { ImportRulesPayloadSchema, ImportRulesSchema } from './import_rules_schema'; -import { importRulesPayloadSchema, importRulesSchema } from './import_rules_schema'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { getListArrayMock } from '../../../schemas/types/lists.mock'; +import { RuleToImport } from './rule_to_import'; import { getImportRulesSchemaMock, getImportThreatMatchRulesSchemaMock, -} from './import_rules_schema.mock'; -import { getListArrayMock } from '../types/lists.mock'; +} from './rule_to_import.mock'; -describe('import rules schema', () => { +describe('RuleToImport', () => { test('empty objects do not validate', () => { - const payload: Partial = {}; + const payload: Partial = {}; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -42,12 +42,12 @@ describe('import rules schema', () => { }); test('made up values do not validate', () => { - const payload: ImportRulesSchema & { madeUp: string } = { + const payload: RuleToImport & { madeUp: string } = { ...getImportRulesSchemaMock(), madeUp: 'hi', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); @@ -55,11 +55,11 @@ describe('import rules schema', () => { }); test('[rule_id] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -78,12 +78,12 @@ describe('import rules schema', () => { }); test('[rule_id, description] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -99,13 +99,13 @@ describe('import rules schema', () => { }); test('[rule_id, description, from] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -121,14 +121,14 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', to: 'now', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -144,7 +144,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, name] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -152,7 +152,7 @@ describe('import rules schema', () => { name: 'some-name', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -165,7 +165,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, name, severity] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -174,7 +174,7 @@ describe('import rules schema', () => { severity: 'low', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toContain( @@ -184,7 +184,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -194,7 +194,7 @@ describe('import rules schema', () => { type: 'query', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -204,7 +204,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -215,7 +215,7 @@ describe('import rules schema', () => { type: 'query', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -225,7 +225,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -237,7 +237,7 @@ describe('import rules schema', () => { index: ['index-1'], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -247,7 +247,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -261,14 +261,14 @@ describe('import rules schema', () => { interval: '5m', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -282,7 +282,7 @@ describe('import rules schema', () => { language: 'kuery', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -292,7 +292,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -307,14 +307,14 @@ describe('import rules schema', () => { language: 'kuery', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -330,14 +330,14 @@ describe('import rules schema', () => { language: 'kuery', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -350,14 +350,14 @@ describe('import rules schema', () => { risk_score: 50, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -371,26 +371,26 @@ describe('import rules schema', () => { type: 'query', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can send in an empty array to threat', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), threat: [], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -421,19 +421,19 @@ describe('import rules schema', () => { ], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('allows references to be sent as valid', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), references: ['index-1'], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -441,19 +441,19 @@ describe('import rules schema', () => { test('defaults references to an array if it is not sent in', () => { const { references, ...noReferences } = getImportRulesSchemaMock(); - const decoded = importRulesSchema.decode(noReferences); + const decoded = RuleToImport.decode(noReferences); const checked = exactCheck(noReferences, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('references cannot be numbers', () => { - const payload: Omit & { references: number[] } = { + const payload: Omit & { references: number[] } = { ...getImportRulesSchemaMock(), references: [5], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); @@ -461,12 +461,12 @@ describe('import rules schema', () => { }); test('indexes cannot be numbers', () => { - const payload: Omit & { index: number[] } = { + const payload: Omit & { index: number[] } = { ...getImportRulesSchemaMock(), index: [5], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); @@ -475,11 +475,11 @@ describe('import rules schema', () => { test('defaults interval to 5 min', () => { const { interval, ...noInterval } = getImportRulesSchemaMock(); - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...noInterval, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -488,11 +488,11 @@ describe('import rules schema', () => { test('defaults max signals to 100', () => { // eslint-disable-next-line @typescript-eslint/naming-convention const { max_signals, ...noMaxSignals } = getImportRulesSchemaMock(); - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...noMaxSignals, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -504,19 +504,19 @@ describe('import rules schema', () => { filters: [], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('filters cannot be a string', () => { - const payload: Omit & { filters: string } = { + const payload: Omit & { filters: string } = { ...getImportRulesSchemaMock(), filters: 'some string', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -531,7 +531,7 @@ describe('import rules schema', () => { language: 'kuery', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -543,19 +543,19 @@ describe('import rules schema', () => { language: 'lucene', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('language does not validate with something made up', () => { - const payload: Omit & { language: string } = { + const payload: Omit & { language: string } = { ...getImportRulesSchemaMock(), language: 'something-made-up', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -565,12 +565,12 @@ describe('import rules schema', () => { }); test('max_signals cannot be negative', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), max_signals: -1, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -580,12 +580,12 @@ describe('import rules schema', () => { }); test('max_signals cannot be zero', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), max_signals: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); @@ -593,36 +593,36 @@ describe('import rules schema', () => { }); test('max_signals can be 1', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), max_signals: 1, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can optionally send in an array of tags', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), tags: ['tag_1', 'tag_2'], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot send in an array of tags that are numbers', () => { - const payload: Omit & { tags: number[] } = { + const payload: Omit & { tags: number[] } = { ...getImportRulesSchemaMock(), tags: [0, 1, 2], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -634,8 +634,8 @@ describe('import rules schema', () => { }); test('You cannot send in an array of threat that are missing "framework"', () => { - const payload: Omit & { - threat: Array>>; + const payload: Omit & { + threat: Array>>; } = { ...getImportRulesSchemaMock(), threat: [ @@ -656,7 +656,7 @@ describe('import rules schema', () => { ], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -666,8 +666,8 @@ describe('import rules schema', () => { }); test('You cannot send in an array of threat that are missing "tactic"', () => { - const payload: Omit & { - threat: Array>>; + const payload: Omit & { + threat: Array>>; } = { ...getImportRulesSchemaMock(), threat: [ @@ -684,7 +684,7 @@ describe('import rules schema', () => { ], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -694,8 +694,8 @@ describe('import rules schema', () => { }); test('You can send in an array of threat that are missing "technique"', () => { - const payload: Omit & { - threat: Array>>; + const payload: Omit & { + threat: Array>>; } = { ...getImportRulesSchemaMock(), threat: [ @@ -710,31 +710,31 @@ describe('import rules schema', () => { ], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can optionally send in an array of false positives', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), false_positives: ['false_1', 'false_2'], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot send in an array of false positives that are numbers', () => { - const payload: Omit & { false_positives: number[] } = { + const payload: Omit & { false_positives: number[] } = { ...getImportRulesSchemaMock(), false_positives: [5, 4], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -745,12 +745,12 @@ describe('import rules schema', () => { }); test('You cannot set the immutable to a number when trying to create a rule', () => { - const payload: Omit & { immutable: number } = { + const payload: Omit & { immutable: number } = { ...getImportRulesSchemaMock(), immutable: 5, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "immutable"']); @@ -758,24 +758,24 @@ describe('import rules schema', () => { }); test('You can optionally set the immutable to be false', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), immutable: false, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot set the immutable to be true', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), immutable: true, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -785,12 +785,12 @@ describe('import rules schema', () => { }); test('You cannot set the immutable to be a number', () => { - const payload: Omit & { immutable: number } = { + const payload: Omit & { immutable: number } = { ...getImportRulesSchemaMock(), immutable: 5, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "immutable"']); @@ -798,12 +798,12 @@ describe('import rules schema', () => { }); test('You cannot set the risk_score to 101', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), risk_score: 101, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -813,12 +813,12 @@ describe('import rules schema', () => { }); test('You cannot set the risk_score to -1', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), risk_score: -1, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); @@ -826,50 +826,50 @@ describe('import rules schema', () => { }); test('You can set the risk_score to 0', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), risk_score: 0, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can set the risk_score to 100', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), risk_score: 100, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can set meta to any object you want', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), meta: { somethingMadeUp: { somethingElse: true }, }, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot create meta as a string', () => { - const payload: Omit & { meta: string } = { + const payload: Omit & { meta: string } = { ...getImportRulesSchemaMock(), meta: 'should not work', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -879,27 +879,27 @@ describe('import rules schema', () => { }); test('validates with timeline_id and timeline_title', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), timeline_id: 'timeline-id', timeline_title: 'timeline-title', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('rule_id is required and you cannot get by with just id', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612', }; // @ts-expect-error delete payload.rule_id; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -909,7 +909,7 @@ describe('import rules schema', () => { }); test('it validates with created_at, updated_at, created_by, updated_by values', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), created_at: '2020-01-09T06:15:24.749Z', updated_at: '2020-01-09T06:15:24.749Z', @@ -917,19 +917,19 @@ describe('import rules schema', () => { updated_by: 'Evan Hassanabad', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('it does not validate with epoch strings for created_at', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), created_at: '1578550728650', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -939,12 +939,12 @@ describe('import rules schema', () => { }); test('it does not validate with epoch strings for updated_at', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), updated_at: '1578550728650', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -953,51 +953,13 @@ describe('import rules schema', () => { expect(message.schema).toEqual({}); }); - describe('importRulesPayloadSchema', () => { - test('does not validate with an empty object', () => { - const payload = {}; - - const decoded = importRulesPayloadSchema.decode(payload); - const checked = exactCheck(payload, decoded); - const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "file"', - ]); - expect(message.schema).toEqual({}); - }); - - test('does not validate with a made string', () => { - const payload: Omit & { madeUpKey: string } = { - madeUpKey: 'madeupstring', - }; - - const decoded = importRulesPayloadSchema.decode(payload); - const checked = exactCheck(payload, decoded); - const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual([ - 'Invalid value "undefined" supplied to "file"', - ]); - expect(message.schema).toEqual({}); - }); - - test('does validate with a file object', () => { - const payload: ImportRulesPayloadSchema = { file: {} }; - - const decoded = importRulesPayloadSchema.decode(payload); - const checked = exactCheck(payload, decoded); - const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual(payload); - }); - }); - test('The default for "from" will be "now-6m"', () => { const { from, ...noFrom } = getImportRulesSchemaMock(); - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...noFrom, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1005,23 +967,23 @@ describe('import rules schema', () => { test('The default for "to" will be "now"', () => { const { to, ...noTo } = getImportRulesSchemaMock(); - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...noTo, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot set the severity to a value other than low, medium, high, or critical', () => { - const payload: Omit & { severity: string } = { + const payload: Omit & { severity: string } = { ...getImportRulesSchemaMock(), severity: 'junk', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); @@ -1030,22 +992,23 @@ describe('import rules schema', () => { test('The default for "actions" will be an empty array', () => { const { actions, ...noActions } = getImportRulesSchemaMock(); - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...noActions, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); + test('You cannot send in an array of actions that are missing "group"', () => { - const payload: Omit = { + const payload: Omit = { ...getImportRulesSchemaMock(), actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1055,12 +1018,12 @@ describe('import rules schema', () => { }); test('You cannot send in an array of actions that are missing "id"', () => { - const payload: Omit = { + const payload: Omit = { ...getImportRulesSchemaMock(), actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1070,12 +1033,12 @@ describe('import rules schema', () => { }); test('You cannot send in an array of actions that are missing "action_type_id"', () => { - const payload: Omit = { + const payload: Omit = { ...getImportRulesSchemaMock(), actions: [{ group: 'group', id: 'id', params: {} }], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1085,12 +1048,12 @@ describe('import rules schema', () => { }); test('You cannot send in an array of actions that are missing "params"', () => { - const payload: Omit = { + const payload: Omit = { ...getImportRulesSchemaMock(), actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1100,7 +1063,7 @@ describe('import rules schema', () => { }); test('You cannot send in an array of actions that are including "actionTypeId"', () => { - const payload: Omit = { + const payload: Omit = { ...getImportRulesSchemaMock(), actions: [ { @@ -1112,7 +1075,7 @@ describe('import rules schema', () => { ], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1123,11 +1086,11 @@ describe('import rules schema', () => { test('The default for "throttle" will be null', () => { const { throttle, ...noThrottle } = getImportRulesSchemaMock(); - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...noThrottle, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1135,38 +1098,38 @@ describe('import rules schema', () => { describe('note', () => { test('You can set note to a string', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), note: '# documentation markdown here', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You can set note to an empty string', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { ...getImportRulesSchemaMock(), note: '', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('You cannot create note as an object', () => { - const payload: Omit & { note: {} } = { + const payload: Omit & { note: {} } = { ...getImportRulesSchemaMock(), note: { somethingHere: 'something else', }, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1176,7 +1139,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1190,7 +1153,7 @@ describe('import rules schema', () => { note: '# some markdown', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1199,7 +1162,7 @@ describe('import rules schema', () => { describe('exception_list', () => { test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, and exceptions_list] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1215,14 +1178,14 @@ describe('import rules schema', () => { exceptions_list: getListArrayMock(), }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1238,7 +1201,7 @@ describe('import rules schema', () => { exceptions_list: [], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1261,7 +1224,7 @@ describe('import rules schema', () => { exceptions_list: [{ id: 'uuid_here', namespace_type: 'not a namespace type' }], }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1273,7 +1236,7 @@ describe('import rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1288,7 +1251,7 @@ describe('import rules schema', () => { note: '# some markdown', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1298,7 +1261,7 @@ describe('import rules schema', () => { describe('threat_mapping', () => { test('You can set a threat query, index, mapping, filters on an imported rule', () => { const payload = getImportThreatMatchRulesSchemaMock(); - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1307,7 +1270,7 @@ describe('import rules schema', () => { describe('data_view_id', () => { test('Defined data_view_id and empty index does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -1322,7 +1285,7 @@ describe('import rules schema', () => { interval: '5m', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1330,7 +1293,7 @@ describe('import rules schema', () => { // Both can be defined, but if a data_view_id is defined, rule will use that one test('Defined data_view_id and index does validate', () => { - const payload: ImportRulesSchema = { + const payload: RuleToImport = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -1345,19 +1308,19 @@ describe('import rules schema', () => { interval: '5m', }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); }); test('data_view_id cannot be a number', () => { - const payload: Omit & { data_view_id: number } = { + const payload: Omit & { data_view_id: number } = { ...getImportRulesSchemaMock(), data_view_id: 5, }; - const decoded = importRulesSchema.decode(payload); + const decoded = RuleToImport.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.ts similarity index 69% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.ts index b3d533a167a7a..b40bed8ce65c5 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import.ts @@ -6,20 +6,18 @@ */ import * as t from 'io-ts'; - import { OnlyFalseAllowed } from '@kbn/securitysolution-io-ts-types'; + import { - rule_id, - id, - created_at, - updated_at, - created_by, - updated_by, RelatedIntegrationArray, RequiredFieldArray, + RuleObjectId, + RuleSignatureId, SetupGuide, -} from '../common'; -import { baseCreateParams, createTypeSpecific } from './rule_schemas'; + BaseCreateProps, + TypeSpecificCreateProps, +} from '../../../rule_schema'; +import { created_at, updated_at, created_by, updated_by } from '../../../schemas/common'; /** * Differences from this and the createRulesSchema are @@ -31,13 +29,14 @@ import { baseCreateParams, createTypeSpecific } from './rule_schemas'; * - created_by is optional (but ignored in the import code) * - updated_by is optional (but ignored in the import code) */ -export const importRulesSchema = t.intersection([ - baseCreateParams, - createTypeSpecific, - t.exact(t.type({ rule_id })), +export type RuleToImport = t.TypeOf; +export const RuleToImport = t.intersection([ + BaseCreateProps, + TypeSpecificCreateProps, + t.exact(t.type({ rule_id: RuleSignatureId })), t.exact( t.partial({ - id, + id: RuleObjectId, immutable: OnlyFalseAllowed, updated_at, updated_by, @@ -49,13 +48,3 @@ export const importRulesSchema = t.intersection([ }) ), ]); - -export type ImportRulesSchema = t.TypeOf; - -export const importRulesPayloadSchema = t.exact( - t.type({ - file: t.object, - }) -); - -export type ImportRulesPayloadSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.test.ts new file mode 100644 index 0000000000000..31ac993eb4053 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.test.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RuleToImport } from './rule_to_import'; +import { getImportRulesSchemaMock } from './rule_to_import.mock'; +import { validateRuleToImport } from './rule_to_import_validation'; + +describe('Rule to import schema, additional validation', () => { + describe('validateRuleToImport', () => { + test('You cannot omit timeline_title when timeline_id is present', () => { + const schema: RuleToImport = { + ...getImportRulesSchemaMock(), + timeline_id: '123', + }; + delete schema.timeline_title; + const errors = validateRuleToImport(schema); + expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); + }); + + test('You cannot have empty string for timeline_title when timeline_id is present', () => { + const schema: RuleToImport = { + ...getImportRulesSchemaMock(), + timeline_id: '123', + timeline_title: '', + }; + const errors = validateRuleToImport(schema); + expect(errors).toEqual(['"timeline_title" cannot be an empty string']); + }); + + test('You cannot have timeline_title with an empty timeline_id', () => { + const schema: RuleToImport = { + ...getImportRulesSchemaMock(), + timeline_id: '', + timeline_title: 'some-title', + }; + const errors = validateRuleToImport(schema); + expect(errors).toEqual(['"timeline_id" cannot be an empty string']); + }); + + test('You cannot have timeline_title without timeline_id', () => { + const schema: RuleToImport = { + ...getImportRulesSchemaMock(), + timeline_title: 'some-title', + }; + delete schema.timeline_id; + const errors = validateRuleToImport(schema); + expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.ts similarity index 78% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.ts index bdb025583b404..de21ac3a7964c 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/model/import/rule_to_import_validation.ts @@ -5,9 +5,16 @@ * 2.0. */ -import type { ImportRulesSchema } from './import_rules_schema'; +import type { RuleToImport } from './rule_to_import'; -export const validateTimelineId = (rule: ImportRulesSchema): string[] => { +/** + * Additional validation that is implemented outside of the schema itself. + */ +export const validateRuleToImport = (rule: RuleToImport): string[] => { + return [...validateTimelineId(rule), ...validateTimelineTitle(rule), ...validateThreshold(rule)]; +}; + +const validateTimelineId = (rule: RuleToImport): string[] => { if (rule.timeline_id != null) { if (rule.timeline_title == null) { return ['when "timeline_id" exists, "timeline_title" must also exist']; @@ -20,7 +27,7 @@ export const validateTimelineId = (rule: ImportRulesSchema): string[] => { return []; }; -export const validateTimelineTitle = (rule: ImportRulesSchema): string[] => { +const validateTimelineTitle = (rule: RuleToImport): string[] => { if (rule.timeline_title != null) { if (rule.timeline_id == null) { return ['when "timeline_title" exists, "timeline_id" must also exist']; @@ -33,7 +40,7 @@ export const validateTimelineTitle = (rule: ImportRulesSchema): string[] => { return []; }; -export const validateThreshold = (rule: ImportRulesSchema): string[] => { +const validateThreshold = (rule: RuleToImport): string[] => { const errors: string[] = []; if (rule.type === 'threshold') { if ( @@ -48,7 +55,3 @@ export const validateThreshold = (rule: ImportRulesSchema): string[] => { } return errors; }; - -export const importRuleValidateTypeDependents = (rule: ImportRulesSchema): string[] => { - return [...validateTimelineId(rule), ...validateTimelineTitle(rule), ...validateThreshold(rule)]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/get_rule_execution_events/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/get_rule_execution_events/request_schema.ts index 9ffa2467e0852..59e17a9d6f604 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/get_rule_execution_events/request_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_monitoring/api/get_rule_execution_events/request_schema.ts @@ -15,7 +15,7 @@ import { TRuleExecutionEventType } from '../../model/execution_event'; import { TLogLevel } from '../../model/log_level'; /** - * Path parameters of the API route. + * URL path parameters of the API route. */ export type GetRuleExecutionEventsRequestParams = t.TypeOf< typeof GetRuleExecutionEventsRequestParams diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/index.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/index.ts new file mode 100644 index 0000000000000..cf1266b1b9a71 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './model/common_attributes/field_overrides'; +export * from './model/common_attributes/misc_attributes'; +export * from './model/common_attributes/related_integrations'; +export * from './model/common_attributes/required_fields'; +export * from './model/common_attributes/saved_objects'; +export * from './model/common_attributes/timeline_template'; + +export * from './model/specific_attributes/eql_attributes'; +export * from './model/specific_attributes/new_terms_attributes'; +export * from './model/specific_attributes/threshold_attributes'; + +export * from './model/rule_schemas'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/mocks.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/mocks.ts new file mode 100644 index 0000000000000..6cf0d49e9560a --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/mocks.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './model/rule_request_schema.mock'; +export * from './model/rule_response_schema.mock'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/build_rule_schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/build_rule_schemas.ts new file mode 100644 index 0000000000000..f7d52c682d191 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/build_rule_schemas.ts @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +interface RuleFields< + Required extends t.Props, + Optional extends t.Props, + Defaultable extends t.Props +> { + required: Required; + optional: Optional; + defaultable: Defaultable; +} + +export const buildRuleSchemas = ( + fields: RuleFields +) => { + return { + create: buildCreateRuleSchema(fields.required, fields.optional, fields.defaultable), + patch: buildPatchRuleSchema(fields.required, fields.optional, fields.defaultable), + response: buildResponseRuleSchema(fields.required, fields.optional, fields.defaultable), + }; +}; + +const buildCreateRuleSchema = < + Required extends t.Props, + Optional extends t.Props, + Defaultable extends t.Props +>( + requiredFields: Required, + optionalFields: Optional, + defaultableFields: Defaultable +) => { + return t.intersection([ + t.exact(t.type(requiredFields)), + t.exact(t.partial(optionalFields)), + t.exact(t.partial(defaultableFields)), + ]); +}; + +const buildPatchRuleSchema = < + Required extends t.Props, + Optional extends t.Props, + Defaultable extends t.Props +>( + requiredFields: Required, + optionalFields: Optional, + defaultableFields: Defaultable +) => { + return t.intersection([ + t.partial(requiredFields), + t.partial(optionalFields), + t.partial(defaultableFields), + ]); +}; + +type OrUndefined

= { + [K in keyof P]: P[K] | t.UndefinedC; +}; + +export const buildResponseRuleSchema = < + Required extends t.Props, + Optional extends t.Props, + Defaultable extends t.Props +>( + requiredFields: Required, + optionalFields: Optional, + defaultableFields: Defaultable +) => { + // This bit of logic is to force all fields to be accounted for in conversions from the internal + // rule schema to the response schema. Rather than use `t.partial`, which makes each field optional, + // we make each field required but possibly undefined. The result is that if a field is forgotten in + // the conversion from internal schema to response schema TS will report an error. If we just used t.partial + // instead, then optional fields can be accidentally omitted from the conversion - and any actual values + // in those fields internally will be stripped in the response. + const optionalWithUndefined = Object.keys(optionalFields).reduce((acc, key) => { + acc[key] = t.union([optionalFields[key], t.undefined]); + return acc; + }, {}) as OrUndefined; + return t.intersection([ + t.exact(t.type(requiredFields)), + t.exact(t.type(optionalWithUndefined)), + t.exact(t.type(defaultableFields)), + ]); +}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/field_overrides.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/field_overrides.ts new file mode 100644 index 0000000000000..85058099fdadf --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/field_overrides.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +export type RuleNameOverride = t.TypeOf; +export const RuleNameOverride = t.string; // should be non-empty string? + +export type TimestampOverride = t.TypeOf; +export const TimestampOverride = t.string; // should be non-empty string? + +export type TimestampOverrideFallbackDisabled = t.TypeOf; +export const TimestampOverrideFallbackDisabled = t.boolean; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/misc_attributes.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/misc_attributes.ts new file mode 100644 index 0000000000000..315a15190ec28 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/misc_attributes.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { listArray } from '@kbn/securitysolution-io-ts-list-types'; +import { NonEmptyString, version, UUID } from '@kbn/securitysolution-io-ts-types'; +import { max_signals, threat } from '@kbn/securitysolution-io-ts-alerting-types'; + +export type RuleObjectId = t.TypeOf; +export const RuleObjectId = UUID; + +/** + * NOTE: Never make this a strict uuid, we allow the rule_id to be any string at the moment + * in case we encounter 3rd party rule systems which might be using auto incrementing numbers + * or other different things. + */ +export type RuleSignatureId = t.TypeOf; +export const RuleSignatureId = t.string; // should be non-empty string? + +export type RuleName = t.TypeOf; +export const RuleName = NonEmptyString; + +export type RuleDescription = t.TypeOf; +export const RuleDescription = NonEmptyString; + +export type RuleVersion = t.TypeOf; +export const RuleVersion = version; + +export type IsRuleImmutable = t.TypeOf; +export const IsRuleImmutable = t.boolean; + +export type IsRuleEnabled = t.TypeOf; +export const IsRuleEnabled = t.boolean; + +export type RuleTagArray = t.TypeOf; +export const RuleTagArray = t.array(t.string); // should be non-empty strings? + +/** + * Note that this is a non-exact io-ts type as we allow extra meta information + * to be added to the meta object + */ +export type RuleMetadata = t.TypeOf; +export const RuleMetadata = t.object; // should be a more specific type? + +export type RuleLicense = t.TypeOf; +export const RuleLicense = t.string; // should be non-empty string? + +export type RuleAuthorArray = t.TypeOf; +export const RuleAuthorArray = t.array(t.string); // should be non-empty strings? + +export type RuleFalsePositiveArray = t.TypeOf; +export const RuleFalsePositiveArray = t.array(t.string); // should be non-empty strings? + +export type RuleReferenceArray = t.TypeOf; +export const RuleReferenceArray = t.array(t.string); // should be non-empty strings? + +export type InvestigationGuide = t.TypeOf; +export const InvestigationGuide = t.string; + +/** + * Any instructions for the user for setting up their environment in order to start receiving + * source events for a given rule. + * + * It's a multiline text. Markdown is supported. + */ +export type SetupGuide = t.TypeOf; +export const SetupGuide = t.string; + +export type BuildingBlockType = t.TypeOf; +export const BuildingBlockType = t.string; + +export type AlertsIndex = t.TypeOf; +export const AlertsIndex = t.string; + +export type AlertsIndexNamespace = t.TypeOf; +export const AlertsIndexNamespace = t.string; + +export type ExceptionListArray = t.TypeOf; +export const ExceptionListArray = listArray; + +export type MaxSignals = t.TypeOf; +export const MaxSignals = max_signals; + +export type ThreatArray = t.TypeOf; +export const ThreatArray = t.array(threat); + +export type IndexPatternArray = t.TypeOf; +export const IndexPatternArray = t.array(t.string); + +export type DataViewId = t.TypeOf; +export const DataViewId = t.string; + +export type RuleQuery = t.TypeOf; +export const RuleQuery = t.string; + +/** + * TODO: Right now the filters is an "unknown", when it could more than likely + * become the actual ESFilter as a type. + */ +export type RuleFilterArray = t.TypeOf; // Filters are not easily type-able yet +export const RuleFilterArray = t.array(t.unknown); // Filters are not easily type-able yet diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/rule_params.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/related_integrations.ts similarity index 55% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/common/rule_params.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/related_integrations.ts index d65bce6e587ef..d99043d81e19e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/rule_params.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/related_integrations.ts @@ -8,9 +8,6 @@ import * as t from 'io-ts'; import { NonEmptyString } from '@kbn/securitysolution-io-ts-types'; -// ------------------------------------------------------------------------------------------------- -// Related integrations - /** * Related integration is a potential dependency of a rule. It's assumed that if the user installs * one of the related integrations of a rule, the rule might start to work properly because it will @@ -74,72 +71,3 @@ export const RelatedIntegration = t.exact( */ export type RelatedIntegrationArray = t.TypeOf; export const RelatedIntegrationArray = t.array(RelatedIntegration); - -// ------------------------------------------------------------------------------------------------- -// Required fields - -/** - * Almost all types of Security rules check source event documents for a match to some kind of - * query or filter. If a document has certain field with certain values, then it's a match and - * the rule will generate an alert. - * - * Required field is an event field that must be present in the source indices of a given rule. - * - * @example - * const standardEcsField: RequiredField = { - * name: 'event.action', - * type: 'keyword', - * ecs: true, - * }; - * - * @example - * const nonEcsField: RequiredField = { - * name: 'winlog.event_data.AttributeLDAPDisplayName', - * type: 'keyword', - * ecs: false, - * }; - */ -export const RequiredField = t.exact( - t.type({ - name: NonEmptyString, - type: NonEmptyString, - ecs: t.boolean, - }) -); - -/** - * Array of event fields that must be present in the source indices of a given rule. - * - * @example - * const x: RequiredFieldArray = [ - * { - * name: 'event.action', - * type: 'keyword', - * ecs: true, - * }, - * { - * name: 'event.code', - * type: 'keyword', - * ecs: true, - * }, - * { - * name: 'winlog.event_data.AttributeLDAPDisplayName', - * type: 'keyword', - * ecs: false, - * }, - * ]; - */ -export type RequiredFieldArray = t.TypeOf; -export const RequiredFieldArray = t.array(RequiredField); - -// ------------------------------------------------------------------------------------------------- -// Setup guide - -/** - * Any instructions for the user for setting up their environment in order to start receiving - * source events for a given rule. - * - * It's a multiline text. Markdown is supported. - */ -export type SetupGuide = t.TypeOf; -export const SetupGuide = t.string; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/required_fields.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/required_fields.ts new file mode 100644 index 0000000000000..0938612fd4654 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/required_fields.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { NonEmptyString } from '@kbn/securitysolution-io-ts-types'; + +/** + * Almost all types of Security rules check source event documents for a match to some kind of + * query or filter. If a document has certain field with certain values, then it's a match and + * the rule will generate an alert. + * + * Required field is an event field that must be present in the source indices of a given rule. + * + * @example + * const standardEcsField: RequiredField = { + * name: 'event.action', + * type: 'keyword', + * ecs: true, + * }; + * + * @example + * const nonEcsField: RequiredField = { + * name: 'winlog.event_data.AttributeLDAPDisplayName', + * type: 'keyword', + * ecs: false, + * }; + */ +export type RequiredField = t.TypeOf; +export const RequiredField = t.exact( + t.type({ + name: NonEmptyString, + type: NonEmptyString, + ecs: t.boolean, + }) +); + +/** + * Array of event fields that must be present in the source indices of a given rule. + * + * @example + * const x: RequiredFieldArray = [ + * { + * name: 'event.action', + * type: 'keyword', + * ecs: true, + * }, + * { + * name: 'event.code', + * type: 'keyword', + * ecs: true, + * }, + * { + * name: 'winlog.event_data.AttributeLDAPDisplayName', + * type: 'keyword', + * ecs: false, + * }, + * ]; + */ +export type RequiredFieldArray = t.TypeOf; +export const RequiredFieldArray = t.array(RequiredField); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/saved_objects.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/saved_objects.ts new file mode 100644 index 0000000000000..78d2eb1d9813a --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/saved_objects.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +/** + * Outcome is a property of the saved object resolve api + * will tell us info about the rule after 8.0 migrations + */ +export type SavedObjectResolveOutcome = t.TypeOf; +export const SavedObjectResolveOutcome = t.union([ + t.literal('exactMatch'), + t.literal('aliasMatch'), + t.literal('conflict'), +]); + +export type SavedObjectResolveAliasTargetId = t.TypeOf; +export const SavedObjectResolveAliasTargetId = t.string; + +export type SavedObjectResolveAliasPurpose = t.TypeOf; +export const SavedObjectResolveAliasPurpose = t.union([ + t.literal('savedObjectConversion'), + t.literal('savedObjectImport'), +]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/timeline_template.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/timeline_template.ts new file mode 100644 index 0000000000000..da3f0c1c210bd --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/common_attributes/timeline_template.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +export type TimelineTemplateId = t.TypeOf; +export const TimelineTemplateId = t.string; // should be non-empty string? + +export type TimelineTemplateTitle = t.TypeOf; +export const TimelineTemplateTitle = t.string; // should be non-empty string? diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.mock.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.mock.ts similarity index 86% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.mock.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.mock.ts index 5edc868a8836c..d76450a0e0425 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.mock.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.mock.ts @@ -7,18 +7,18 @@ import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../constants'; import type { - MachineLearningCreateSchema, - MachineLearningUpdateSchema, - QueryCreateSchema, - QueryUpdateSchema, - SavedQueryCreateSchema, - ThreatMatchCreateSchema, - ThresholdCreateSchema, - NewTermsCreateSchema, - NewTermsUpdateSchema, + MachineLearningRuleCreateProps, + MachineLearningRuleUpdateProps, + QueryRuleCreateProps, + QueryRuleUpdateProps, + SavedQueryRuleCreateProps, + ThreatMatchRuleCreateProps, + ThresholdRuleCreateProps, + NewTermsRuleCreateProps, + NewTermsRuleUpdateProps, } from './rule_schemas'; -export const getCreateRulesSchemaMock = (ruleId = 'rule-1'): QueryCreateSchema => ({ +export const getCreateRulesSchemaMock = (ruleId = 'rule-1'): QueryRuleCreateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', @@ -29,7 +29,7 @@ export const getCreateRulesSchemaMock = (ruleId = 'rule-1'): QueryCreateSchema = rule_id: ruleId, }); -export const getCreateRulesSchemaMockWithDataView = (ruleId = 'rule-1'): QueryCreateSchema => ({ +export const getCreateRulesSchemaMockWithDataView = (ruleId = 'rule-1'): QueryRuleCreateProps => ({ data_view_id: 'logs-*', description: 'Detecting root and admin users', name: 'Query with a rule id', @@ -41,7 +41,9 @@ export const getCreateRulesSchemaMockWithDataView = (ruleId = 'rule-1'): QueryCr rule_id: ruleId, }); -export const getCreateSavedQueryRulesSchemaMock = (ruleId = 'rule-1'): SavedQueryCreateSchema => ({ +export const getCreateSavedQueryRulesSchemaMock = ( + ruleId = 'rule-1' +): SavedQueryRuleCreateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', @@ -56,7 +58,7 @@ export const getCreateSavedQueryRulesSchemaMock = (ruleId = 'rule-1'): SavedQuer export const getCreateThreatMatchRulesSchemaMock = ( ruleId = 'rule-1', enabled = false -): ThreatMatchCreateSchema => ({ +): ThreatMatchRuleCreateProps => ({ description: 'Detecting root and admin users', enabled, index: ['auditbeat-*'], @@ -105,7 +107,7 @@ export const getCreateThreatMatchRulesSchemaMock = ( export const getCreateMachineLearningRulesSchemaMock = ( ruleId = 'rule-1' -): MachineLearningCreateSchema => ({ +): MachineLearningRuleCreateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -116,7 +118,7 @@ export const getCreateMachineLearningRulesSchemaMock = ( machine_learning_job_id: 'typical-ml-job-id', }); -export const getCreateThresholdRulesSchemaMock = (ruleId = 'rule-1'): ThresholdCreateSchema => ({ +export const getCreateThresholdRulesSchemaMock = (ruleId = 'rule-1'): ThresholdRuleCreateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -133,7 +135,7 @@ export const getCreateThresholdRulesSchemaMock = (ruleId = 'rule-1'): ThresholdC export const getCreateNewTermsRulesSchemaMock = ( ruleId = 'rule-1', enabled = false -): NewTermsCreateSchema => ({ +): NewTermsRuleCreateProps => ({ description: 'Detecting root and admin users', enabled, index: ['auditbeat-*'], @@ -152,7 +154,7 @@ export const getCreateNewTermsRulesSchemaMock = ( export const getUpdateRulesSchemaMock = ( id = '04128c15-0d1b-4716-a4c5-46997ac7f3bd' -): QueryUpdateSchema => ({ +): QueryRuleUpdateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', query: 'user.name: root or user.name: admin', @@ -165,7 +167,7 @@ export const getUpdateRulesSchemaMock = ( export const getUpdateMachineLearningSchemaMock = ( id = '04128c15-0d1b-4716-a4c5-46997ac7f3bd' -): MachineLearningUpdateSchema => ({ +): MachineLearningRuleUpdateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -178,7 +180,7 @@ export const getUpdateMachineLearningSchemaMock = ( export const getUpdateNewTermsSchemaMock = ( id = '04128c15-0d1b-4716-a4c5-46997ac7f3bd' -): NewTermsUpdateSchema => ({ +): NewTermsRuleUpdateProps => ({ description: 'Detecting root and admin users', index: ['auditbeat-*'], name: 'Query with a rule id', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.test.ts similarity index 86% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.test.ts index 12a0c08582a0f..dab249557cc5a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_request_schema.test.ts @@ -6,11 +6,13 @@ */ import * as t from 'io-ts'; -import type { CreateRulesSchema, SavedQueryCreateSchema } from './rule_schemas'; -import { createRulesSchema, responseSchema } from './rule_schemas'; -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; import { left } from 'fp-ts/lib/Either'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { getListArrayMock } from '../../schemas/types/lists.mock'; +import type { SavedQueryRuleCreateProps } from './rule_schemas'; +import { RuleCreateProps } from './rule_schemas'; import { getCreateSavedQueryRulesSchemaMock, getCreateThreatMatchRulesSchemaMock, @@ -18,14 +20,14 @@ import { getCreateThresholdRulesSchemaMock, getCreateRulesSchemaMockWithDataView, getCreateMachineLearningRulesSchemaMock, -} from './rule_schemas.mock'; -import { getListArrayMock } from '../types/lists.mock'; +} from './rule_request_schema.mock'; +import { buildResponseRuleSchema } from './build_rule_schemas'; describe('rules schema', () => { test('empty objects do not validate', () => { const payload = {}; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -33,12 +35,12 @@ describe('rules schema', () => { }); test('made up values do not validate', () => { - const payload: CreateRulesSchema & { madeUp: string } = { + const payload: RuleCreateProps & { madeUp: string } = { ...getCreateRulesSchemaMock(), madeUp: 'hi', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "madeUp"']); @@ -46,11 +48,11 @@ describe('rules schema', () => { }); test('[rule_id] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -58,12 +60,12 @@ describe('rules schema', () => { }); test('[rule_id, description] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -71,13 +73,13 @@ describe('rules schema', () => { }); test('[rule_id, description, from] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -85,14 +87,14 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', to: 'now', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -100,7 +102,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, name] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -108,7 +110,7 @@ describe('rules schema', () => { name: 'some-name', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -116,7 +118,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, name, severity] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -125,7 +127,7 @@ describe('rules schema', () => { severity: 'low', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(message.errors.length).toBeGreaterThan(0); @@ -133,7 +135,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -143,7 +145,7 @@ describe('rules schema', () => { type: 'query', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -153,7 +155,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -164,7 +166,7 @@ describe('rules schema', () => { type: 'query', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -174,7 +176,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, interval, index] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -186,7 +188,7 @@ describe('rules schema', () => { index: ['index-1'], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -196,7 +198,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, name, severity, type, query, index, interval] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -210,7 +212,7 @@ describe('rules schema', () => { interval: '5m', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -218,7 +220,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language] does not validate', () => { - const payload: Partial = { + const payload: Partial = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -232,7 +234,7 @@ describe('rules schema', () => { language: 'kuery', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -242,7 +244,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', risk_score: 50, description: 'some description', @@ -257,7 +259,7 @@ describe('rules schema', () => { language: 'kuery', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -265,7 +267,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, query, language, risk_score, output_index] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -281,7 +283,7 @@ describe('rules schema', () => { language: 'kuery', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -289,7 +291,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -302,7 +304,7 @@ describe('rules schema', () => { risk_score: 50, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -310,7 +312,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { author: [], severity_mapping: [], risk_score_mapping: [], @@ -327,7 +329,7 @@ describe('rules schema', () => { type: 'query', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -335,12 +337,12 @@ describe('rules schema', () => { }); test('You can send in a namespace', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), namespace: 'a namespace', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -348,12 +350,12 @@ describe('rules schema', () => { }); test('You can send in an empty array to threat', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), threat: [], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -361,7 +363,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, output_index, threat] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -392,7 +394,7 @@ describe('rules schema', () => { ], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -400,12 +402,12 @@ describe('rules schema', () => { }); test('allows references to be sent as valid', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), references: ['index-1'], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -413,12 +415,12 @@ describe('rules schema', () => { }); test('references cannot be numbers', () => { - const payload: Omit & { references: number[] } = { + const payload: Omit & { references: number[] } = { ...getCreateRulesSchemaMock(), references: [5], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "references"']); @@ -426,12 +428,12 @@ describe('rules schema', () => { }); test('indexes cannot be numbers', () => { - const payload: Omit & { index: number[] } = { + const payload: Omit & { index: number[] } = { ...getCreateRulesSchemaMock(), index: [5], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "5" supplied to "index"']); @@ -439,12 +441,12 @@ describe('rules schema', () => { }); test('saved_query type can have filters with it', () => { - const payload: SavedQueryCreateSchema = { + const payload: SavedQueryRuleCreateProps = { ...getCreateSavedQueryRulesSchemaMock(), filters: [], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -457,7 +459,7 @@ describe('rules schema', () => { filters: 'some string', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -467,12 +469,12 @@ describe('rules schema', () => { }); test('language validates with kuery', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), language: 'kuery', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -480,12 +482,12 @@ describe('rules schema', () => { }); test('language validates with lucene', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), language: 'lucene', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -498,7 +500,7 @@ describe('rules schema', () => { language: 'something-made-up', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -508,12 +510,12 @@ describe('rules schema', () => { }); test('max_signals cannot be negative', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), max_signals: -1, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -523,12 +525,12 @@ describe('rules schema', () => { }); test('max_signals cannot be zero', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), max_signals: 0, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "0" supplied to "max_signals"']); @@ -536,12 +538,12 @@ describe('rules schema', () => { }); test('max_signals can be 1', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), max_signals: 1, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -549,12 +551,12 @@ describe('rules schema', () => { }); test('You can optionally send in an array of tags', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), tags: ['tag_1', 'tag_2'], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -567,7 +569,7 @@ describe('rules schema', () => { tags: [0, 1, 2], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -599,7 +601,7 @@ describe('rules schema', () => { ], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -625,7 +627,7 @@ describe('rules schema', () => { ], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -649,7 +651,7 @@ describe('rules schema', () => { ], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -657,12 +659,12 @@ describe('rules schema', () => { }); test('You can optionally send in an array of false positives', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), false_positives: ['false_1', 'false_2'], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -675,7 +677,7 @@ describe('rules schema', () => { false_positives: [5, 4], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -691,7 +693,7 @@ describe('rules schema', () => { immutable: 5, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['invalid keys "immutable"']); @@ -699,12 +701,12 @@ describe('rules schema', () => { }); test('You cannot set the risk_score to 101', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), risk_score: 101, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -714,12 +716,12 @@ describe('rules schema', () => { }); test('You cannot set the risk_score to -1', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), risk_score: -1, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "-1" supplied to "risk_score"']); @@ -727,12 +729,12 @@ describe('rules schema', () => { }); test('You can set the risk_score to 0', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), risk_score: 0, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -740,12 +742,12 @@ describe('rules schema', () => { }); test('You can set the risk_score to 100', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), risk_score: 100, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -753,14 +755,14 @@ describe('rules schema', () => { }); test('You can set meta to any object you want', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), meta: { somethingMadeUp: { somethingElse: true }, }, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -773,7 +775,7 @@ describe('rules schema', () => { meta: 'should not work', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -784,12 +786,12 @@ describe('rules schema', () => { test('You can omit the query string when filters are present', () => { const { query, ...noQuery } = getCreateRulesSchemaMock(); - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...noQuery, filters: [], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -797,13 +799,13 @@ describe('rules schema', () => { }); test('validates with timeline_id and timeline_title', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), timeline_id: 'timeline-id', timeline_title: 'timeline-title', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -816,7 +818,7 @@ describe('rules schema', () => { severity: 'junk', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "junk" supplied to "severity"']); @@ -829,7 +831,7 @@ describe('rules schema', () => { actions: [{ id: 'id', action_type_id: 'action_type_id', params: {} }], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -844,7 +846,7 @@ describe('rules schema', () => { actions: [{ group: 'group', action_type_id: 'action_type_id', params: {} }], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -859,7 +861,7 @@ describe('rules schema', () => { actions: [{ group: 'group', id: 'id', params: {} }], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -874,7 +876,7 @@ describe('rules schema', () => { actions: [{ group: 'group', id: 'id', action_type_id: 'action_type_id' }], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -896,7 +898,7 @@ describe('rules schema', () => { ], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -907,12 +909,12 @@ describe('rules schema', () => { describe('note', () => { test('You can set note to a string', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), note: '# documentation markdown here', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -920,12 +922,12 @@ describe('rules schema', () => { }); test('You can set note to an empty string', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), note: '', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -940,7 +942,7 @@ describe('rules schema', () => { }, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -950,12 +952,12 @@ describe('rules schema', () => { }); test('empty name is not valid', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), name: '', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual(['Invalid value "" supplied to "name"']); @@ -963,12 +965,12 @@ describe('rules schema', () => { }); test('empty description is not valid', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { ...getCreateRulesSchemaMock(), description: '', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -978,7 +980,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -992,7 +994,7 @@ describe('rules schema', () => { note: '# some markdown', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1001,7 +1003,7 @@ describe('rules schema', () => { }); test('machine_learning type does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { type: 'machine_learning', anomaly_threshold: 50, machine_learning_job_id: 'linux_anomalous_network_activity_ecs', @@ -1023,7 +1025,7 @@ describe('rules schema', () => { rule_id: 'rule-1', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1033,7 +1035,7 @@ describe('rules schema', () => { test('saved_id is required when type is saved_query and will not validate without it', () => { /* eslint-disable @typescript-eslint/naming-convention */ const { saved_id, ...payload } = getCreateSavedQueryRulesSchemaMock(); - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1044,7 +1046,7 @@ describe('rules schema', () => { test('threshold is required when type is threshold and will not validate without it', () => { const { threshold, ...payload } = getCreateThresholdRulesSchemaMock(); - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1056,7 +1058,7 @@ describe('rules schema', () => { test('threshold rules fail validation if threshold is not greater than 0', () => { const payload = getCreateThresholdRulesSchemaMock(); payload.threshold.value = 0; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1067,7 +1069,7 @@ describe('rules schema', () => { describe('exception_list', () => { test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, and exceptions_list] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1083,7 +1085,7 @@ describe('rules schema', () => { exceptions_list: getListArrayMock(), }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1091,7 +1093,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filter, risk_score, note, and empty exceptions_list] does validate', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1107,7 +1109,7 @@ describe('rules schema', () => { exceptions_list: [], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1131,7 +1133,7 @@ describe('rules schema', () => { exceptions_list: [{ id: 'uuid_here', namespace_type: 'not a namespace type' }], }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1143,7 +1145,7 @@ describe('rules schema', () => { }); test('[rule_id, description, from, to, index, name, severity, interval, type, filters, risk_score, note, and non-existent exceptions_list] does validate with empty exceptions_list', () => { - const payload: CreateRulesSchema = { + const payload: RuleCreateProps = { rule_id: 'rule-1', description: 'some description', from: 'now-5m', @@ -1158,7 +1160,7 @@ describe('rules schema', () => { note: '# some markdown', }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1169,7 +1171,7 @@ describe('rules schema', () => { describe('threat_match', () => { test('You can set a threat query, index, mapping, filters when creating a rule', () => { const payload = getCreateThreatMatchRulesSchemaMock(); - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1180,7 +1182,7 @@ describe('rules schema', () => { /* eslint-disable @typescript-eslint/naming-convention */ const { threat_index, threat_query, threat_mapping, ...payload } = getCreateThreatMatchRulesSchemaMock(); - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1194,7 +1196,7 @@ describe('rules schema', () => { test('fails validation when threat_mapping is an empty array', () => { const payload = getCreateThreatMatchRulesSchemaMock(); payload.threat_mapping = []; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1207,7 +1209,7 @@ describe('rules schema', () => { describe('data_view_id', () => { test('validates when "data_view_id" and index are defined', () => { const payload = { ...getCreateRulesSchemaMockWithDataView(), index: ['auditbeat-*'] }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([]); @@ -1215,12 +1217,12 @@ describe('rules schema', () => { }); test('"data_view_id" cannot be a number', () => { - const payload: Omit & { data_view_id: number } = { + const payload: Omit & { data_view_id: number } = { ...getCreateRulesSchemaMockWithDataView(), data_view_id: 5, }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); expect(getPaths(left(message.errors))).toEqual([ @@ -1232,7 +1234,7 @@ describe('rules schema', () => { test('it should validate a type of "query" with "data_view_id" defined', () => { const payload = getCreateRulesSchemaMockWithDataView(); - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = getCreateRulesSchemaMockWithDataView(); @@ -1244,7 +1246,7 @@ describe('rules schema', () => { test('it should validate a type of "saved_query" with "data_view_id" defined', () => { const payload = { ...getCreateSavedQueryRulesSchemaMock(), data_view_id: 'logs-*' }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = { ...getCreateSavedQueryRulesSchemaMock(), data_view_id: 'logs-*' }; @@ -1256,7 +1258,7 @@ describe('rules schema', () => { test('it should validate a type of "threat_match" with "data_view_id" defined', () => { const payload = { ...getCreateThreatMatchRulesSchemaMock(), data_view_id: 'logs-*' }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = { ...getCreateThreatMatchRulesSchemaMock(), data_view_id: 'logs-*' }; @@ -1268,7 +1270,7 @@ describe('rules schema', () => { test('it should validate a type of "threshold" with "data_view_id" defined', () => { const payload = { ...getCreateThresholdRulesSchemaMock(), data_view_id: 'logs-*' }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = { ...getCreateThresholdRulesSchemaMock(), data_view_id: 'logs-*' }; @@ -1280,7 +1282,7 @@ describe('rules schema', () => { test('it should NOT validate a type of "machine_learning" with "data_view_id" defined', () => { const payload = { ...getCreateMachineLearningRulesSchemaMock(), data_view_id: 'logs-*' }; - const decoded = createRulesSchema.decode(payload); + const decoded = RuleCreateProps.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -1301,7 +1303,11 @@ describe('rules schema', () => { testDefaultableString: t.string, }, }; - const schema = responseSchema(testSchema.required, testSchema.optional, testSchema.defaultable); + const schema = buildResponseRuleSchema( + testSchema.required, + testSchema.optional, + testSchema.defaultable + ); describe('required fields', () => { test('should allow required fields with the correct type', () => { diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.mocks.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.mock.ts similarity index 87% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.mocks.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.mock.ts index 189cbd1045d67..0a99da6b4f6f3 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.mocks.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.mock.ts @@ -7,18 +7,18 @@ import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../constants'; import type { - EqlResponseSchema, - MachineLearningResponseSchema, - QueryResponseSchema, - SavedQueryResponseSchema, - SharedResponseSchema, - ThreatMatchResponseSchema, -} from '../request'; -import { getListArrayMock } from '../types/lists.mock'; + EqlRule, + MachineLearningRule, + QueryRule, + SavedQueryRule, + SharedResponseProps, + ThreatMatchRule, +} from './rule_schemas'; +import { getListArrayMock } from '../../schemas/types/lists.mock'; export const ANCHOR_DATE = '2020-02-20T03:57:54.037Z'; -const getResponseBaseParams = (anchorDate: string = ANCHOR_DATE): SharedResponseSchema => ({ +const getResponseBaseParams = (anchorDate: string = ANCHOR_DATE): SharedResponseProps => ({ author: [], id: '7a7065d7-6e8b-4aae-8d20-c93613dec9f9', created_at: new Date(anchorDate).toISOString(), @@ -65,7 +65,7 @@ const getResponseBaseParams = (anchorDate: string = ANCHOR_DATE): SharedResponse namespace: undefined, }); -export const getRulesSchemaMock = (anchorDate: string = ANCHOR_DATE): QueryResponseSchema => ({ +export const getRulesSchemaMock = (anchorDate: string = ANCHOR_DATE): QueryRule => ({ ...getResponseBaseParams(anchorDate), query: 'user.name: root or user.name: admin', type: 'query', @@ -76,9 +76,8 @@ export const getRulesSchemaMock = (anchorDate: string = ANCHOR_DATE): QueryRespo saved_id: undefined, response_actions: undefined, }); -export const getSavedQuerySchemaMock = ( - anchorDate: string = ANCHOR_DATE -): SavedQueryResponseSchema => ({ + +export const getSavedQuerySchemaMock = (anchorDate: string = ANCHOR_DATE): SavedQueryRule => ({ ...getResponseBaseParams(anchorDate), query: 'user.name: root or user.name: admin', type: 'saved_query', @@ -90,9 +89,7 @@ export const getSavedQuerySchemaMock = ( response_actions: undefined, }); -export const getRulesMlSchemaMock = ( - anchorDate: string = ANCHOR_DATE -): MachineLearningResponseSchema => { +export const getRulesMlSchemaMock = (anchorDate: string = ANCHOR_DATE): MachineLearningRule => { return { ...getResponseBaseParams(anchorDate), type: 'machine_learning', @@ -101,9 +98,7 @@ export const getRulesMlSchemaMock = ( }; }; -export const getThreatMatchingSchemaMock = ( - anchorDate: string = ANCHOR_DATE -): ThreatMatchResponseSchema => { +export const getThreatMatchingSchemaMock = (anchorDate: string = ANCHOR_DATE): ThreatMatchRule => { return { ...getResponseBaseParams(anchorDate), type: 'threat_match', @@ -145,9 +140,7 @@ export const getThreatMatchingSchemaMock = ( * Useful for e2e backend tests where it doesn't have date time and other * server side properties attached to it. */ -export const getThreatMatchingSchemaPartialMock = ( - enabled = false -): Partial => { +export const getThreatMatchingSchemaPartialMock = (enabled = false): Partial => { return { author: [], created_by: 'elastic', @@ -216,7 +209,7 @@ export const getThreatMatchingSchemaPartialMock = ( }; }; -export const getRulesEqlSchemaMock = (anchorDate: string = ANCHOR_DATE): EqlResponseSchema => { +export const getRulesEqlSchemaMock = (anchorDate: string = ANCHOR_DATE): EqlRule => { return { ...getResponseBaseParams(anchorDate), language: 'eql', diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.test.ts similarity index 80% rename from x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.test.ts rename to x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.test.ts index 0a337eb28bc1c..0032ee60267c4 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_response_schema.test.ts @@ -7,23 +7,22 @@ import { left } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; - import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; + +import { RuleResponse } from './rule_schemas'; import { getRulesSchemaMock, getRulesMlSchemaMock, getSavedQuerySchemaMock, getThreatMatchingSchemaMock, getRulesEqlSchemaMock, -} from './rules_schema.mocks'; -import { fullResponseSchema } from '../request'; -import type { FullResponseSchema } from '../request'; +} from './rule_response_schema.mock'; -describe('rules_schema', () => { +describe('Rule response schema', () => { test('it should validate a type of "query" without anything extra', () => { const payload = getRulesSchemaMock(); - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = getRulesSchemaMock(); @@ -33,10 +32,10 @@ describe('rules_schema', () => { }); test('it should NOT validate a type of "query" when it has extra data', () => { - const payload: FullResponseSchema & { invalid_extra_data?: string } = getRulesSchemaMock(); + const payload: RuleResponse & { invalid_extra_data?: string } = getRulesSchemaMock(); payload.invalid_extra_data = 'invalid_extra_data'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -45,10 +44,10 @@ describe('rules_schema', () => { }); test('it should NOT validate invalid_data for the type', () => { - const payload: Omit & { type: string } = getRulesSchemaMock(); + const payload: Omit & { type: string } = getRulesSchemaMock(); payload.type = 'invalid_data'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -57,11 +56,11 @@ describe('rules_schema', () => { }); test('it should validate a type of "query" with a saved_id together', () => { - const payload: FullResponseSchema & { saved_id?: string } = getRulesSchemaMock(); + const payload: RuleResponse & { saved_id?: string } = getRulesSchemaMock(); payload.type = 'query'; payload.saved_id = 'save id 123'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -72,7 +71,7 @@ describe('rules_schema', () => { test('it should validate a type of "saved_query" with a "saved_id" dependent', () => { const payload = getSavedQuerySchemaMock(); - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = getSavedQuerySchemaMock(); @@ -82,11 +81,11 @@ describe('rules_schema', () => { }); test('it should NOT validate a type of "saved_query" without a "saved_id" dependent', () => { - const payload: FullResponseSchema & { saved_id?: string } = getSavedQuerySchemaMock(); + const payload: RuleResponse & { saved_id?: string } = getSavedQuerySchemaMock(); // @ts-expect-error delete payload.saved_id; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -97,11 +96,11 @@ describe('rules_schema', () => { }); test('it should NOT validate a type of "saved_query" when it has extra data', () => { - const payload: FullResponseSchema & { saved_id?: string; invalid_extra_data?: string } = + const payload: RuleResponse & { saved_id?: string; invalid_extra_data?: string } = getSavedQuerySchemaMock(); payload.invalid_extra_data = 'invalid_extra_data'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -114,7 +113,7 @@ describe('rules_schema', () => { payload.timeline_id = 'some timeline id'; payload.timeline_title = 'some timeline title'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = getRulesSchemaMock(); @@ -126,12 +125,12 @@ describe('rules_schema', () => { }); test('it should NOT validate a type of "timeline_id" if there is "timeline_title" dependent when it has extra invalid data', () => { - const payload: FullResponseSchema & { invalid_extra_data?: string } = getRulesSchemaMock(); + const payload: RuleResponse & { invalid_extra_data?: string } = getRulesSchemaMock(); payload.timeline_id = 'some timeline id'; payload.timeline_title = 'some timeline title'; payload.invalid_extra_data = 'invalid_extra_data'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -143,7 +142,7 @@ describe('rules_schema', () => { test('it should validate an empty array for "exceptions_list"', () => { const payload = getRulesSchemaMock(); payload.exceptions_list = []; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = getRulesSchemaMock(); @@ -153,11 +152,11 @@ describe('rules_schema', () => { }); test('it should NOT validate when "exceptions_list" is not expected type', () => { - const payload: Omit & { + const payload: Omit & { exceptions_list?: string; } = { ...getRulesSchemaMock(), exceptions_list: 'invalid_data' }; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); @@ -172,7 +171,7 @@ describe('rules_schema', () => { test('it should validate a type of "query" with "data_view_id" defined', () => { const payload = { ...getRulesSchemaMock(), data_view_id: 'logs-*' }; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = { ...getRulesSchemaMock(), data_view_id: 'logs-*' }; @@ -182,14 +181,14 @@ describe('rules_schema', () => { }); test('it should validate a type of "saved_query" with "data_view_id" defined', () => { - const payload: FullResponseSchema & { saved_id?: string; data_view_id?: string } = + const payload: RuleResponse & { saved_id?: string; data_view_id?: string } = getSavedQuerySchemaMock(); payload.data_view_id = 'logs-*'; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); - const expected: FullResponseSchema & { saved_id?: string; data_view_id?: string } = + const expected: RuleResponse & { saved_id?: string; data_view_id?: string } = getSavedQuerySchemaMock(); expected.data_view_id = 'logs-*'; @@ -201,7 +200,7 @@ describe('rules_schema', () => { test('it should validate a type of "eql" with "data_view_id" defined', () => { const payload = { ...getRulesEqlSchemaMock(), data_view_id: 'logs-*' }; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = { ...getRulesEqlSchemaMock(), data_view_id: 'logs-*' }; @@ -213,7 +212,7 @@ describe('rules_schema', () => { test('it should validate a type of "threat_match" with "data_view_id" defined', () => { const payload = { ...getThreatMatchingSchemaMock(), data_view_id: 'logs-*' }; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); const expected = { ...getThreatMatchingSchemaMock(), data_view_id: 'logs-*' }; @@ -225,7 +224,7 @@ describe('rules_schema', () => { test('it should NOT validate a type of "machine_learning" with "data_view_id" defined', () => { const payload = { ...getRulesMlSchemaMock(), data_view_id: 'logs-*' }; - const decoded = fullResponseSchema.decode(payload); + const decoded = RuleResponse.decode(payload); const checked = exactCheck(payload, decoded); const message = pipe(checked, foldLeftRight); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_schemas.ts new file mode 100644 index 0000000000000..9985ef4102736 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/rule_schemas.ts @@ -0,0 +1,554 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +import { + concurrent_searches, + items_per_search, + machine_learning_job_id, + RiskScore, + RiskScoreMapping, + RuleActionArray, + RuleActionThrottle, + RuleInterval, + RuleIntervalFrom, + RuleIntervalTo, + Severity, + SeverityMapping, + threat_filters, + threat_index, + threat_indicator_path, + threat_mapping, + threat_query, +} from '@kbn/securitysolution-io-ts-alerting-types'; + +import { RuleExecutionSummary } from '../../rule_monitoring'; +import { ResponseActionArray } from '../../rule_response_actions/schemas'; +import { + saved_id, + anomaly_threshold, + updated_at, + updated_by, + created_at, + created_by, +} from '../../schemas/common'; + +import { + AlertsIndex, + AlertsIndexNamespace, + BuildingBlockType, + DataViewId, + ExceptionListArray, + IndexPatternArray, + InvestigationGuide, + IsRuleEnabled, + IsRuleImmutable, + MaxSignals, + RuleAuthorArray, + RuleDescription, + RuleFalsePositiveArray, + RuleFilterArray, + RuleLicense, + RuleMetadata, + RuleName, + RuleObjectId, + RuleQuery, + RuleReferenceArray, + RuleSignatureId, + RuleTagArray, + RuleVersion, + SetupGuide, + ThreatArray, +} from './common_attributes/misc_attributes'; +import { + RuleNameOverride, + TimestampOverride, + TimestampOverrideFallbackDisabled, +} from './common_attributes/field_overrides'; +import { + SavedObjectResolveAliasPurpose, + SavedObjectResolveAliasTargetId, + SavedObjectResolveOutcome, +} from './common_attributes/saved_objects'; +import { RelatedIntegrationArray } from './common_attributes/related_integrations'; +import { RequiredFieldArray } from './common_attributes/required_fields'; +import { TimelineTemplateId, TimelineTemplateTitle } from './common_attributes/timeline_template'; +import { + EventCategoryOverride, + TiebreakerField, + TimestampField, +} from './specific_attributes/eql_attributes'; +import { Threshold } from './specific_attributes/threshold_attributes'; +import { HistoryWindowStart, NewTermsFields } from './specific_attributes/new_terms_attributes'; + +import { buildRuleSchemas } from './build_rule_schemas'; + +// ------------------------------------------------------------------------------------------------- +// Base schema + +const baseSchema = buildRuleSchemas({ + required: { + name: RuleName, + description: RuleDescription, + risk_score: RiskScore, + severity: Severity, + }, + optional: { + // Field overrides + rule_name_override: RuleNameOverride, + timestamp_override: TimestampOverride, + timestamp_override_fallback_disabled: TimestampOverrideFallbackDisabled, + // Timeline template + timeline_id: TimelineTemplateId, + timeline_title: TimelineTemplateTitle, + // Atributes related to SavedObjectsClient.resolve API + outcome: SavedObjectResolveOutcome, + alias_target_id: SavedObjectResolveAliasTargetId, + alias_purpose: SavedObjectResolveAliasPurpose, + // Misc attributes + license: RuleLicense, + note: InvestigationGuide, + building_block_type: BuildingBlockType, + output_index: AlertsIndex, + namespace: AlertsIndexNamespace, + meta: RuleMetadata, + }, + defaultable: { + // Main attributes + version: RuleVersion, + tags: RuleTagArray, + enabled: IsRuleEnabled, + // Field overrides + risk_score_mapping: RiskScoreMapping, + severity_mapping: SeverityMapping, + // Rule schedule + interval: RuleInterval, + from: RuleIntervalFrom, + to: RuleIntervalTo, + // Rule actions + actions: RuleActionArray, + throttle: RuleActionThrottle, + // Rule exceptions + exceptions_list: ExceptionListArray, + // Misc attributes + author: RuleAuthorArray, + false_positives: RuleFalsePositiveArray, + references: RuleReferenceArray, + // maxSignals not used in ML rules but probably should be used + max_signals: MaxSignals, + threat: ThreatArray, + }, +}); + +const responseRequiredFields = { + id: RuleObjectId, + rule_id: RuleSignatureId, + immutable: IsRuleImmutable, + updated_at, + updated_by, + created_at, + created_by, + + // NOTE: For now, Related Integrations, Required Fields and Setup Guide are supported for prebuilt + // rules only. We don't want to allow users to edit these 3 fields via the API. If we added them + // to baseParams.defaultable, they would become a part of the request schema as optional fields. + // This is why we add them here, in order to add them only to the response schema. + related_integrations: RelatedIntegrationArray, + required_fields: RequiredFieldArray, + setup: SetupGuide, +}; + +const responseOptionalFields = { + execution_summary: RuleExecutionSummary, +}; + +export type BaseCreateProps = t.TypeOf; +export const BaseCreateProps = baseSchema.create; + +// ------------------------------------------------------------------------------------------------- +// Shared schemas + +// "Shared" types are the same across all rule types, and built from "baseSchema" above +// with some variations for each route. These intersect with type specific schemas below +// to create the full schema for each route. + +type SharedCreateProps = t.TypeOf; +const SharedCreateProps = t.intersection([ + baseSchema.create, + t.exact(t.partial({ rule_id: RuleSignatureId })), +]); + +type SharedUpdateProps = t.TypeOf; +const SharedUpdateProps = t.intersection([ + baseSchema.create, + t.exact(t.partial({ rule_id: RuleSignatureId })), + t.exact(t.partial({ id: RuleObjectId })), +]); + +type SharedPatchProps = t.TypeOf; +const SharedPatchProps = t.intersection([ + baseSchema.patch, + t.exact(t.partial({ rule_id: RuleSignatureId, id: RuleObjectId })), +]); + +export type SharedResponseProps = t.TypeOf; +export const SharedResponseProps = t.intersection([ + baseSchema.response, + t.exact(t.type(responseRequiredFields)), + t.exact(t.partial(responseOptionalFields)), +]); + +// ------------------------------------------------------------------------------------------------- +// EQL rule schema + +const eqlSchema = buildRuleSchemas({ + required: { + type: t.literal('eql'), + language: t.literal('eql'), + query: RuleQuery, + }, + optional: { + index: IndexPatternArray, + data_view_id: DataViewId, + filters: RuleFilterArray, + timestamp_field: TimestampField, + event_category_override: EventCategoryOverride, + tiebreaker_field: TiebreakerField, + }, + defaultable: {}, +}); + +export type EqlRule = t.TypeOf; +export const EqlRule = t.intersection([SharedResponseProps, eqlSchema.response]); + +export type EqlRuleCreateProps = t.TypeOf; +export const EqlRuleCreateProps = t.intersection([SharedCreateProps, eqlSchema.create]); + +export type EqlRuleUpdateProps = t.TypeOf; +export const EqlRuleUpdateProps = t.intersection([SharedUpdateProps, eqlSchema.create]); + +export type EqlRulePatchProps = t.TypeOf; +export const EqlRulePatchProps = t.intersection([SharedPatchProps, eqlSchema.patch]); + +export type EqlPatchParams = t.TypeOf; +export const EqlPatchParams = eqlSchema.patch; + +// ------------------------------------------------------------------------------------------------- +// Indicator Match rule schema + +const threatMatchSchema = buildRuleSchemas({ + required: { + type: t.literal('threat_match'), + query: RuleQuery, + threat_query, + threat_mapping, + threat_index, + }, + optional: { + index: IndexPatternArray, + data_view_id: DataViewId, + filters: RuleFilterArray, + saved_id, + threat_filters, + threat_indicator_path, + threat_language: t.keyof({ kuery: null, lucene: null }), + concurrent_searches, + items_per_search, + }, + defaultable: { + language: t.keyof({ kuery: null, lucene: null }), + }, +}); + +export type ThreatMatchRule = t.TypeOf; +export const ThreatMatchRule = t.intersection([SharedResponseProps, threatMatchSchema.response]); + +export type ThreatMatchRuleCreateProps = t.TypeOf; +export const ThreatMatchRuleCreateProps = t.intersection([ + SharedCreateProps, + threatMatchSchema.create, +]); + +export type ThreatMatchRuleUpdateProps = t.TypeOf; +export const ThreatMatchRuleUpdateProps = t.intersection([ + SharedUpdateProps, + threatMatchSchema.create, +]); + +export type ThreatMatchRulePatchProps = t.TypeOf; +export const ThreatMatchRulePatchProps = t.intersection([ + SharedPatchProps, + threatMatchSchema.patch, +]); + +export type ThreatMatchPatchParams = t.TypeOf; +export const ThreatMatchPatchParams = threatMatchSchema.patch; + +// ------------------------------------------------------------------------------------------------- +// Custom Query rule schema + +const querySchema = buildRuleSchemas({ + required: { + type: t.literal('query'), + }, + optional: { + index: IndexPatternArray, + data_view_id: DataViewId, + filters: RuleFilterArray, + saved_id, + response_actions: ResponseActionArray, + }, + defaultable: { + query: RuleQuery, + language: t.keyof({ kuery: null, lucene: null }), + }, +}); + +export type QueryRule = t.TypeOf; +export const QueryRule = t.intersection([SharedResponseProps, querySchema.response]); + +export type QueryRuleCreateProps = t.TypeOf; +export const QueryRuleCreateProps = t.intersection([SharedCreateProps, querySchema.create]); + +export type QueryRuleUpdateProps = t.TypeOf; +export const QueryRuleUpdateProps = t.intersection([SharedUpdateProps, querySchema.create]); + +export type QueryRulePatchProps = t.TypeOf; +export const QueryRulePatchProps = t.intersection([SharedPatchProps, querySchema.patch]); + +export type QueryPatchParams = t.TypeOf; +export const QueryPatchParams = querySchema.patch; + +// ------------------------------------------------------------------------------------------------- +// Saved Query rule schema + +const savedQuerySchema = buildRuleSchemas({ + required: { + type: t.literal('saved_query'), + saved_id, + }, + optional: { + // Having language, query, and filters possibly defined adds more code confusion and probably user confusion + // if the saved object gets deleted for some reason + index: IndexPatternArray, + data_view_id: DataViewId, + query: RuleQuery, + filters: RuleFilterArray, + response_actions: ResponseActionArray, + }, + defaultable: { + language: t.keyof({ kuery: null, lucene: null }), + }, +}); + +export type SavedQueryRule = t.TypeOf; +export const SavedQueryRule = t.intersection([SharedResponseProps, savedQuerySchema.response]); + +export type SavedQueryRuleCreateProps = t.TypeOf; +export const SavedQueryRuleCreateProps = t.intersection([ + SharedCreateProps, + savedQuerySchema.create, +]); + +export type SavedQueryRuleUpdateProps = t.TypeOf; +export const SavedQueryRuleUpdateProps = t.intersection([ + SharedUpdateProps, + savedQuerySchema.create, +]); + +export type SavedQueryRulePatchProps = t.TypeOf; +export const SavedQueryRulePatchProps = t.intersection([SharedPatchProps, savedQuerySchema.patch]); + +export type SavedQueryPatchParams = t.TypeOf; +export const SavedQueryPatchParams = savedQuerySchema.patch; + +// ------------------------------------------------------------------------------------------------- +// Threshold rule schema + +const thresholdSchema = buildRuleSchemas({ + required: { + type: t.literal('threshold'), + query: RuleQuery, + threshold: Threshold, + }, + optional: { + index: IndexPatternArray, + data_view_id: DataViewId, + filters: RuleFilterArray, + saved_id, + }, + defaultable: { + language: t.keyof({ kuery: null, lucene: null }), + }, +}); + +export type ThresholdRule = t.TypeOf; +export const ThresholdRule = t.intersection([SharedResponseProps, thresholdSchema.response]); + +export type ThresholdRuleCreateProps = t.TypeOf; +export const ThresholdRuleCreateProps = t.intersection([SharedCreateProps, thresholdSchema.create]); + +export type ThresholdRuleUpdateProps = t.TypeOf; +export const ThresholdRuleUpdateProps = t.intersection([SharedUpdateProps, thresholdSchema.create]); + +export type ThresholdRulePatchProps = t.TypeOf; +export const ThresholdRulePatchProps = t.intersection([SharedPatchProps, thresholdSchema.patch]); + +export type ThresholdPatchParams = t.TypeOf; +export const ThresholdPatchParams = thresholdSchema.patch; + +// ------------------------------------------------------------------------------------------------- +// Machine Learning rule schema + +const machineLearningSchema = buildRuleSchemas({ + required: { + type: t.literal('machine_learning'), + anomaly_threshold, + machine_learning_job_id, + }, + optional: {}, + defaultable: {}, +}); + +export type MachineLearningRule = t.TypeOf; +export const MachineLearningRule = t.intersection([ + SharedResponseProps, + machineLearningSchema.response, +]); + +export type MachineLearningRuleCreateProps = t.TypeOf; +export const MachineLearningRuleCreateProps = t.intersection([ + SharedCreateProps, + machineLearningSchema.create, +]); + +export type MachineLearningRuleUpdateProps = t.TypeOf; +export const MachineLearningRuleUpdateProps = t.intersection([ + SharedUpdateProps, + machineLearningSchema.create, +]); + +export type MachineLearningRulePatchProps = t.TypeOf; +export const MachineLearningRulePatchProps = t.intersection([ + SharedPatchProps, + machineLearningSchema.patch, +]); + +export type MachineLearningPatchParams = t.TypeOf; +export const MachineLearningPatchParams = machineLearningSchema.patch; + +// ------------------------------------------------------------------------------------------------- +// New Terms rule schema + +const newTermsSchema = buildRuleSchemas({ + required: { + type: t.literal('new_terms'), + query: RuleQuery, + new_terms_fields: NewTermsFields, + history_window_start: HistoryWindowStart, + }, + optional: { + index: IndexPatternArray, + data_view_id: DataViewId, + filters: RuleFilterArray, + }, + defaultable: { + language: t.keyof({ kuery: null, lucene: null }), + }, +}); + +export type NewTermsRule = t.TypeOf; +export const NewTermsRule = t.intersection([SharedResponseProps, newTermsSchema.response]); + +export type NewTermsRuleCreateProps = t.TypeOf; +export const NewTermsRuleCreateProps = t.intersection([SharedCreateProps, newTermsSchema.create]); + +export type NewTermsRuleUpdateProps = t.TypeOf; +export const NewTermsRuleUpdateProps = t.intersection([SharedUpdateProps, newTermsSchema.create]); + +export type NewTermsRulePatchProps = t.TypeOf; +export const NewTermsRulePatchProps = t.intersection([SharedPatchProps, newTermsSchema.patch]); + +export type NewTermsPatchParams = t.TypeOf; +export const NewTermsPatchParams = newTermsSchema.patch; + +// ------------------------------------------------------------------------------------------------- +// Combined type specific schemas + +export type TypeSpecificCreateProps = t.TypeOf; +export const TypeSpecificCreateProps = t.union([ + eqlSchema.create, + threatMatchSchema.create, + querySchema.create, + savedQuerySchema.create, + thresholdSchema.create, + machineLearningSchema.create, + newTermsSchema.create, +]); + +export type TypeSpecificPatchProps = t.TypeOf; +export const TypeSpecificPatchProps = t.union([ + eqlSchema.patch, + threatMatchSchema.patch, + querySchema.patch, + savedQuerySchema.patch, + thresholdSchema.patch, + machineLearningSchema.patch, + newTermsSchema.patch, +]); + +export type TypeSpecificResponse = t.TypeOf; +export const TypeSpecificResponse = t.union([ + eqlSchema.response, + threatMatchSchema.response, + querySchema.response, + savedQuerySchema.response, + thresholdSchema.response, + machineLearningSchema.response, + newTermsSchema.response, +]); + +// ------------------------------------------------------------------------------------------------- +// Final combined schemas + +export type RuleCreateProps = t.TypeOf; +export const RuleCreateProps = t.intersection([SharedCreateProps, TypeSpecificCreateProps]); + +export type RuleUpdateProps = t.TypeOf; +export const RuleUpdateProps = t.intersection([TypeSpecificCreateProps, SharedUpdateProps]); + +export type RulePatchProps = t.TypeOf; +export const RulePatchProps = t.intersection([TypeSpecificPatchProps, SharedPatchProps]); + +export type RuleResponse = t.TypeOf; +export const RuleResponse = t.intersection([SharedResponseProps, TypeSpecificResponse]); + +// ------------------------------------------------------------------------------------------------- +// Rule preview schemas + +// TODO: Move to the rule_preview subdomain + +export type PreviewRulesSchema = t.TypeOf; +export const previewRulesSchema = t.intersection([ + SharedCreateProps, + TypeSpecificCreateProps, + t.type({ invocationCount: t.number, timeframeEnd: t.string }), +]); + +export interface RulePreviewLogs { + errors: string[]; + warnings: string[]; + startedAt?: string; + duration: number; +} + +export interface PreviewResponse { + previewId: string | undefined; + logs: RulePreviewLogs[] | undefined; + isAborted: boolean | undefined; +} diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/eql_attributes.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/eql_attributes.ts new file mode 100644 index 0000000000000..0bc029fa0d4a5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/eql_attributes.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +// Attributes specific to EQL rules + +export type EventCategoryOverride = t.TypeOf; +export const EventCategoryOverride = t.string; // should be non-empty string? + +export type TimestampField = t.TypeOf; +export const TimestampField = t.string; // should be non-empty string? + +export type TiebreakerField = t.TypeOf; +export const TiebreakerField = t.string; // should be non-empty string? diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/new_terms_attributes.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/new_terms_attributes.ts new file mode 100644 index 0000000000000..15bf73ba150e5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/new_terms_attributes.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { LimitedSizeArray, NonEmptyString } from '@kbn/securitysolution-io-ts-types'; + +// Attributes specific to New Terms rules + +/** + * New terms rule type currently only supports a single term, but should support more in the future + */ +export type NewTermsFields = t.TypeOf; +export const NewTermsFields = LimitedSizeArray({ codec: t.string, minSize: 1, maxSize: 1 }); + +export type HistoryWindowStart = t.TypeOf; +export const HistoryWindowStart = NonEmptyString; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/threshold_attributes.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/threshold_attributes.ts new file mode 100644 index 0000000000000..eb5639c97ab3e --- /dev/null +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_schema/model/specific_attributes/threshold_attributes.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; +import { PositiveInteger, PositiveIntegerGreaterThanZero } from '@kbn/securitysolution-io-ts-types'; + +// Attributes specific to Threshold rules + +const thresholdField = t.exact( + t.type({ + field: t.union([t.string, t.array(t.string)]), // Covers pre- and post-7.12 + value: PositiveIntegerGreaterThanZero, + }) +); + +const thresholdFieldNormalized = t.exact( + t.type({ + field: t.array(t.string), + value: PositiveIntegerGreaterThanZero, + }) +); + +const thresholdCardinalityField = t.exact( + t.type({ + field: t.string, + value: PositiveInteger, + }) +); + +export type Threshold = t.TypeOf; +export const Threshold = t.intersection([ + thresholdField, + t.exact( + t.partial({ + cardinality: t.array(thresholdCardinalityField), + }) + ), +]); + +export type ThresholdNormalized = t.TypeOf; +export const ThresholdNormalized = t.intersection([ + thresholdFieldNormalized, + t.exact( + t.partial({ + cardinality: t.array(thresholdCardinalityField), + }) + ), +]); + +export type ThresholdWithCardinality = t.TypeOf; +export const ThresholdWithCardinality = t.intersection([ + thresholdFieldNormalized, + t.exact( + t.type({ + cardinality: t.array(thresholdCardinalityField), + }) + ), +]); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts index ad8745a8caf21..e129a72362ed7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/index.ts @@ -5,8 +5,6 @@ * 2.0. */ -export * from './installed_integrations'; export * from './pagination'; -export * from './rule_params'; export * from './schemas'; export * from './sorting'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts index f7c5fe6307736..52ba9e06622d4 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/common/schemas.ts @@ -7,55 +7,8 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { - IsoDateString, - NonEmptyString, - PositiveInteger, - PositiveIntegerGreaterThanZero, - UUID, - LimitedSizeArray, -} from '@kbn/securitysolution-io-ts-types'; import * as t from 'io-ts'; - -export const author = t.array(t.string); -export type Author = t.TypeOf; - -export const building_block_type = t.string; -export type BuildingBlockType = t.TypeOf; - -export const buildingBlockTypeOrUndefined = t.union([building_block_type, t.undefined]); - -export const description = NonEmptyString; -export type Description = t.TypeOf; - -// outcome is a property of the saved object resolve api -// will tell us info about the rule after 8.0 migrations -export const outcome = t.union([ - t.literal('exactMatch'), - t.literal('aliasMatch'), - t.literal('conflict'), -]); -export type Outcome = t.TypeOf; - -export const alias_target_id = t.string; -export const alias_purpose = t.union([ - t.literal('savedObjectConversion'), - t.literal('savedObjectImport'), -]); -export const enabled = t.boolean; -export type Enabled = t.TypeOf; -export const event_category_override = t.string; -export const eventCategoryOverrideOrUndefined = t.union([event_category_override, t.undefined]); - -export const tiebreaker_field = t.string; - -export const tiebreakerFieldOrUndefined = t.union([tiebreaker_field, t.undefined]); - -export const timestamp_field = t.string; - -export const timestampFieldOrUndefined = t.union([timestamp_field, t.undefined]); - -export const false_positives = t.array(t.string); +import { IsoDateString, PositiveInteger } from '@kbn/securitysolution-io-ts-types'; export const file_name = t.string; export type FileName = t.TypeOf; @@ -63,112 +16,13 @@ export type FileName = t.TypeOf; export const exclude_export_details = t.boolean; export type ExcludeExportDetails = t.TypeOf; -export const namespace = t.string; -export type Namespace = t.TypeOf; - -/** - * TODO: Right now the filters is an "unknown", when it could more than likely - * become the actual ESFilter as a type. - */ -export const filters = t.array(t.unknown); // Filters are not easily type-able yet -export type Filters = t.TypeOf; // Filters are not easily type-able yet - -export const filtersOrUndefined = t.union([filters, t.undefined]); -export type FiltersOrUndefined = t.TypeOf; - -export const immutable = t.boolean; -export type Immutable = t.TypeOf; - -// Note: Never make this a strict uuid, we allow the rule_id to be any string at the moment -// in case we encounter 3rd party rule systems which might be using auto incrementing numbers -// or other different things. -export const rule_id = t.string; -export type RuleId = t.TypeOf; - -export const ruleIdOrUndefined = t.union([rule_id, t.undefined]); -export type RuleIdOrUndefined = t.TypeOf; - -export const id = UUID; -export type Id = t.TypeOf; - -export const idOrUndefined = t.union([id, t.undefined]); -export type IdOrUndefined = t.TypeOf; - -export const index = t.array(t.string); -export type Index = t.TypeOf; - -export const data_view_id = t.string; - -export const dataViewIdOrUndefined = t.union([data_view_id, t.undefined]); - -export const indexOrUndefined = t.union([index, t.undefined]); -export type IndexOrUndefined = t.TypeOf; - -export const interval = t.string; -export type Interval = t.TypeOf; - -export const query = t.string; -export type Query = t.TypeOf; - -export const queryOrUndefined = t.union([query, t.undefined]); -export type QueryOrUndefined = t.TypeOf; - -export const license = t.string; -export type License = t.TypeOf; - -export const licenseOrUndefined = t.union([license, t.undefined]); - -export const objects = t.array(t.type({ rule_id })); - -export const output_index = t.string; - export const saved_id = t.string; export const savedIdOrUndefined = t.union([saved_id, t.undefined]); export type SavedIdOrUndefined = t.TypeOf; -export const timeline_id = t.string; -export type TimelineId = t.TypeOf; - -export const timelineIdOrUndefined = t.union([timeline_id, t.undefined]); - -export const timeline_title = t.string; - -export const timelineTitleOrUndefined = t.union([timeline_title, t.undefined]); - -export const timestamp_override = t.string; -export type TimestampOverride = t.TypeOf; - -export const timestampOverrideOrUndefined = t.union([timestamp_override, t.undefined]); -export type TimestampOverrideOrUndefined = t.TypeOf; - export const anomaly_threshold = PositiveInteger; -export const timestamp_override_fallback_disabled = t.boolean; - -export const timestampOverrideFallbackDisabledOrUndefined = t.union([ - timestamp_override_fallback_disabled, - t.undefined, -]); - -/** - * Note that this is a non-exact io-ts type as we allow extra meta information - * to be added to the meta object - */ -export const meta = t.object; -export type Meta = t.TypeOf; -export const metaOrUndefined = t.union([meta, t.undefined]); -export type MetaOrUndefined = t.TypeOf; - -export const name = NonEmptyString; -export type Name = t.TypeOf; - -export const rule_name_override = t.string; -export type RuleNameOverride = t.TypeOf; - -export const ruleNameOverrideOrUndefined = t.union([rule_name_override, t.undefined]); -export type RuleNameOverrideOrUndefined = t.TypeOf; - export const status = t.keyof({ open: null, closed: null, @@ -179,122 +33,34 @@ export type Status = t.TypeOf; export const conflicts = t.keyof({ abort: null, proceed: null }); -// TODO: Create a regular expression type or custom date math part type here -export const to = t.string; -export type To = t.TypeOf; - export const queryFilter = t.string; export type QueryFilter = t.TypeOf; export const queryFilterOrUndefined = t.union([queryFilter, t.undefined]); export type QueryFilterOrUndefined = t.TypeOf; -export const references = t.array(t.string); -export type References = t.TypeOf; - export const signal_ids = t.array(t.string); export type SignalIds = t.TypeOf; // TODO: Can this be more strict or is this is the set of all Elastic Queries? export const signal_status_query = t.object; -export const tags = t.array(t.string); -export type Tags = t.TypeOf; - export const fields = t.array(t.string); export type Fields = t.TypeOf; export const fieldsOrUndefined = t.union([fields, t.undefined]); export type FieldsOrUndefined = t.TypeOf; -export const thresholdField = t.exact( - t.type({ - field: t.union([t.string, t.array(t.string)]), // Covers pre- and post-7.12 - value: PositiveIntegerGreaterThanZero, - }) -); - -export const thresholdFieldNormalized = t.exact( - t.type({ - field: t.array(t.string), - value: PositiveIntegerGreaterThanZero, - }) -); - -export const thresholdCardinalityField = t.exact( - t.type({ - field: t.string, - value: PositiveInteger, - }) -); - -export const threshold = t.intersection([ - thresholdField, - t.exact( - t.partial({ - cardinality: t.array(thresholdCardinalityField), - }) - ), -]); -export type Threshold = t.TypeOf; - -export const thresholdNormalized = t.intersection([ - thresholdFieldNormalized, - t.exact( - t.partial({ - cardinality: t.array(thresholdCardinalityField), - }) - ), -]); -export type ThresholdNormalized = t.TypeOf; - -export const thresholdWithCardinality = t.intersection([ - thresholdFieldNormalized, - t.exact( - t.type({ - cardinality: t.array(thresholdCardinalityField), - }) - ), -]); -export type ThresholdWithCardinality = t.TypeOf; - -// New terms rule type currently only supports a single term, but should support more in the future -export const newTermsFields = LimitedSizeArray({ codec: t.string, minSize: 1, maxSize: 1 }); -export type NewTermsFields = t.TypeOf; - -export const historyWindowStart = NonEmptyString; -export type HistoryWindowStart = t.TypeOf; - export const created_at = IsoDateString; - export const updated_at = IsoDateString; - -export const updated_by = t.string; - export const created_by = t.string; +export const updated_by = t.string; -export const rules_installed = PositiveInteger; -export const rules_updated = PositiveInteger; export const status_code = PositiveInteger; export const message = t.string; export const perPage = PositiveInteger; export const total = PositiveInteger; export const success = t.boolean; export const success_count = PositiveInteger; -export const rules_custom_installed = PositiveInteger; -export const rules_not_installed = PositiveInteger; -export const rules_not_updated = PositiveInteger; - -export const timelines_installed = PositiveInteger; -export const timelines_updated = PositiveInteger; -export const timelines_not_installed = PositiveInteger; -export const timelines_not_updated = PositiveInteger; - -export const note = t.string; -export type Note = t.TypeOf; - -export const namespaceOrUndefined = t.union([namespace, t.undefined]); - -export const noteOrUndefined = t.union([note, t.undefined]); export const indexRecord = t.record( t.string, diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rule_exception_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rule_exception_schema.ts deleted file mode 100644 index e2d23d21abd53..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rule_exception_schema.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import type { CreateRuleExceptionListItemSchemaDecoded } from '@kbn/securitysolution-io-ts-list-types'; -import { createRuleExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; -import type { RequiredKeepUndefined } from '@kbn/osquery-plugin/common/types'; - -export const createRuleExceptionsSchema = t.exact( - t.type({ - items: t.array(createRuleExceptionListItemSchema), - }) -); - -export type CreateRuleExceptionSchema = t.TypeOf; - -// This type is used after a decode since some things are defaults after a decode. -export type CreateRuleExceptionSchemaDecoded = Omit< - RequiredKeepUndefined>, - 'items' -> & { - items: CreateRuleExceptionListItemSchemaDecoded[]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.ts deleted file mode 100644 index c429656d575f8..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_rules_type_dependents.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { CreateRulesSchema } from './rule_schemas'; - -export const validateTimelineId = (rule: CreateRulesSchema): string[] => { - if (rule.timeline_id != null) { - if (rule.timeline_title == null) { - return ['when "timeline_id" exists, "timeline_title" must also exist']; - } else if (rule.timeline_id === '') { - return ['"timeline_id" cannot be an empty string']; - } else { - return []; - } - } - return []; -}; - -export const validateTimelineTitle = (rule: CreateRulesSchema): string[] => { - if (rule.timeline_title != null) { - if (rule.timeline_id == null) { - return ['when "timeline_title" exists, "timeline_id" must also exist']; - } else if (rule.timeline_title === '') { - return ['"timeline_title" cannot be an empty string']; - } else { - return []; - } - } - return []; -}; - -export const validateThreatMapping = (rule: CreateRulesSchema): string[] => { - const errors: string[] = []; - if (rule.type === 'threat_match') { - if (rule.concurrent_searches != null && rule.items_per_search == null) { - errors.push('when "concurrent_searches" exists, "items_per_search" must also exist'); - } - if (rule.concurrent_searches == null && rule.items_per_search != null) { - errors.push('when "items_per_search" exists, "concurrent_searches" must also exist'); - } - } - return errors; -}; - -export const validateThreshold = (rule: CreateRulesSchema): string[] => { - const errors: string[] = []; - if (rule.type === 'threshold') { - if (!rule.threshold) { - errors.push('when "type" is "threshold", "threshold" is required'); - } else { - if ( - rule.threshold.cardinality?.length && - rule.threshold.field.includes(rule.threshold.cardinality[0].field) - ) { - errors.push('Cardinality of a field that is being aggregated on is always 1'); - } - if (Array.isArray(rule.threshold.field) && rule.threshold.field.length > 3) { - errors.push('Number of fields must be 3 or less'); - } - } - } - return errors; -}; - -export const createRuleValidateTypeDependents = (rule: CreateRulesSchema): string[] => { - return [ - ...validateTimelineId(rule), - ...validateTimelineTitle(rule), - ...validateThreatMapping(rule), - ...validateThreshold(rule), - ]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts index 55267c27ee37f..1eba4855bf0d3 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/create_signals_migration_schema.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; import { PositiveInteger, PositiveIntegerGreaterThanZero } from '@kbn/securitysolution-io-ts-types'; -import { index } from '../common/schemas'; +import { IndexPatternArray } from '../../rule_schema'; export const signalsReindexOptions = t.partial({ requests_per_second: t.number, @@ -21,7 +21,7 @@ export type SignalsReindexOptions = t.TypeOf; export const createSignalsMigrationSchema = t.intersection([ t.exact( t.type({ - index, + index: IndexPatternArray, }) ), t.exact(signalsReindexOptions), diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts deleted file mode 100644 index 9541d37c78049..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/export_rules_schema.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import { DefaultExportFileName } from '@kbn/securitysolution-io-ts-alerting-types'; -import { DefaultStringBooleanFalse } from '@kbn/securitysolution-io-ts-types'; -import type { FileName, ExcludeExportDetails } from '../common/schemas'; -import { rule_id } from '../common/schemas'; - -const objects = t.array(t.exact(t.type({ rule_id }))); -export const exportRulesSchema = t.union([t.exact(t.type({ objects })), t.null]); -export type ExportRulesSchema = t.TypeOf; -export type ExportRulesSchemaDecoded = ExportRulesSchema; - -export const exportRulesQuerySchema = t.exact( - t.partial({ file_name: DefaultExportFileName, exclude_export_details: DefaultStringBooleanFalse }) -); - -export type ExportRulesQuerySchema = t.TypeOf; - -export type ExportRulesQuerySchemaDecoded = Omit< - ExportRulesQuerySchema, - 'file_name' | 'exclude_export_details' -> & { - file_name: FileName; - exclude_export_details: ExcludeExportDetails; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_type_dependents.test.ts deleted file mode 100644 index 50afe7f970acb..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rule_type_dependents.test.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { FindRulesSchema } from './find_rules_schema'; -import { findRuleValidateTypeDependents } from './find_rules_type_dependents'; - -describe('find_rules_type_dependents', () => { - test('You can have an empty sort_field and empty sort_order', () => { - const schema: FindRulesSchema = {}; - const errors = findRuleValidateTypeDependents(schema); - expect(errors).toEqual([]); - }); - - test('You can have both a sort_field and and a sort_order', () => { - const schema: FindRulesSchema = { - sort_field: 'some field', - sort_order: 'asc', - }; - const errors = findRuleValidateTypeDependents(schema); - expect(errors).toEqual([]); - }); - - test('You cannot have sort_field without sort_order', () => { - const schema: FindRulesSchema = { - sort_field: 'some field', - }; - const errors = findRuleValidateTypeDependents(schema); - expect(errors).toEqual([ - 'when "sort_order" and "sort_field" must exist together or not at all', - ]); - }); - - test('You cannot have sort_order without sort_field', () => { - const schema: FindRulesSchema = { - sort_order: 'asc', - }; - const errors = findRuleValidateTypeDependents(schema); - expect(errors).toEqual([ - 'when "sort_order" and "sort_field" must exist together or not at all', - ]); - }); -}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_type_dependents.ts deleted file mode 100644 index f9bd6dc56f104..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/find_rules_type_dependents.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { FindRulesSchema } from './find_rules_schema'; - -export const validateSortOrder = (find: FindRulesSchema): string[] => { - if (find.sort_order != null || find.sort_field != null) { - if (find.sort_order == null || find.sort_field == null) { - return ['when "sort_order" and "sort_field" must exist together or not at all']; - } else { - return []; - } - } else { - return []; - } -}; - -export const findRuleValidateTypeDependents = (schema: FindRulesSchema): string[] => { - return [...validateSortOrder(schema)]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.ts index c0969768d8be6..f2a9fc210df2b 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/get_signals_migration_status_schema.ts @@ -7,11 +7,11 @@ import * as t from 'io-ts'; -import { from } from '@kbn/securitysolution-io-ts-alerting-types'; +import { RuleIntervalFrom } from '@kbn/securitysolution-io-ts-alerting-types'; export const getSignalsMigrationStatusSchema = t.exact( t.type({ - from, + from: RuleIntervalFrom, }) ); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.test.ts deleted file mode 100644 index cd7ec37a85edb..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/import_rules_type_dependents.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getImportRulesSchemaMock } from './import_rules_schema.mock'; -import type { ImportRulesSchema } from './import_rules_schema'; -import { importRuleValidateTypeDependents } from './import_rules_type_dependents'; - -describe('import_rules_type_dependents', () => { - test('You cannot omit timeline_title when timeline_id is present', () => { - const schema: ImportRulesSchema = { - ...getImportRulesSchemaMock(), - timeline_id: '123', - }; - delete schema.timeline_title; - const errors = importRuleValidateTypeDependents(schema); - expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); - }); - - test('You cannot have empty string for timeline_title when timeline_id is present', () => { - const schema: ImportRulesSchema = { - ...getImportRulesSchemaMock(), - timeline_id: '123', - timeline_title: '', - }; - const errors = importRuleValidateTypeDependents(schema); - expect(errors).toEqual(['"timeline_title" cannot be an empty string']); - }); - - test('You cannot have timeline_title with an empty timeline_id', () => { - const schema: ImportRulesSchema = { - ...getImportRulesSchemaMock(), - timeline_id: '', - timeline_title: 'some-title', - }; - const errors = importRuleValidateTypeDependents(schema); - expect(errors).toEqual(['"timeline_id" cannot be an empty string']); - }); - - test('You cannot have timeline_title without timeline_id', () => { - const schema: ImportRulesSchema = { - ...getImportRulesSchemaMock(), - timeline_title: 'some-title', - }; - delete schema.timeline_id; - const errors = importRuleValidateTypeDependents(schema); - expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); - }); -}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts index 6e77066299249..56ea598c58b0d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/index.ts @@ -5,18 +5,5 @@ * 2.0. */ -export * from './add_prepackaged_rules_schema'; -export * from './create_rules_bulk_schema'; -export * from './create_rule_exception_schema'; -export * from './export_rules_schema'; -export * from './find_rules_schema'; -export * from './import_rules_schema'; -export * from './patch_rules_bulk_schema'; -export * from './patch_rules_schema'; -export * from './perform_bulk_action_schema'; -export * from './query_rule_by_id_schema'; -export * from './query_rules_schema'; export * from './query_signals_index_schema'; -export * from './rule_schemas'; export * from './set_signal_status_schema'; -export * from './update_rules_bulk_schema'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts deleted file mode 100644 index 5f4f5a4b16891..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_schema.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import { patchTypeSpecific, sharedPatchSchema, thresholdPatchParams } from './rule_schemas'; - -/** - * All of the patch elements should default to undefined if not set - */ -export const patchRulesSchema = t.intersection([patchTypeSpecific, sharedPatchSchema]); -export type PatchRulesSchema = t.TypeOf; - -const thresholdPatchSchema = t.intersection([thresholdPatchParams, sharedPatchSchema]); -export type ThresholdPatchSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.test.ts deleted file mode 100644 index abb64ec5522f2..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/patch_rules_type_dependents.test.ts +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - getPatchRulesSchemaMock, - getPatchThresholdRulesSchemaMock, -} from './patch_rules_schema.mock'; -import type { PatchRulesSchema, ThresholdPatchSchema } from './patch_rules_schema'; -import { patchRuleValidateTypeDependents } from './patch_rules_type_dependents'; - -describe('patch_rules_type_dependents', () => { - test('You cannot omit timeline_title when timeline_id is present', () => { - const schema: PatchRulesSchema = { - ...getPatchRulesSchemaMock(), - timeline_id: '123', - }; - delete schema.timeline_title; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['when "timeline_id" exists, "timeline_title" must also exist']); - }); - - test('You cannot have empty string for timeline_title when timeline_id is present', () => { - const schema: PatchRulesSchema = { - ...getPatchRulesSchemaMock(), - timeline_id: '123', - timeline_title: '', - }; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['"timeline_title" cannot be an empty string']); - }); - - test('You cannot have timeline_title with an empty timeline_id', () => { - const schema: PatchRulesSchema = { - ...getPatchRulesSchemaMock(), - timeline_id: '', - timeline_title: 'some-title', - }; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['"timeline_id" cannot be an empty string']); - }); - - test('You cannot have timeline_title without timeline_id', () => { - const schema: PatchRulesSchema = { - ...getPatchRulesSchemaMock(), - timeline_title: 'some-title', - }; - delete schema.timeline_id; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['when "timeline_title" exists, "timeline_id" must also exist']); - }); - - test('You cannot have both an id and a rule_id', () => { - const schema: PatchRulesSchema = { - ...getPatchRulesSchemaMock(), - id: 'some-id', - rule_id: 'some-rule-id', - }; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['both "id" and "rule_id" cannot exist, choose one or the other']); - }); - - test('You must set either an id or a rule_id', () => { - const schema: PatchRulesSchema = { - ...getPatchRulesSchemaMock(), - }; - delete schema.id; - delete schema.rule_id; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['either "id" or "rule_id" must be set']); - }); - - test('threshold.value is required and has to be bigger than 0 when type is threshold and validates with it', () => { - const schema: ThresholdPatchSchema = { - ...getPatchThresholdRulesSchemaMock(), - threshold: { - field: '', - value: -1, - }, - }; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['"threshold.value" has to be bigger than 0']); - }); - - test('threshold.field should contain 3 items or less', () => { - const schema: ThresholdPatchSchema = { - ...getPatchThresholdRulesSchemaMock(), - threshold: { - field: ['field-1', 'field-2', 'field-3', 'field-4'], - value: 1, - }, - }; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['Number of fields must be 3 or less']); - }); - - test('threshold.cardinality[0].field should not be in threshold.field', () => { - const schema: ThresholdPatchSchema = { - ...getPatchThresholdRulesSchemaMock(), - threshold: { - field: ['field-1', 'field-2', 'field-3'], - value: 1, - cardinality: [ - { - field: 'field-1', - value: 2, - }, - ], - }, - }; - const errors = patchRuleValidateTypeDependents(schema); - expect(errors).toEqual(['Cardinality of a field that is being aggregated on is always 1']); - }); -}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rule_by_id_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rule_by_id_schema.test.ts deleted file mode 100644 index 7266bebc8027d..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rule_by_id_schema.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { QueryRuleByIdSchema } from './query_rule_by_id_schema'; -import { queryRuleByIdSchema } from './query_rule_by_id_schema'; -import { exactCheck, foldLeftRight, getPaths } from '@kbn/securitysolution-io-ts-utils'; -import { pipe } from 'fp-ts/lib/pipeable'; -import { left } from 'fp-ts/lib/Either'; - -describe('query_rule_by_id_schema', () => { - test('empty objects do not validate', () => { - const payload: Partial = {}; - - const decoded = queryRuleByIdSchema.decode(payload); - const checked = exactCheck(payload, decoded); - const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual(['Invalid value "undefined" supplied to "id"']); - expect(message.schema).toEqual({}); - }); - - test('validates string for id', () => { - const payload: Partial = { - id: '4656dc92-5832-11ea-8e2d-0242ac130003', - }; - - const decoded = queryRuleByIdSchema.decode(payload); - const checked = exactCheck(payload, decoded); - const message = pipe(checked, foldLeftRight); - expect(getPaths(left(message.errors))).toEqual([]); - expect(message.schema).toEqual({ - id: '4656dc92-5832-11ea-8e2d-0242ac130003', - }); - }); -}); diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.ts deleted file mode 100644 index afa485687043f..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/query_rules_bulk_schema.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import type { QueryRulesSchemaDecoded } from './query_rules_schema'; -import { queryRulesSchema } from './query_rules_schema'; - -export const queryRulesBulkSchema = t.array(queryRulesSchema); -export type QueryRulesBulkSchema = t.TypeOf; - -export type QueryRulesBulkSchemaDecoded = QueryRulesSchemaDecoded[]; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts deleted file mode 100644 index 61e28f1edb902..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/rule_schemas.ts +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import { - actions, - from, - risk_score, - machine_learning_job_id, - risk_score_mapping, - threat_filters, - threat_query, - threat_mapping, - threat_index, - threat_indicator_path, - concurrent_searches, - items_per_search, - threats, - severity_mapping, - severity, - max_signals, - throttle, -} from '@kbn/securitysolution-io-ts-alerting-types'; -import { listArray } from '@kbn/securitysolution-io-ts-list-types'; -import { version } from '@kbn/securitysolution-io-ts-types'; - -import { RuleExecutionSummary } from '../../rule_monitoring'; -import { - id, - index, - data_view_id, - filters, - timestamp_field, - event_category_override, - tiebreaker_field, - building_block_type, - note, - license, - timeline_id, - timeline_title, - meta, - rule_name_override, - timestamp_override, - timestamp_override_fallback_disabled, - author, - description, - false_positives, - rule_id, - immutable, - output_index, - query, - to, - references, - saved_id, - threshold, - anomaly_threshold, - name, - tags, - interval, - enabled, - outcome, - alias_target_id, - alias_purpose, - updated_at, - updated_by, - created_at, - created_by, - namespace, - RelatedIntegrationArray, - RequiredFieldArray, - SetupGuide, - newTermsFields, - historyWindowStart, -} from '../common'; -import { ResponseActionArray } from '../../rule_response_actions/schemas'; - -export const createSchema = < - Required extends t.Props, - Optional extends t.Props, - Defaultable extends t.Props ->( - requiredFields: Required, - optionalFields: Optional, - defaultableFields: Defaultable -) => { - return t.intersection([ - t.exact(t.type(requiredFields)), - t.exact(t.partial(optionalFields)), - t.exact(t.partial(defaultableFields)), - ]); -}; - -const patchSchema = < - Required extends t.Props, - Optional extends t.Props, - Defaultable extends t.Props ->( - requiredFields: Required, - optionalFields: Optional, - defaultableFields: Defaultable -) => { - return t.intersection([ - t.partial(requiredFields), - t.partial(optionalFields), - t.partial(defaultableFields), - ]); -}; - -type OrUndefined

= { - [K in keyof P]: P[K] | t.UndefinedC; -}; - -export const responseSchema = < - Required extends t.Props, - Optional extends t.Props, - Defaultable extends t.Props ->( - requiredFields: Required, - optionalFields: Optional, - defaultableFields: Defaultable -) => { - // This bit of logic is to force all fields to be accounted for in conversions from the internal - // rule schema to the response schema. Rather than use `t.partial`, which makes each field optional, - // we make each field required but possibly undefined. The result is that if a field is forgotten in - // the conversion from internal schema to response schema TS will report an error. If we just used t.partial - // instead, then optional fields can be accidentally omitted from the conversion - and any actual values - // in those fields internally will be stripped in the response. - const optionalWithUndefined = Object.keys(optionalFields).reduce((acc, key) => { - acc[key] = t.union([optionalFields[key], t.undefined]); - return acc; - }, {}) as OrUndefined; - return t.intersection([ - t.exact(t.type(requiredFields)), - t.exact(t.type(optionalWithUndefined)), - t.exact(t.type(defaultableFields)), - ]); -}; - -export const buildAPISchemas = ( - params: APIParams -) => { - return { - create: createSchema(params.required, params.optional, params.defaultable), - patch: patchSchema(params.required, params.optional, params.defaultable), - response: responseSchema(params.required, params.optional, params.defaultable), - }; -}; - -interface APIParams< - Required extends t.Props, - Optional extends t.Props, - Defaultable extends t.Props -> { - required: Required; - optional: Optional; - defaultable: Defaultable; -} - -const baseParams = { - required: { - name, - description, - risk_score, - severity, - }, - optional: { - building_block_type, - note, - license, - outcome, - alias_target_id, - alias_purpose, - output_index, - timeline_id, - timeline_title, - meta, - rule_name_override, - timestamp_override, - timestamp_override_fallback_disabled, - namespace, - }, - defaultable: { - tags, - interval, - enabled, - throttle, - actions, - author, - false_positives, - from, - // maxSignals not used in ML rules but probably should be used - max_signals, - risk_score_mapping, - severity_mapping, - threat: threats, - to, - references, - version, - exceptions_list: listArray, - }, -}; -const { - create: baseCreateParams, - patch: basePatchParams, - response: baseResponseParams, -} = buildAPISchemas(baseParams); -export { baseCreateParams }; - -// "shared" types are the same across all rule types, and built from "baseParams" above -// with some variations for each route. These intersect with type specific schemas below -// to create the full schema for each route. -export const sharedCreateSchema = t.intersection([ - baseCreateParams, - t.exact(t.partial({ rule_id })), -]); -export type SharedCreateSchema = t.TypeOf; - -export const sharedUpdateSchema = t.intersection([ - baseCreateParams, - t.exact(t.partial({ rule_id })), - t.exact(t.partial({ id })), -]); -export type SharedUpdateSchema = t.TypeOf; - -export const sharedPatchSchema = t.intersection([ - basePatchParams, - t.exact(t.partial({ rule_id, id })), -]); - -// START type specific parameter definitions -// ----------------------------------------- -const eqlRuleParams = { - required: { - type: t.literal('eql'), - language: t.literal('eql'), - query, - }, - optional: { - index, - data_view_id, - filters, - timestamp_field, - event_category_override, - tiebreaker_field, - }, - defaultable: {}, -}; -const { - create: eqlCreateParams, - patch: eqlPatchParams, - response: eqlResponseParams, -} = buildAPISchemas(eqlRuleParams); -export { eqlCreateParams, eqlResponseParams }; - -const threatMatchRuleParams = { - required: { - type: t.literal('threat_match'), - query, - threat_query, - threat_mapping, - threat_index, - }, - optional: { - index, - data_view_id, - filters, - saved_id, - threat_filters, - threat_indicator_path, - threat_language: t.keyof({ kuery: null, lucene: null }), - concurrent_searches, - items_per_search, - }, - defaultable: { - language: t.keyof({ kuery: null, lucene: null }), - }, -}; -const { - create: threatMatchCreateParams, - patch: threatMatchPatchParams, - response: threatMatchResponseParams, -} = buildAPISchemas(threatMatchRuleParams); -export { threatMatchCreateParams, threatMatchResponseParams }; - -const queryRuleParams = { - required: { - type: t.literal('query'), - }, - optional: { - index, - data_view_id, - filters, - saved_id, - response_actions: ResponseActionArray, - }, - defaultable: { - query, - language: t.keyof({ kuery: null, lucene: null }), - }, -}; -const { - create: queryCreateParams, - patch: queryPatchParams, - response: queryResponseParams, -} = buildAPISchemas(queryRuleParams); - -export { queryCreateParams, queryResponseParams }; - -const savedQueryRuleParams = { - required: { - type: t.literal('saved_query'), - saved_id, - }, - optional: { - // Having language, query, and filters possibly defined adds more code confusion and probably user confusion - // if the saved object gets deleted for some reason - index, - data_view_id, - query, - filters, - response_actions: ResponseActionArray, - }, - defaultable: { - language: t.keyof({ kuery: null, lucene: null }), - }, -}; -const { - create: savedQueryCreateParams, - patch: savedQueryPatchParams, - response: savedQueryResponseParams, -} = buildAPISchemas(savedQueryRuleParams); - -export { savedQueryCreateParams, savedQueryResponseParams }; - -const thresholdRuleParams = { - required: { - type: t.literal('threshold'), - query, - threshold, - }, - optional: { - index, - data_view_id, - filters, - saved_id, - }, - defaultable: { - language: t.keyof({ kuery: null, lucene: null }), - }, -}; -const { - create: thresholdCreateParams, - patch: thresholdPatchParams, - response: thresholdResponseParams, -} = buildAPISchemas(thresholdRuleParams); - -export { thresholdCreateParams, thresholdResponseParams }; - -const machineLearningRuleParams = { - required: { - type: t.literal('machine_learning'), - anomaly_threshold, - machine_learning_job_id, - }, - optional: {}, - defaultable: {}, -}; -const { - create: machineLearningCreateParams, - patch: machineLearningPatchParams, - response: machineLearningResponseParams, -} = buildAPISchemas(machineLearningRuleParams); - -export { machineLearningCreateParams, machineLearningResponseParams }; - -const newTermsRuleParams = { - required: { - type: t.literal('new_terms'), - query, - new_terms_fields: newTermsFields, - history_window_start: historyWindowStart, - }, - optional: { - index, - data_view_id, - filters, - }, - defaultable: { - language: t.keyof({ kuery: null, lucene: null }), - }, -}; -const { - create: newTermsCreateParams, - patch: newTermsPatchParams, - response: newTermsResponseParams, -} = buildAPISchemas(newTermsRuleParams); - -export { newTermsCreateParams, newTermsResponseParams }; -// --------------------------------------- -// END type specific parameter definitions - -export const createTypeSpecific = t.union([ - eqlCreateParams, - threatMatchCreateParams, - queryCreateParams, - savedQueryCreateParams, - thresholdCreateParams, - machineLearningCreateParams, - newTermsCreateParams, -]); -export type CreateTypeSpecific = t.TypeOf; - -// Convenience types for building specific types of rules -type CreateSchema = SharedCreateSchema & T; -export type EqlCreateSchema = CreateSchema>; -export type ThreatMatchCreateSchema = CreateSchema>; -export type QueryCreateSchema = CreateSchema>; -export type SavedQueryCreateSchema = CreateSchema>; -export type ThresholdCreateSchema = CreateSchema>; -export type MachineLearningCreateSchema = CreateSchema< - t.TypeOf ->; -export type NewTermsCreateSchema = CreateSchema>; - -export const createRulesSchema = t.intersection([sharedCreateSchema, createTypeSpecific]); -export type CreateRulesSchema = t.TypeOf; -export const previewRulesSchema = t.intersection([ - sharedCreateSchema, - createTypeSpecific, - t.type({ invocationCount: t.number, timeframeEnd: t.string }), -]); -export type PreviewRulesSchema = t.TypeOf; - -type UpdateSchema = SharedUpdateSchema & T; -export type QueryUpdateSchema = UpdateSchema>; -export type MachineLearningUpdateSchema = UpdateSchema< - t.TypeOf ->; -export type NewTermsUpdateSchema = UpdateSchema>; - -export const patchTypeSpecific = t.union([ - eqlPatchParams, - threatMatchPatchParams, - queryPatchParams, - savedQueryPatchParams, - thresholdPatchParams, - machineLearningPatchParams, - newTermsPatchParams, -]); -export { - eqlPatchParams, - threatMatchPatchParams, - queryPatchParams, - savedQueryPatchParams, - thresholdPatchParams, - machineLearningPatchParams, - newTermsPatchParams, -}; - -export type EqlPatchParams = t.TypeOf; -export type ThreatMatchPatchParams = t.TypeOf; -export type QueryPatchParams = t.TypeOf; -export type SavedQueryPatchParams = t.TypeOf; -export type ThresholdPatchParams = t.TypeOf; -export type MachineLearningPatchParams = t.TypeOf; -export type NewTermsPatchParams = t.TypeOf; - -const responseTypeSpecific = t.union([ - eqlResponseParams, - threatMatchResponseParams, - queryResponseParams, - savedQueryResponseParams, - thresholdResponseParams, - machineLearningResponseParams, - newTermsResponseParams, -]); -export type ResponseTypeSpecific = t.TypeOf; - -export const updateRulesSchema = t.intersection([createTypeSpecific, sharedUpdateSchema]); -export type UpdateRulesSchema = t.TypeOf; - -const responseRequiredFields = { - id, - rule_id, - immutable, - updated_at, - updated_by, - created_at, - created_by, - - // NOTE: For now, Related Integrations, Required Fields and Setup Guide are supported for prebuilt - // rules only. We don't want to allow users to edit these 3 fields via the API. If we added them - // to baseParams.defaultable, they would become a part of the request schema as optional fields. - // This is why we add them here, in order to add them only to the response schema. - related_integrations: RelatedIntegrationArray, - required_fields: RequiredFieldArray, - setup: SetupGuide, -}; - -const responseOptionalFields = { - execution_summary: RuleExecutionSummary, -}; - -const sharedResponseSchema = t.intersection([ - baseResponseParams, - t.exact(t.type(responseRequiredFields)), - t.exact(t.partial(responseOptionalFields)), -]); -export type SharedResponseSchema = t.TypeOf; -export const fullResponseSchema = t.intersection([sharedResponseSchema, responseTypeSpecific]); -export type FullResponseSchema = t.TypeOf; - -// Convenience types for type specific responses -type ResponseSchema = SharedResponseSchema & T; -export type EqlResponseSchema = ResponseSchema>; -export type ThreatMatchResponseSchema = ResponseSchema>; -export type QueryResponseSchema = ResponseSchema>; -export type SavedQueryResponseSchema = ResponseSchema>; -export type ThresholdResponseSchema = ResponseSchema>; -export type MachineLearningResponseSchema = ResponseSchema< - t.TypeOf ->; -export type NewTermsResponseSchema = ResponseSchema>; - -export interface RulePreviewLogs { - errors: string[]; - warnings: string[]; - startedAt?: string; - duration: number; -} - -export interface PreviewResponse { - previewId: string | undefined; - logs: RulePreviewLogs[] | undefined; - isAborted: boolean | undefined; -} diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.ts deleted file mode 100644 index 518937193cc4f..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/request/update_rules_type_dependents.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { UpdateRulesSchema } from './rule_schemas'; - -export const validateTimelineId = (rule: UpdateRulesSchema): string[] => { - if (rule.timeline_id != null) { - if (rule.timeline_title == null) { - return ['when "timeline_id" exists, "timeline_title" must also exist']; - } else if (rule.timeline_id === '') { - return ['"timeline_id" cannot be an empty string']; - } else { - return []; - } - } - return []; -}; - -export const validateTimelineTitle = (rule: UpdateRulesSchema): string[] => { - if (rule.timeline_title != null) { - if (rule.timeline_id == null) { - return ['when "timeline_title" exists, "timeline_id" must also exist']; - } else if (rule.timeline_title === '') { - return ['"timeline_title" cannot be an empty string']; - } else { - return []; - } - } - return []; -}; - -export const validateId = (rule: UpdateRulesSchema): string[] => { - if (rule.id != null && rule.rule_id != null) { - return ['both "id" and "rule_id" cannot exist, choose one or the other']; - } else if (rule.id == null && rule.rule_id == null) { - return ['either "id" or "rule_id" must be set']; - } else { - return []; - } -}; - -export const validateThreshold = (rule: UpdateRulesSchema): string[] => { - const errors: string[] = []; - if (rule.type === 'threshold') { - if (!rule.threshold) { - errors.push('when "type" is "threshold", "threshold" is required'); - } else { - if ( - rule.threshold.cardinality?.length && - rule.threshold.field.includes(rule.threshold.cardinality[0].field) - ) { - errors.push('Cardinality of a field that is being aggregated on is always 1'); - } - if (Array.isArray(rule.threshold.field) && rule.threshold.field.length > 3) { - errors.push('Number of fields must be 3 or less'); - } - } - } - return errors; -}; - -export const updateRuleValidateTypeDependents = (rule: UpdateRulesSchema): string[] => { - return [ - ...validateId(rule), - ...validateTimelineId(rule), - ...validateTimelineTitle(rule), - ...validateThreshold(rule), - ]; -}; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts index d6e1faa7a5180..2c1cf288afe03 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/error_schema.ts @@ -8,13 +8,19 @@ import { NonEmptyString } from '@kbn/securitysolution-io-ts-types'; import * as t from 'io-ts'; -import { rule_id, status_code, message } from '../common/schemas'; +import { RuleSignatureId } from '../../rule_schema'; +import { status_code, message } from '../common/schemas'; // We use id: t.string intentionally and _never_ the id from global schemas as // sometimes echo back out the id that the user gave us and it is not guaranteed // to be a UUID but rather just a string const partial = t.exact( - t.partial({ id: t.string, rule_id, list_id: NonEmptyString, item_id: NonEmptyString }) + t.partial({ + id: t.string, + rule_id: RuleSignatureId, + list_id: NonEmptyString, + item_id: NonEmptyString, + }) ); const required = t.exact( t.type({ diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts index 5c934b0d2e040..b20a956525e2e 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/index.ts @@ -6,9 +6,3 @@ */ export * from './error_schema'; -export * from './get_installed_integrations_response_schema'; -export * from './find_exception_list_references_schema'; -export * from './import_rules_schema'; -export * from './prepackaged_rules_schema'; -export * from './prepackaged_rules_status_schema'; -export * from './rules_bulk_schema'; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts deleted file mode 100644 index 50c36075a0cf2..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_schema.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import { - rules_installed, - rules_updated, - timelines_installed, - timelines_updated, -} from '../common/schemas'; - -const prePackagedRulesSchema = t.type({ - rules_installed, - rules_updated, -}); - -const prePackagedTimelinesSchema = t.type({ - timelines_installed, - timelines_updated, -}); - -export const prePackagedRulesAndTimelinesSchema = t.exact( - t.intersection([prePackagedRulesSchema, prePackagedTimelinesSchema]) -); - -export type PrePackagedRulesAndTimelinesSchema = t.TypeOf< - typeof prePackagedRulesAndTimelinesSchema ->; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts deleted file mode 100644 index 9f5cc5542bc7c..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/prepackaged_rules_status_schema.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import { - rules_installed, - rules_custom_installed, - rules_not_installed, - rules_not_updated, - timelines_installed, - timelines_not_installed, - timelines_not_updated, -} from '../common/schemas'; - -export const prePackagedTimelinesStatusSchema = t.type({ - timelines_installed, - timelines_not_installed, - timelines_not_updated, -}); - -const prePackagedRulesStatusSchema = t.type({ - rules_custom_installed, - rules_installed, - rules_not_installed, - rules_not_updated, -}); - -export const prePackagedRulesAndTimelinesStatusSchema = t.exact( - t.intersection([prePackagedRulesStatusSchema, prePackagedTimelinesStatusSchema]) -); - -export type PrePackagedRulesAndTimelinesStatusSchema = t.TypeOf< - typeof prePackagedRulesAndTimelinesStatusSchema ->; diff --git a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.ts deleted file mode 100644 index 65c55f356c44b..0000000000000 --- a/x-pack/plugins/security_solution/common/detection_engine/schemas/response/rules_bulk_schema.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -import { fullResponseSchema } from '../request'; -import { errorSchema } from './error_schema'; - -export const rulesBulkSchema = t.array(t.union([fullResponseSchema, errorSchema])); -export type RulesBulkSchema = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/utils.ts b/x-pack/plugins/security_solution/common/detection_engine/utils.ts index afa5a3950921b..36f7ee8977f5f 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/utils.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/utils.ts @@ -16,7 +16,7 @@ import type { import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; import { hasLargeValueList } from '@kbn/securitysolution-list-utils'; -import type { Threshold, ThresholdNormalized } from './schemas/common'; +import type { Threshold, ThresholdNormalized } from './rule_schema'; export const hasLargeValueItem = ( exceptionItems: Array diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index 938374b622e79..64621f0a0598d 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -14,8 +14,11 @@ import { NoteSavedObjectToReturnRuntimeType } from './note'; import type { PinnedEvent } from './pinned_event'; import { PinnedEventToReturnSavedObjectRuntimeType } from './pinned_event'; import { - alias_purpose as savedObjectResolveAliasPurpose, - outcome as savedObjectResolveOutcome, + SavedObjectResolveAliasPurpose, + SavedObjectResolveAliasTargetId, + SavedObjectResolveOutcome, +} from '../../detection_engine/rule_schema'; +import { success, success_count as successCount, } from '../../detection_engine/schemas/common/schemas'; @@ -375,11 +378,11 @@ export type SingleTimelineResponse = runtimeTypes.TypeOf { 'have.text', `Elastic rules (${expectedNumberOfRulesAfterDeletion})` ); - cy.get(RELOAD_PREBUILT_RULES_BTN).should('exist'); - cy.get(RELOAD_PREBUILT_RULES_BTN).should('have.text', 'Install 1 Elastic prebuilt rule '); + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should('exist'); + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should( + 'have.text', + 'Install 1 Elastic prebuilt rule ' + ); reloadDeletedRules(); - cy.get(RELOAD_PREBUILT_RULES_BTN).should('not.exist'); + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should('not.exist'); cy.get(ELASTIC_RULES_BTN).should( 'have.text', @@ -134,8 +137,8 @@ describe('Prebuilt rules', () => { selectNumberOfRules(numberOfRulesToBeSelected); deleteSelectedRules(); - cy.get(RELOAD_PREBUILT_RULES_BTN).should('exist'); - cy.get(RELOAD_PREBUILT_RULES_BTN).should( + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should('exist'); + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should( 'have.text', `Install ${numberOfRulesToBeSelected} Elastic prebuilt rules ` ); @@ -146,7 +149,7 @@ describe('Prebuilt rules', () => { reloadDeletedRules(); - cy.get(RELOAD_PREBUILT_RULES_BTN).should('not.exist'); + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).should('not.exist'); cy.get(ELASTIC_RULES_BTN).should( 'have.text', diff --git a/x-pack/plugins/security_solution/cypress/objects/rule.ts b/x-pack/plugins/security_solution/cypress/objects/rule.ts index 53cbdc7e84c48..59464a3ceda2f 100644 --- a/x-pack/plugins/security_solution/cypress/objects/rule.ts +++ b/x-pack/plugins/security_solution/cypress/objects/rule.ts @@ -5,11 +5,11 @@ * 2.0. */ -import type { Throttle } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { RuleActionThrottle } from '@kbn/securitysolution-io-ts-alerting-types'; import { getMockThreatData } from '../../public/detections/mitre/mitre_tactics_techniques'; import type { CompleteTimeline } from './timeline'; import { getTimeline, getIndicatorMatchTimelineTemplate } from './timeline'; -import type { FullResponseSchema } from '../../common/detection_engine/schemas/request'; +import type { RuleResponse } from '../../common/detection_engine/rule_schema'; import type { Connectors } from './connector'; const ccsRemoteName: string = Cypress.env('CCS_REMOTE_NAME'); @@ -36,7 +36,7 @@ interface Interval { } export interface Actions { - throttle: Throttle; + throttle: RuleActionThrottle; connectors: Connectors[]; } @@ -506,9 +506,7 @@ export const getEditedRule = (): CustomRule => ({ tags: [...(getExistingRule().tags || []), 'edited'], }); -export const expectedExportedRule = ( - ruleResponse: Cypress.Response -): string => { +export const expectedExportedRule = (ruleResponse: Cypress.Response): string => { const { id, updated_at: updatedAt, @@ -531,7 +529,7 @@ export const expectedExportedRule = ( // NOTE: Order of the properties in this object matters for the tests to work. // TODO: Follow up https://github.com/elastic/kibana/pull/137628 and add an explicit type to this object // without using Partial - const rule: Partial = { + const rule: Partial = { id, updated_at: updatedAt, updated_by: updatedBy, diff --git a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts index 8b717d7f6bd22..5452d59b68c07 100644 --- a/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/screens/alerts_detection_rules.ts @@ -58,8 +58,6 @@ export const RULES_TABLE_AUTOREFRESH_INDICATOR = '[data-test-subj="loadingRulesI export const RISK_SCORE = '[data-test-subj="riskScore"]'; -export const RELOAD_PREBUILT_RULES_BTN = '[data-test-subj="reloadPrebuiltRulesBtn"]'; - export const SECOND_RULE = 1; export const RULE_CHECKBOX = '.euiTableRow .euiCheckbox__input'; diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts index 13c0c7a7735bc..2bc4badf3cfa1 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts_detection_rules.ts @@ -18,7 +18,6 @@ import { RULES_TABLE_REFRESH_INDICATOR, RULES_TABLE_AUTOREFRESH_INDICATOR, PAGINATION_POPOVER_BTN, - RELOAD_PREBUILT_RULES_BTN, RULE_CHECKBOX, RULE_NAME, RULE_SWITCH, @@ -194,7 +193,7 @@ export const openIntegrationsPopover = () => { }; export const reloadDeletedRules = () => { - cy.get(RELOAD_PREBUILT_RULES_BTN).click({ force: true }); + cy.get(LOAD_PREBUILT_RULES_ON_PAGE_HEADER_BTN).click({ force: true }); }; /** diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts index 57197fe512946..f8a48dd9c8239 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/prebuilt_rules.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { PrePackagedRulesStatusResponse } from '../../../public/detections/containers/detection_engine/rules/types'; +import type { PrePackagedRulesStatusResponse } from '../../../public/detection_engine/rule_management/logic/types'; export const getPrebuiltRulesStatus = () => { return cy.request({ diff --git a/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts b/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts index 82eb2f9255b0f..099736e4f1003 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/api_calls/rules.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { Actions } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { RuleActionArray } from '@kbn/securitysolution-io-ts-alerting-types'; import type { CustomRule, @@ -258,7 +258,7 @@ export const createCustomRuleEnabled = ( ruleId = '1', interval = '100m', maxSignals = 500, - actions?: Actions + actions?: RuleActionArray ) => { const riskScore = rule.riskScore != null ? parseInt(rule.riskScore, 10) : undefined; const severity = rule.severity != null ? rule.severity.toLocaleLowerCase() : undefined; diff --git a/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts b/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts index bbfadc337f5e2..3d4f25d248e6a 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/rule_details.ts @@ -136,7 +136,7 @@ export const goBackToAllRulesTable = () => { }; export const getDetails = (title: string | RegExp) => - cy.get(DETAILS_TITLE).contains(title).next(DETAILS_DESCRIPTION); + cy.contains(DETAILS_TITLE, title).next(DETAILS_DESCRIPTION); export const assertDetailsNotExist = (title: string | RegExp) => cy.get(DETAILS_TITLE).contains(title).should('not.exist'); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx index e860713e5ce0c..662e1983680bd 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/alert_summary_view.test.tsx @@ -11,7 +11,7 @@ import { waitFor, render, act } from '@testing-library/react'; import { AlertSummaryView } from './alert_summary_view'; import { mockAlertDetailsData } from './__mocks__'; import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy'; -import { useRuleWithFallback } from '../../../detections/containers/detection_engine/rules/use_rule_with_fallback'; +import { useRuleWithFallback } from '../../../detection_engine/rule_management/logic/use_rule_with_fallback'; import { TestProviders, TestProvidersComponent } from '../../mock'; import { TimelineId } from '../../../../common/types'; @@ -20,7 +20,7 @@ import * as i18n from './translations'; jest.mock('../../lib/kibana'); -jest.mock('../../../detections/containers/detection_engine/rules/use_rule_with_fallback', () => { +jest.mock('../../../detection_engine/rule_management/logic/use_rule_with_fallback', () => { return { useRuleWithFallback: jest.fn(), }; diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx index 3da1cfdb3c6de..2b8c0d534228d 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/event_details.test.tsx @@ -51,7 +51,7 @@ mockUseGetUserCasesPermissions.mockImplementation(originalKibanaLib.useGetUserCa jest.mock('../../containers/cti/event_enrichment'); -jest.mock('../../../detections/containers/detection_engine/rules/use_rule_with_fallback', () => { +jest.mock('../../../detection_engine/rule_management/logic/use_rule_with_fallback', () => { return { useRuleWithFallback: jest.fn().mockReturnValue({ rule: { diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/investigation_guide_view.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/investigation_guide_view.tsx index 4e9ff49a2b1dd..5e2827c396f74 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/investigation_guide_view.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/investigation_guide_view.tsx @@ -13,7 +13,7 @@ import styled from 'styled-components'; import type { GetBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers'; import { useBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers'; import * as i18n from './translations'; -import { useRuleWithFallback } from '../../../detections/containers/detection_engine/rules/use_rule_with_fallback'; +import { useRuleWithFallback } from '../../../detection_engine/rule_management/logic/use_rule_with_fallback'; import { MarkdownRenderer } from '../markdown_editor'; import { LineClamp } from '../line_clamp'; import type { TimelineEventsDetailsItem } from '../../../../common/search_strategy'; diff --git a/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx b/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx index 822d4b7cc794d..a291265bc234d 100644 --- a/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/import_data_modal/index.tsx @@ -23,7 +23,7 @@ import React, { useCallback, useState } from 'react'; import type { ImportDataResponse, ImportDataProps, -} from '../../../detections/containers/detection_engine/rules'; +} from '../../../detection_engine/rule_management/logic'; import { useAppToasts } from '../../hooks/use_app_toasts'; import * as i18n from './translations'; import { showToasterMessage } from './utils'; @@ -48,6 +48,7 @@ interface ImportDataModalProps { /** * Modal component for importing Rules from a json file */ +// TODO split into two: timelines and rules export const ImportDataModalComponent = ({ checkBoxLabel, closeModal, diff --git a/x-pack/plugins/security_solution/public/common/components/import_data_modal/utils.ts b/x-pack/plugins/security_solution/public/common/components/import_data_modal/utils.ts index d6158dfe97ff6..8211c01a7bffa 100644 --- a/x-pack/plugins/security_solution/public/common/components/import_data_modal/utils.ts +++ b/x-pack/plugins/security_solution/public/common/components/import_data_modal/utils.ts @@ -14,7 +14,7 @@ import type { ImportResponseError, ImportRulesResponseError, ExceptionsImportError, -} from '../../../detections/containers/detection_engine/rules'; +} from '../../../detection_engine/rule_management/logic'; export const formatError = ( i18nFailedDetailedMessage: (message: string) => string, diff --git a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs.ts b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs.ts index ec87d2e2c22a5..0fcbe7eb39850 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs.ts @@ -28,6 +28,7 @@ export interface UseGetInstalledJobReturn { isLicensed: boolean; } +// TODO react-query export const useGetInstalledJob = (jobIds: string[]): UseGetInstalledJobReturn => { const [jobs, setJobs] = useState([]); const { addError } = useAppToasts(); diff --git a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts index 129e41f575318..9d0a3870aca13 100644 --- a/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts +++ b/x-pack/plugins/security_solution/public/common/components/ml/hooks/use_get_jobs_summary.ts @@ -10,4 +10,5 @@ import { getJobsSummary } from '../api/get_jobs_summary'; const _getJobsSummary = withOptionalSignal(getJobsSummary); +// TODO rewrite to react-query export const useGetJobsSummary = () => useAsync(_getJobsSummary); diff --git a/x-pack/plugins/security_solution/public/common/components/top_risk_score_contributors/index.tsx b/x-pack/plugins/security_solution/public/common/components/top_risk_score_contributors/index.tsx index 7f59912829438..eaf8f9f35cc66 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_risk_score_contributors/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/top_risk_score_contributors/index.tsx @@ -16,7 +16,7 @@ import * as i18n from './translations'; import type { RuleRisk } from '../../../../common/search_strategy'; -import { RuleLink } from '../../../detections/pages/detection_engine/rules/all/use_columns'; +import { RuleLink } from '../../../detection_engine/rule_management_ui/components/rules_table/use_columns'; export interface TopRiskScoreContributorsProps { loading: boolean; diff --git a/x-pack/plugins/security_solution/public/common/utils/privileges/index.ts b/x-pack/plugins/security_solution/public/common/utils/privileges/index.ts index c420630ee23ba..817bbc5f5f296 100644 --- a/x-pack/plugins/security_solution/public/common/utils/privileges/index.ts +++ b/x-pack/plugins/security_solution/public/common/utils/privileges/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { Rule } from '../../../detections/containers/detection_engine/rules'; +import type { Rule } from '../../../detection_engine/rule_management/logic'; import * as i18nActions from '../../../detections/pages/detection_engine/rules/translations'; import { isMlRule } from '../../../../common/machine_learning/helpers'; import * as detectionI18n from '../../../detections/pages/detection_engine/translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/__mocks__/api_client.ts b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/__mocks__/api_client.ts new file mode 100644 index 0000000000000..e2d98118c593e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/__mocks__/api_client.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { GetInstalledIntegrationsResponse } from '../../../../../common/detection_engine/fleet_integrations'; +import type { + FetchInstalledIntegrationsArgs, + IFleetIntegrationsApiClient, +} from '../api_client_interface'; + +export const fleetIntegrationsApi: jest.Mocked = { + fetchInstalledIntegrations: jest + .fn, [FetchInstalledIntegrationsArgs]>() + .mockResolvedValue({ + installed_integrations: [ + { + package_name: 'atlassian_bitbucket', + package_title: 'Atlassian Bitbucket', + package_version: '1.0.1', + integration_name: 'audit', + integration_title: 'Audit Logs', + is_enabled: true, + }, + { + package_name: 'system', + package_title: 'System', + package_version: '1.6.4', + is_enabled: true, + }, + ], + }), +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/__mocks__/index.ts b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/__mocks__/index.ts new file mode 100644 index 0000000000000..ebfcff4941a99 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/__mocks__/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api_client'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/api_client.ts b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/api_client.ts new file mode 100644 index 0000000000000..58cd7b17a1fb5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/api_client.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { GetInstalledIntegrationsResponse } from '../../../../common/detection_engine/fleet_integrations'; +import { GET_INSTALLED_INTEGRATIONS_URL } from '../../../../common/detection_engine/fleet_integrations'; +import { KibanaServices } from '../../../common/lib/kibana'; + +import type { + FetchInstalledIntegrationsArgs, + IFleetIntegrationsApiClient, +} from './api_client_interface'; + +export const fleetIntegrationsApi: IFleetIntegrationsApiClient = { + fetchInstalledIntegrations: ( + args: FetchInstalledIntegrationsArgs + ): Promise => { + const { packages, signal } = args; + + return http().fetch(GET_INSTALLED_INTEGRATIONS_URL, { + method: 'GET', + query: { + packages: packages?.sort()?.join(','), + }, + signal, + }); + }, +}; + +const http = () => KibanaServices.get().http; diff --git a/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/api_client_interface.ts b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/api_client_interface.ts new file mode 100644 index 0000000000000..4776b6e5528af --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/api_client_interface.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { GetInstalledIntegrationsResponse } from '../../../../common/detection_engine/fleet_integrations'; + +export interface IFleetIntegrationsApiClient { + /** + * Fetch all installed integrations. + * @throws An error if response is not OK + */ + fetchInstalledIntegrations( + args: FetchInstalledIntegrationsArgs + ): Promise; +} + +export interface FetchInstalledIntegrationsArgs { + /** + * Array of Fleet packages to filter for. + */ + packages?: string[]; + + /** + * Optional signal for cancelling the request. + */ + signal?: AbortSignal; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/index.ts b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/index.ts new file mode 100644 index 0000000000000..f20ead0b41939 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/api/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api_client_interface'; +export * from './api_client'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/index.ts b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/index.ts new file mode 100644 index 0000000000000..473b51dc47c28 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/fleet_integrations/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts similarity index 97% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts index 2ab0c7ae0b5b2..af6a82af1a9d5 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.test.ts @@ -6,12 +6,12 @@ */ import type { List } from '@kbn/securitysolution-io-ts-list-types'; -import type { CreateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; -import type { Rule } from '../../../../containers/detection_engine/rules'; +import type { RuleCreateProps } from '../../../../../common/detection_engine/rule_schema'; +import type { Rule } from '../../../rule_management/logic'; import { getListMock, getEndpointListMock, -} from '../../../../../../common/detection_engine/schemas/types/lists.mock'; +} from '../../../../../common/detection_engine/schemas/types/lists.mock'; import type { DefineStepRuleJson, ScheduleStepRuleJson, @@ -21,7 +21,7 @@ import type { ActionsStepRule, ScheduleStepRule, DefineStepRule, -} from '../types'; +} from '../../../../detections/pages/detection_engine/rules/types'; import { getTimeTypeValue, formatDefineStepData, @@ -38,8 +38,8 @@ import { mockScheduleStepRule, mockAboutStepRule, mockActionsStepRule, -} from '../all/__mocks__/mock'; -import { getThreatMock } from '../../../../../../common/detection_engine/schemas/types/threat.mock'; +} from '../../../rule_management_ui/components/rules_table/__mocks__/mock'; +import { getThreatMock } from '../../../../../common/detection_engine/schemas/types/threat.mock'; import type { Threat, Threats } from '@kbn/securitysolution-io-ts-alerting-types'; describe('helpers', () => { @@ -958,7 +958,7 @@ describe('helpers', () => { saved_id: '', }, }; - const result = formatRule( + const result = formatRule( mockDefineStepRuleWithoutSavedId, mockAbout, mockSchedule, @@ -969,14 +969,9 @@ describe('helpers', () => { }); test('returns rule without id if ruleId does not exist', () => { - const result = formatRule( - mockDefine, - mockAbout, - mockSchedule, - mockActions - ); + const result = formatRule(mockDefine, mockAbout, mockSchedule, mockActions); - expect(result).not.toHaveProperty('id'); + expect(result).not.toHaveProperty('id'); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts similarity index 96% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts index 9beeb17d3a1bb..6686239e053f9 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/helpers.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/helpers.ts @@ -23,12 +23,12 @@ import type { Type, } from '@kbn/securitysolution-io-ts-alerting-types'; import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; -import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../../common/constants'; -import { assertUnreachable } from '../../../../../../common/utility_types'; +import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../common/constants'; +import { assertUnreachable } from '../../../../../common/utility_types'; import { transformAlertToRuleAction, transformAlertToRuleResponseAction, -} from '../../../../../../common/detection_engine/transform_actions'; +} from '../../../../../common/detection_engine/transform_actions'; import type { AboutStepRule, @@ -41,10 +41,10 @@ import type { ActionsStepRuleJson, RuleStepsFormData, RuleStep, -} from '../types'; -import { DataSourceType } from '../types'; -import type { CreateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; -import { stepActionsDefaultValue } from '../../../../components/rules/step_rule_actions'; +} from '../../../../detections/pages/detection_engine/rules/types'; +import { DataSourceType } from '../../../../detections/pages/detection_engine/rules/types'; +import type { RuleCreateProps } from '../../../../../common/detection_engine/rule_schema'; +import { stepActionsDefaultValue } from '../../../../detections/components/rules/step_rule_actions'; export const getTimeTypeValue = (time: string): { unit: Unit; value: number } => { const timeObj: { unit: Unit; value: number } = { @@ -568,7 +568,7 @@ export const formatActionsStepData = (actionsStepData: ActionsStepRule): Actions // Used to format form data in rule edit and // create flows so "T" here would likely -// either be CreateRulesSchema or Rule +// either be RuleCreateProps or Rule export const formatRule = ( defineStepData: DefineStepRule, aboutStepData: AboutStepRule, @@ -593,14 +593,14 @@ export const formatPreviewRule = ({ aboutRuleData: AboutStepRule; scheduleRuleData: ScheduleStepRule; exceptionsList?: List[]; -}): CreateRulesSchema => { +}): RuleCreateProps => { const aboutStepData = { ...aboutRuleData, name: 'Preview Rule', description: 'Preview Rule', }; return { - ...formatRule( + ...formatRule( defineRuleData, aboutStepData, scheduleRuleData, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx similarity index 88% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx index 0ea11725ab27a..a5dbc91d1709b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/index.tsx @@ -18,28 +18,32 @@ import React, { useCallback, useRef, useState, useMemo, useEffect } from 'react' import styled from 'styled-components'; import type { DataViewListItem } from '@kbn/data-views-plugin/common'; -import { hasUserCRUDPermission } from '../../../../../common/utils/privileges'; -import { isThreatMatchRule } from '../../../../../../common/detection_engine/utils'; -import { useCreateRule } from '../../../../containers/detection_engine/rules'; -import type { CreateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; -import { useListsConfig } from '../../../../containers/detection_engine/lists/use_lists_config'; +import { isThreatMatchRule } from '../../../../../common/detection_engine/utils'; +import { useCreateRule } from '../../../rule_management/logic'; +import type { RuleCreateProps } from '../../../../../common/detection_engine/rule_schema'; +import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; +import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { getDetectionEngineUrl, getRuleDetailsUrl, getRulesUrl, -} from '../../../../../common/components/link_to/redirect_to_detection_engine'; -import { SecuritySolutionPageWrapper } from '../../../../../common/components/page_wrapper'; -import { displaySuccessToast, useStateToaster } from '../../../../../common/components/toasters'; -import { SpyRoute } from '../../../../../common/utils/route/spy_routes'; -import { useUserData } from '../../../../components/user_info'; -import { AccordionTitle } from '../../../../components/rules/accordion_title'; -import { StepDefineRule } from '../../../../components/rules/step_define_rule'; -import { StepAboutRule } from '../../../../components/rules/step_about_rule'; -import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; -import { StepRuleActions } from '../../../../components/rules/step_rule_actions'; -import * as RuleI18n from '../translations'; -import { redirectToDetections, getActionMessageParams, MaxWidthEuiFlexItem } from '../helpers'; +} from '../../../../common/components/link_to/redirect_to_detection_engine'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; +import { displaySuccessToast, useStateToaster } from '../../../../common/components/toasters'; +import { SpyRoute } from '../../../../common/utils/route/spy_routes'; +import { useUserData } from '../../../../detections/components/user_info'; +import { AccordionTitle } from '../../../../detections/components/rules/accordion_title'; +import { StepDefineRule } from '../../../../detections/components/rules/step_define_rule'; +import { StepAboutRule } from '../../../../detections/components/rules/step_about_rule'; +import { StepScheduleRule } from '../../../../detections/components/rules/step_schedule_rule'; +import { StepRuleActions } from '../../../../detections/components/rules/step_rule_actions'; +import * as RuleI18n from '../../../../detections/pages/detection_engine/rules/translations'; +import { + redirectToDetections, + getActionMessageParams, + MaxWidthEuiFlexItem, +} from '../../../../detections/pages/detection_engine/rules/helpers'; import type { AboutStepRule, DefineStepRule, @@ -47,26 +51,26 @@ import type { RuleStepsFormData, RuleStepsFormHooks, RuleStepsData, -} from '../types'; -import { RuleStep } from '../types'; +} from '../../../../detections/pages/detection_engine/rules/types'; +import { RuleStep } from '../../../../detections/pages/detection_engine/rules/types'; import { formatRule, stepIsValid } from './helpers'; import * as i18n from './translations'; -import { SecurityPageName } from '../../../../../app/types'; +import { SecurityPageName } from '../../../../app/types'; import { getStepScheduleDefaultValue, ruleStepsOrder, stepAboutDefaultValue, stepDefineDefaultValue, -} from '../utils'; +} from '../../../../detections/pages/detection_engine/rules/utils'; import { APP_UI_ID, DEFAULT_INDEX_KEY, DEFAULT_INDICATOR_SOURCE_PATH, DEFAULT_THREAT_INDEX_KEY, -} from '../../../../../../common/constants'; -import { useKibana, useUiSetting$ } from '../../../../../common/lib/kibana'; -import { HeaderPage } from '../../../../../common/components/header_page'; -import { PreviewFlyout } from '../preview'; +} from '../../../../../common/constants'; +import { useKibana, useUiSetting$ } from '../../../../common/lib/kibana'; +import { HeaderPage } from '../../../../common/components/header_page'; +import { PreviewFlyout } from '../../../../detections/pages/detection_engine/rules/preview'; const formHookNoop = async (): Promise => undefined; @@ -159,9 +163,8 @@ const CreateRulePageComponent: React.FC = () => { [RuleStep.scheduleRule]: false, [RuleStep.ruleActions]: false, }); - const [{ isLoading, ruleId }, setRule] = useCreateRule(); + const { mutateAsync: createRule, isLoading } = useCreateRule(); const ruleType = stepsData.current[RuleStep.defineRule].data?.ruleType; - const ruleName = stepsData.current[RuleStep.aboutRule].data?.name; const actionMessageParams = useMemo(() => getActionMessageParams(ruleType), [ruleType]); const [dataViewOptions, setDataViewOptions] = useState<{ [x: string]: DataViewListItem }>({}); const [isPreviewDisabled, setIsPreviewDisabled] = useState(false); @@ -282,19 +285,25 @@ const CreateRulePageComponent: React.FC = () => { stepIsValid(scheduleStep) && stepIsValid(actionsStep) ) { - setRule( - formatRule( + const createdRule = await createRule( + formatRule( defineStep.data, aboutStep.data, scheduleStep.data, actionsStep.data ) ); + + displaySuccessToast(i18n.SUCCESSFULLY_CREATED_RULES(createdRule.name), dispatchToaster); + navigateToApp(APP_UI_ID, { + deepLinkId: SecurityPageName.rules, + path: getRuleDetailsUrl(createdRule.id), + }); } } } }, - [goToStep, setRule, updateCurrentDataState] + [updateCurrentDataState, goToStep, createRule, dispatchToaster, navigateToApp] ); const getAccordionType = useCallback( @@ -338,15 +347,6 @@ const CreateRulePageComponent: React.FC = () => { /> ); - if (ruleName && ruleId) { - displaySuccessToast(i18n.SUCCESSFULLY_CREATED_RULES(ruleName), dispatchToaster); - navigateToApp(APP_UI_ID, { - deepLinkId: SecurityPageName.rules, - path: getRuleDetailsUrl(ruleId), - }); - return null; - } - if ( redirectToDetections( isSignalIndexExists, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_creation/translations.ts diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx similarity index 86% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx index b249aa099c8b5..78b58f95c91a0 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/index.tsx @@ -21,23 +21,23 @@ import { useParams } from 'react-router-dom'; import { noop } from 'lodash'; import type { DataViewListItem } from '@kbn/data-views-plugin/common'; -import { hasUserCRUDPermission } from '../../../../../common/utils/privileges'; -import type { UpdateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; -import { useRule, useUpdateRule } from '../../../../containers/detection_engine/rules'; -import { useListsConfig } from '../../../../containers/detection_engine/lists/use_lists_config'; -import { SecuritySolutionPageWrapper } from '../../../../../common/components/page_wrapper'; +import type { RuleUpdateProps } from '../../../../../common/detection_engine/rule_schema'; +import { useRule, useUpdateRule } from '../../../rule_management/logic'; +import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; +import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { getRuleDetailsUrl, getDetectionEngineUrl, -} from '../../../../../common/components/link_to/redirect_to_detection_engine'; -import { displaySuccessToast, useStateToaster } from '../../../../../common/components/toasters'; -import { SpyRoute } from '../../../../../common/utils/route/spy_routes'; -import { useUserData } from '../../../../components/user_info'; -import { StepPanel } from '../../../../components/rules/step_panel'; -import { StepAboutRule } from '../../../../components/rules/step_about_rule'; -import { StepDefineRule } from '../../../../components/rules/step_define_rule'; -import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; -import { StepRuleActions } from '../../../../components/rules/step_rule_actions'; +} from '../../../../common/components/link_to/redirect_to_detection_engine'; +import { displaySuccessToast, useStateToaster } from '../../../../common/components/toasters'; +import { SpyRoute } from '../../../../common/utils/route/spy_routes'; +import { useUserData } from '../../../../detections/components/user_info'; +import { StepPanel } from '../../../../detections/components/rules/step_panel'; +import { StepAboutRule } from '../../../../detections/components/rules/step_about_rule'; +import { StepDefineRule } from '../../../../detections/components/rules/step_define_rule'; +import { StepScheduleRule } from '../../../../detections/components/rules/step_schedule_rule'; +import { StepRuleActions } from '../../../../detections/components/rules/step_rule_actions'; import { formatRule, stepIsValid, @@ -45,14 +45,14 @@ import { isAboutStep, isScheduleStep, isActionsStep, -} from '../create/helpers'; +} from '../rule_creation/helpers'; import { getStepsData, redirectToDetections, getActionMessageParams, MaxWidthEuiFlexItem, -} from '../helpers'; -import * as ruleI18n from '../translations'; +} from '../../../../detections/pages/detection_engine/rules/helpers'; +import * as ruleI18n from '../../../../detections/pages/detection_engine/rules/translations'; import type { ActionsStepRule, AboutStepRule, @@ -61,22 +61,22 @@ import type { RuleStepsFormHooks, RuleStepsFormData, RuleStepsData, -} from '../types'; -import { RuleStep } from '../types'; +} from '../../../../detections/pages/detection_engine/rules/types'; +import { RuleStep } from '../../../../detections/pages/detection_engine/rules/types'; import * as i18n from './translations'; -import { SecurityPageName } from '../../../../../app/types'; -import { ruleStepsOrder } from '../utils'; -import { useKibana, useUiSetting$ } from '../../../../../common/lib/kibana'; +import { SecurityPageName } from '../../../../app/types'; +import { ruleStepsOrder } from '../../../../detections/pages/detection_engine/rules/utils'; +import { useKibana, useUiSetting$ } from '../../../../common/lib/kibana'; import { APP_UI_ID, DEFAULT_INDEX_KEY, DEFAULT_THREAT_INDEX_KEY, -} from '../../../../../../common/constants'; -import { HeaderPage } from '../../../../../common/components/header_page'; -import { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; -import { SINGLE_RULE_ACTIONS } from '../../../../../common/lib/apm/user_actions'; -import { PreviewFlyout } from '../preview'; -import { useGetSavedQuery } from '../use_get_saved_query'; +} from '../../../../../common/constants'; +import { HeaderPage } from '../../../../common/components/header_page'; +import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; +import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions'; +import { PreviewFlyout } from '../../../../detections/pages/detection_engine/rules/preview'; +import { useGetSavedQuery } from '../../../../detections/pages/detection_engine/rules/use_get_saved_query'; const formHookNoop = async (): Promise => undefined; @@ -96,8 +96,8 @@ const EditRulePageComponent: FC = () => { const { data: dataServices } = useKibana().services; const { navigateToApp } = useKibana().services.application; - const { detailName: ruleId } = useParams<{ detailName: string | undefined }>(); - const [ruleLoading, rule] = useRule(ruleId); + const { detailName: ruleId } = useParams<{ detailName: string }>(); + const { data: rule, isLoading: ruleLoading } = useRule(ruleId); const loading = ruleLoading || userInfoLoading || listsConfigLoading; const { isSavedQueryLoading, savedQueryBar, savedQuery } = useGetSavedQuery(rule?.saved_id, { @@ -126,7 +126,7 @@ const EditRulePageComponent: FC = () => { const stepData = stepsData.current[step]; return stepData.data != null && !stepIsValid(stepData); }); - const [{ isLoading, isSaved }, setRule] = useUpdateRule(); + const { mutateAsync: updateRule, isLoading } = useUpdateRule(); const [dataViewOptions, setDataViewOptions] = useState<{ [x: string]: DataViewListItem }>({}); const [isPreviewDisabled, setIsPreviewDisabled] = useState(false); const [isRulePreviewVisible, setIsRulePreviewVisible] = useState(false); @@ -358,8 +358,8 @@ const EditRulePageComponent: FC = () => { stepIsValid(actions) ) { startTransaction({ name: SINGLE_RULE_ACTIONS.SAVE }); - setRule({ - ...formatRule( + await updateRule({ + ...formatRule( define.data, about.data, schedule.data, @@ -369,17 +369,25 @@ const EditRulePageComponent: FC = () => { ...(ruleId ? { id: ruleId } : {}), ...(rule != null ? { max_signals: rule.max_signals } : {}), }); + + displaySuccessToast(i18n.SUCCESSFULLY_SAVED_RULE(rule?.name ?? ''), dispatchToaster); + navigateToApp(APP_UI_ID, { + deepLinkId: SecurityPageName.rules, + path: getRuleDetailsUrl(ruleId ?? ''), + }); } }, [ aboutStep, actionsStep, activeStep, defineStep, + dispatchToaster, + navigateToApp, rule, ruleId, scheduleStep, - setRule, setStepData, + updateRule, startTransaction, ]); @@ -432,15 +440,6 @@ const EditRulePageComponent: FC = () => { } }, [rule]); - if (isSaved) { - displaySuccessToast(i18n.SUCCESSFULLY_SAVED_RULE(rule?.name ?? ''), dispatchToaster); - navigateToApp(APP_UI_ID, { - deepLinkId: SecurityPageName.rules, - path: getRuleDetailsUrl(ruleId ?? ''), - }); - return null; - } - if ( redirectToDetections( isSignalIndexExists, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_creation_ui/pages/rule_editing/translations.ts diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/__mocks__/rule_details_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/__mocks__/rule_details_context.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/__mocks__/rule_details_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/__mocks__/rule_details_context.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/__snapshots__/execution_log_search_bar.test.tsx.snap b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/__snapshots__/execution_log_search_bar.test.tsx.snap similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/__snapshots__/execution_log_search_bar.test.tsx.snap rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/__snapshots__/execution_log_search_bar.test.tsx.snap diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx similarity index 89% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_columns.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx index 9d5fd1a974dac..610277ddcd076 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_columns.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_columns.tsx @@ -14,13 +14,13 @@ import { FormattedMessage } from '@kbn/i18n-react'; import type { RuleExecutionResult, RuleExecutionStatus, -} from '../../../../../../../common/detection_engine/rule_monitoring'; +} from '../../../../../../common/detection_engine/rule_monitoring'; -import { getEmptyValue } from '../../../../../../common/components/empty_value'; -import { FormattedDate } from '../../../../../../common/components/formatted_date'; -import { ExecutionStatusIndicator } from '../../../../../../detection_engine/rule_monitoring'; -import { PopoverTooltip } from '../../all/popover_tooltip'; -import { TableHeaderTooltipCell } from '../../all/table_header_tooltip_cell'; +import { getEmptyValue } from '../../../../../common/components/empty_value'; +import { FormattedDate } from '../../../../../common/components/formatted_date'; +import { ExecutionStatusIndicator } from '../../../../rule_monitoring'; +import { PopoverTooltip } from '../../../../rule_management_ui/components/rules_table/popover_tooltip'; +import { TableHeaderTooltipCell } from '../../../../rule_management_ui/components/rules_table/table_header_tooltip_cell'; import { RuleDurationFormat } from './rule_duration_format'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_search_bar.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_search_bar.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_search_bar.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_search_bar.test.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_search_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_search_bar.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_search_bar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_search_bar.tsx index 39a4c3ee159de..98c61183ab861 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_search_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_search_bar.tsx @@ -9,8 +9,8 @@ import React, { useCallback } from 'react'; import { replace } from 'lodash'; import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { RuleExecutionStatus } from '../../../../../../../common/detection_engine/rule_monitoring'; -import { ExecutionStatusFilter } from '../../../../../../detection_engine/rule_monitoring'; +import { RuleExecutionStatus } from '../../../../../../common/detection_engine/rule_monitoring'; +import { ExecutionStatusFilter } from '../../../../rule_monitoring'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_table.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.test.tsx similarity index 76% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_table.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.test.tsx index 52f85b228ab36..e8cc02990289e 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_table.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.test.tsx @@ -9,19 +9,17 @@ import React from 'react'; import { noop } from 'lodash/fp'; import { render, screen } from '@testing-library/react'; -import { TestProviders } from '../../../../../../common/mock'; +import { TestProviders } from '../../../../../common/mock'; import { useRuleDetailsContextMock } from '../__mocks__/rule_details_context'; -import { getRuleExecutionResultsResponseMock } from '../../../../../../../common/detection_engine/rule_monitoring/mocks'; +import { getRuleExecutionResultsResponseMock } from '../../../../../../common/detection_engine/rule_monitoring/mocks'; -import { useExecutionResults } from '../../../../../../detection_engine/rule_monitoring'; -import { useSourcererDataView } from '../../../../../../common/containers/sourcerer'; +import { useExecutionResults } from '../../../../rule_monitoring'; +import { useSourcererDataView } from '../../../../../common/containers/sourcerer'; import { useRuleDetailsContext } from '../rule_details_context'; import { ExecutionLogTable } from './execution_log_table'; -jest.mock('../../../../../../common/containers/sourcerer'); -jest.mock( - '../../../../../../detection_engine/rule_monitoring/components/execution_results_table/use_execution_results' -); +jest.mock('../../../../../common/containers/sourcerer'); +jest.mock('../../../../rule_monitoring/components/execution_results_table/use_execution_results'); jest.mock('../rule_details_context'); const mockUseSourcererDataView = useSourcererDataView as jest.Mock; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_table.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_table.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx index 11b8e15194d07..072d3b6f58174 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/execution_log_table.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/execution_log_table.tsx @@ -27,41 +27,38 @@ import { buildFilter, FILTERS } from '@kbn/es-query'; import { MAX_EXECUTION_EVENTS_DISPLAYED } from '@kbn/securitysolution-rules'; import { mountReactNode } from '@kbn/core-mount-utils-browser-internal'; -import { InputsModelId } from '../../../../../../common/store/inputs/constants'; +import { InputsModelId } from '../../../../../common/store/inputs/constants'; import { RuleDetailTabs } from '..'; -import { RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY } from '../../../../../../../common/constants'; +import { RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY } from '../../../../../../common/constants'; import type { RuleExecutionResult, RuleExecutionStatus, -} from '../../../../../../../common/detection_engine/rule_monitoring'; +} from '../../../../../../common/detection_engine/rule_monitoring'; -import { HeaderSection } from '../../../../../../common/components/header_section'; +import { HeaderSection } from '../../../../../common/components/header_section'; import { UtilityBar, UtilityBarGroup, UtilityBarSection, UtilityBarText, -} from '../../../../../../common/components/utility_bar'; -import { useSourcererDataView } from '../../../../../../common/containers/sourcerer'; -import { useAppToasts } from '../../../../../../common/hooks/use_app_toasts'; -import { useDeepEqualSelector } from '../../../../../../common/hooks/use_selector'; -import { useKibana } from '../../../../../../common/lib/kibana'; -import { inputsSelectors } from '../../../../../../common/store'; +} from '../../../../../common/components/utility_bar'; +import { useSourcererDataView } from '../../../../../common/containers/sourcerer'; +import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; +import { useDeepEqualSelector } from '../../../../../common/hooks/use_selector'; +import { useKibana } from '../../../../../common/lib/kibana'; +import { inputsSelectors } from '../../../../../common/store'; import { setAbsoluteRangeDatePicker, setFilterQuery, setRelativeRangeDatePicker, -} from '../../../../../../common/store/inputs/actions'; +} from '../../../../../common/store/inputs/actions'; import type { AbsoluteTimeRange, RelativeTimeRange, -} from '../../../../../../common/store/inputs/model'; -import { - isAbsoluteTimeRange, - isRelativeTimeRange, -} from '../../../../../../common/store/inputs/model'; -import { SourcererScopeName } from '../../../../../../common/store/sourcerer/model'; -import { useExecutionResults } from '../../../../../../detection_engine/rule_monitoring'; +} from '../../../../../common/store/inputs/model'; +import { isAbsoluteTimeRange, isRelativeTimeRange } from '../../../../../common/store/inputs/model'; +import { SourcererScopeName } from '../../../../../common/store/sourcerer/model'; +import { useExecutionResults } from '../../../../rule_monitoring'; import { useRuleDetailsContext } from '../rule_details_context'; import * as i18n from './translations'; import { EXECUTION_LOG_COLUMNS, GET_EXECUTION_LOG_METRICS_COLUMNS } from './execution_log_columns'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/rule_duration_format.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/rule_duration_format.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/rule_duration_format.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/rule_duration_format.test.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/rule_duration_format.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/rule_duration_format.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/rule_duration_format.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/rule_duration_format.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/execution_log_table/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/execution_log_table/translations.ts diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.test.tsx similarity index 84% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.test.tsx index 8130abd7efe3d..2cd73c6293a17 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.test.tsx @@ -8,64 +8,57 @@ import React from 'react'; import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; +import { tGridReducer } from '@kbn/timelines-plugin/public'; -import '../../../../../common/mock/match_media'; +import '../../../../common/mock/match_media'; import { createSecuritySolutionStorageMock, kibanaObservable, mockGlobalState, TestProviders, SUB_PLUGINS_REDUCER, -} from '../../../../../common/mock'; +} from '../../../../common/mock'; import { RuleDetailsPage } from '.'; -import type { State } from '../../../../../common/store'; -import { createStore } from '../../../../../common/store'; -import { useUserData } from '../../../../components/user_info'; -import { useRuleWithFallback } from '../../../../containers/detection_engine/rules/use_rule_with_fallback'; +import type { State } from '../../../../common/store'; +import { createStore } from '../../../../common/store'; +import { useUserData } from '../../../../detections/components/user_info'; +import { useRuleWithFallback } from '../../../rule_management/logic/use_rule_with_fallback'; -import { useSourcererDataView } from '../../../../../common/containers/sourcerer'; +import { useSourcererDataView } from '../../../../common/containers/sourcerer'; import { useParams } from 'react-router-dom'; -import { mockHistory, Router } from '../../../../../common/mock/router'; +import { mockHistory, Router } from '../../../../common/mock/router'; -import { fillEmptySeverityMappings } from '../helpers'; -import { tGridReducer } from '@kbn/timelines-plugin/public'; +import { fillEmptySeverityMappings } from '../../../../detections/pages/detection_engine/rules/helpers'; // Test will fail because we will to need to mock some core services to make the test work // For now let's forget about SiemSearchBar and QueryBar -jest.mock('../../../../../common/components/search_bar', () => ({ +jest.mock('../../../../common/components/search_bar', () => ({ SiemSearchBar: () => null, })); -jest.mock('../helpers', () => { - const original = jest.requireActual('../helpers'); +jest.mock('../../../../detections/pages/detection_engine/rules/helpers', () => { + const original = jest.requireActual( + '../../../../detections/pages/detection_engine/rules/helpers' + ); return { ...original, fillEmptySeverityMappings: jest.fn().mockReturnValue([]), }; }); -jest.mock('../../../../../common/components/query_bar', () => ({ +jest.mock('../../../../common/components/query_bar', () => ({ QueryBar: () => null, })); -jest.mock('../../../../containers/detection_engine/lists/use_lists_config'); -jest.mock('../../../../../common/components/link_to'); -jest.mock('../../../../components/user_info'); -jest.mock('../../../../containers/detection_engine/rules', () => { - const original = jest.requireActual('../../../../containers/detection_engine/rules'); - return { - ...original, - useRuleStatus: jest.fn(), - }; -}); -jest.mock('../../../../containers/detection_engine/rules/use_rule_with_fallback', () => { - const original = jest.requireActual( - '../../../../containers/detection_engine/rules/use_rule_with_fallback' - ); +jest.mock('../../../../detections/containers/detection_engine/lists/use_lists_config'); +jest.mock('../../../../common/components/link_to'); +jest.mock('../../../../detections/components/user_info'); +jest.mock('../../../rule_management/logic/use_rule_with_fallback', () => { + const original = jest.requireActual('../../../rule_management/logic/use_rule_with_fallback'); return { ...original, useRuleWithFallback: jest.fn(), }; }); -jest.mock('../../../../../common/containers/sourcerer', () => { - const actual = jest.requireActual('../../../../../common/containers/sourcerer'); +jest.mock('../../../../common/containers/sourcerer', () => { + const actual = jest.requireActual('../../../../common/containers/sourcerer'); return { ...actual, useSourcererDataView: jest @@ -73,7 +66,7 @@ jest.mock('../../../../../common/containers/sourcerer', () => { .mockReturnValue({ indexPattern: ['fakeindex'], loading: false }), }; }); -jest.mock('../../../../../common/containers/use_global_time', () => ({ +jest.mock('../../../../common/containers/use_global_time', () => ({ useGlobalTime: jest.fn().mockReturnValue({ from: '2020-07-07T08:20:18.966Z', isInitializing: false, @@ -94,8 +87,8 @@ jest.mock('react-router-dom', () => { const mockRedirectLegacyUrl = jest.fn(); const mockGetLegacyUrlConflict = jest.fn(); -jest.mock('../../../../../common/lib/kibana', () => { - const originalModule = jest.requireActual('../../../../../common/lib/kibana'); +jest.mock('../../../../common/lib/kibana', () => { + const originalModule = jest.requireActual('../../../../common/lib/kibana'); return { ...originalModule, useKibana: () => ({ diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx similarity index 86% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx index 16dbd27e03ebf..5e8c5137f47c5 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/index.tsx @@ -30,107 +30,108 @@ import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import type { Dispatch } from 'redux'; import { isTab } from '@kbn/timelines-plugin/public'; import type { DataViewListItem } from '@kbn/data-views-plugin/common'; -import { tableDefaults } from '../../../../../common/store/data_table/defaults'; -import { dataTableActions, dataTableSelectors } from '../../../../../common/store/data_table'; -import { isMlRule } from '../../../../../../common/machine_learning/helpers'; -import { SecuritySolutionTabNavigation } from '../../../../../common/components/navigation'; -import { InputsModelId } from '../../../../../common/store/inputs/constants'; + +import { isMlRule } from '../../../../../common/machine_learning/helpers'; +import { SecuritySolutionTabNavigation } from '../../../../common/components/navigation'; +import { InputsModelId } from '../../../../common/store/inputs/constants'; import { useDeepEqualSelector, useShallowEqualSelector, -} from '../../../../../common/hooks/use_selector'; -import { useKibana, useUiSetting$ } from '../../../../../common/lib/kibana'; -import { TableId } from '../../../../../../common/types/timeline'; -import type { UpdateDateRange } from '../../../../../common/components/charts/common'; -import { FiltersGlobal } from '../../../../../common/components/filters_global'; -import { FormattedDate } from '../../../../../common/components/formatted_date'; +} from '../../../../common/hooks/use_selector'; +import { useKibana, useUiSetting$ } from '../../../../common/lib/kibana'; +import { TableId } from '../../../../../common/types/timeline'; +import type { UpdateDateRange } from '../../../../common/components/charts/common'; +import { FiltersGlobal } from '../../../../common/components/filters_global'; +import { FormattedDate } from '../../../../common/components/formatted_date'; +import { tableDefaults } from '../../../../common/store/data_table/defaults'; +import { dataTableActions, dataTableSelectors } from '../../../../common/store/data_table'; import { getRulesUrl, getDetectionEngineUrl, getRuleDetailsTabUrl, -} from '../../../../../common/components/link_to/redirect_to_detection_engine'; -import { SiemSearchBar } from '../../../../../common/components/search_bar'; -import { SecuritySolutionPageWrapper } from '../../../../../common/components/page_wrapper'; -import type { Rule } from '../../../../containers/detection_engine/rules'; -import { useListsConfig } from '../../../../containers/detection_engine/lists/use_lists_config'; -import { SpyRoute } from '../../../../../common/utils/route/spy_routes'; -import { StepAboutRuleToggleDetails } from '../../../../components/rules/step_about_rule_details'; -import { AlertsHistogramPanel } from '../../../../components/alerts_kpis/alerts_histogram_panel'; -import { AlertsTable } from '../../../../components/alerts_table'; -import { useUserData } from '../../../../components/user_info'; -import { StepDefineRule } from '../../../../components/rules/step_define_rule'; -import { StepScheduleRule } from '../../../../components/rules/step_schedule_rule'; +} from '../../../../common/components/link_to/redirect_to_detection_engine'; +import { SiemSearchBar } from '../../../../common/components/search_bar'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; +import type { Rule } from '../../../rule_management/logic'; +import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; +import { SpyRoute } from '../../../../common/utils/route/spy_routes'; +import { StepAboutRuleToggleDetails } from '../../../../detections/components/rules/step_about_rule_details'; +import { AlertsHistogramPanel } from '../../../../detections/components/alerts_kpis/alerts_histogram_panel'; +import { AlertsTable } from '../../../../detections/components/alerts_table'; +import { useUserData } from '../../../../detections/components/user_info'; +import { StepDefineRule } from '../../../../detections/components/rules/step_define_rule'; +import { StepScheduleRule } from '../../../../detections/components/rules/step_schedule_rule'; import { buildAlertsFilter, buildAlertStatusFilter, buildShowBuildingBlockFilter, buildThreatMatchFilter, -} from '../../../../components/alerts_table/default_config'; -import { RuleSwitch } from '../../../../components/rules/rule_switch'; -import { StepPanel } from '../../../../components/rules/step_panel'; -import { getStepsData, redirectToDetections } from '../helpers'; -import { useGlobalTime } from '../../../../../common/containers/use_global_time'; -import { inputsSelectors } from '../../../../../common/store/inputs'; -import { setAbsoluteRangeDatePicker } from '../../../../../common/store/inputs/actions'; -import { RuleActionsOverflow } from '../../../../components/rules/rule_actions_overflow'; -import { useMlCapabilities } from '../../../../../common/components/ml/hooks/use_ml_capabilities'; -import { hasMlAdminPermissions } from '../../../../../../common/machine_learning/has_ml_admin_permissions'; -import { hasMlLicense } from '../../../../../../common/machine_learning/has_ml_license'; -import { SecurityPageName } from '../../../../../app/types'; +} from '../../../../detections/components/alerts_table/default_config'; +import { RuleSwitch } from '../../../../detections/components/rules/rule_switch'; +import { StepPanel } from '../../../../detections/components/rules/step_panel'; +import { + getStepsData, + redirectToDetections, +} from '../../../../detections/pages/detection_engine/rules/helpers'; +import { useGlobalTime } from '../../../../common/containers/use_global_time'; +import { inputsSelectors } from '../../../../common/store/inputs'; +import { setAbsoluteRangeDatePicker } from '../../../../common/store/inputs/actions'; +import { RuleActionsOverflow } from '../../../../detections/components/rules/rule_actions_overflow'; +import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; +import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { SecurityPageName } from '../../../../app/types'; import { APP_UI_ID, DEFAULT_INDEX_KEY, DEFAULT_THREAT_INDEX_KEY, -} from '../../../../../../common/constants'; -import { useGlobalFullScreen } from '../../../../../common/containers/use_full_screen'; -import { Display } from '../../../../../hosts/pages/display'; +} from '../../../../../common/constants'; +import { useGlobalFullScreen } from '../../../../common/containers/use_full_screen'; +import { Display } from '../../../../hosts/pages/display'; import { focusUtilityBarAction, onTimelineTabKeyPressed, resetKeyboardFocus, showGlobalFilters, -} from '../../../../../timelines/components/timeline/helpers'; -import { useSourcererDataView } from '../../../../../common/containers/sourcerer'; -import { SourcererScopeName } from '../../../../../common/store/sourcerer/model'; +} from '../../../../timelines/components/timeline/helpers'; +import { useSourcererDataView } from '../../../../common/containers/sourcerer'; +import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; import { explainLackOfPermission, canEditRuleWithActions, isBoolean, hasUserCRUDPermission, -} from '../../../../../common/utils/privileges'; +} from '../../../../common/utils/privileges'; import { RuleStatus, RuleStatusFailedCallOut, ruleStatusI18n, -} from '../../../../components/rules/rule_execution_status'; -import { - ExecutionEventsTable, - useRuleExecutionSettings, -} from '../../../../../detection_engine/rule_monitoring'; +} from '../../../../detections/components/rules/rule_execution_status'; +import { ExecutionEventsTable, useRuleExecutionSettings } from '../../../rule_monitoring'; import { ExecutionLogTable } from './execution_log_table/execution_log_table'; -import * as detectionI18n from '../../translations'; -import * as ruleI18n from '../translations'; +import * as detectionI18n from '../../../../detections/pages/detection_engine/translations'; +import * as ruleI18n from '../../../../detections/pages/detection_engine/rules/translations'; import { RuleDetailsContextProvider } from './rule_details_context'; -import { useGetSavedQuery } from '../use_get_saved_query'; +import { useGetSavedQuery } from '../../../../detections/pages/detection_engine/rules/use_get_saved_query'; import * as i18n from './translations'; -import { NeedAdminForUpdateRulesCallOut } from '../../../../components/callouts/need_admin_for_update_callout'; -import { MissingPrivilegesCallOut } from '../../../../components/callouts/missing_privileges_callout'; -import { useRuleWithFallback } from '../../../../containers/detection_engine/rules/use_rule_with_fallback'; -import type { BadgeOptions } from '../../../../../common/components/header_page/types'; -import type { AlertsStackByField } from '../../../../components/alerts_kpis/common/types'; -import type { Status } from '../../../../../../common/detection_engine/schemas/common/schemas'; +import { NeedAdminForUpdateRulesCallOut } from '../../../../detections/components/callouts/need_admin_for_update_callout'; +import { MissingPrivilegesCallOut } from '../../../../detections/components/callouts/missing_privileges_callout'; +import { useRuleWithFallback } from '../../../rule_management/logic/use_rule_with_fallback'; +import type { BadgeOptions } from '../../../../common/components/header_page/types'; +import type { AlertsStackByField } from '../../../../detections/components/alerts_kpis/common/types'; +import type { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; import { AlertsTableFilterGroup, FILTER_OPEN, -} from '../../../../components/alerts_table/alerts_filter_group'; -import { useSignalHelpers } from '../../../../../common/containers/sourcerer/use_signal_helpers'; -import { HeaderPage } from '../../../../../common/components/header_page'; -import { ExceptionsViewer } from '../../../../../detection_engine/rule_exceptions/components/all_exception_items_table'; -import type { NavTab } from '../../../../../common/components/navigation/types'; -import { EditRuleSettingButtonLink } from './components/edit_rule_settings_button_link'; +} from '../../../../detections/components/alerts_table/alerts_filter_group'; +import { useSignalHelpers } from '../../../../common/containers/sourcerer/use_signal_helpers'; +import { HeaderPage } from '../../../../common/components/header_page'; +import { ExceptionsViewer } from '../../../rule_exceptions/components/all_exception_items_table'; +import type { NavTab } from '../../../../common/components/navigation/types'; +import { EditRuleSettingButtonLink } from '../../../../detections/pages/detection_engine/rules/details/components/edit_rule_settings_button_link'; /** * Need a 100% height here to account for the graph/analyze tool, which sets no explicit height parameters, but fills the available space. diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/rule_details_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_details_context.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/rule_details_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_details_context.tsx index 58b34eb4a2bee..92de2e337dcad 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/rule_details_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/rule_details_context.tsx @@ -8,13 +8,13 @@ import type { SortOrder } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { DurationRange } from '@elastic/eui/src/components/date_picker/types'; import React, { createContext, useContext, useMemo, useState } from 'react'; -import { RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY } from '../../../../../../common/constants'; +import { RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY } from '../../../../../common/constants'; import type { RuleExecutionResult, RuleExecutionStatus, -} from '../../../../../../common/detection_engine/rule_monitoring'; -import { invariant } from '../../../../../../common/utils/invariant'; -import { useKibana } from '../../../../../common/lib/kibana'; +} from '../../../../../common/detection_engine/rule_monitoring'; +import { invariant } from '../../../../../common/utils/invariant'; +import { useKibana } from '../../../../common/lib/kibana'; import { RuleDetailTabs } from '.'; export interface ExecutionLogTableState { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_details_ui/pages/rule_details/translations.ts diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.test.tsx index 0613f08b7f572..d422c7c5ce6bf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.test.tsx @@ -23,7 +23,7 @@ import { useCreateOrUpdateException } from '../../logic/use_create_update_except import { useFetchIndexPatterns } from '../../logic/use_exception_flyout_data'; import { useSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_signal_index'; import * as helpers from '../../utils/helpers'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; import * as i18n from './translations'; import { TestProviders } from '../../../../common/mock'; @@ -31,15 +31,14 @@ import { TestProviders } from '../../../../common/mock'; import { getRulesEqlSchemaMock, getRulesSchemaMock, -} from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; +} from '../../../../../common/detection_engine/rule_schema/mocks'; import type { AlertData } from '../../utils/types'; -import { useFindRules } from '../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'; +import { useFindRules } from '../../../rule_management/logic/use_find_rules'; import { useFindExceptionListReferences } from '../../logic/use_find_references'; jest.mock('../../../../detections/containers/detection_engine/alerts/use_signal_index'); jest.mock('../../../../common/lib/kibana'); jest.mock('../../../../common/containers/source'); -jest.mock('../../../../detections/containers/detection_engine/rules'); jest.mock('../../logic/use_create_update_exception'); jest.mock('../../logic/use_exception_flyout_data'); jest.mock('../../logic/use_find_references'); @@ -47,9 +46,9 @@ jest.mock('@kbn/securitysolution-hook-utils', () => ({ ...jest.requireActual('@kbn/securitysolution-hook-utils'), useAsync: jest.fn(), })); -jest.mock('../../../../detections/containers/detection_engine/rules/use_rule_async'); +jest.mock('../../../rule_management/logic/use_rule'); jest.mock('@kbn/lists-plugin/public'); -jest.mock('../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'); +jest.mock('../../../rule_management/logic/use_find_rules'); const mockGetExceptionBuilderComponentLazy = getExceptionBuilderComponentLazy as jest.Mock< ReturnType diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx index 6d190913e358d..413973faff766 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/index.tsx @@ -24,16 +24,18 @@ import { EuiCallOut, EuiText, } from '@elastic/eui'; + +import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import type { OsTypeArray, ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; import type { ExceptionsBuilderExceptionItem, ExceptionsBuilderReturnExceptionItem, } from '@kbn/securitysolution-list-utils'; -import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; import type { Status } from '../../../../../common/detection_engine/schemas/common/schemas'; import * as i18n from './translations'; +import { ExceptionItemComments } from '../item_comments'; import { defaultEndpointExceptionItems, retrieveAlertOsTypes, @@ -44,14 +46,13 @@ import { initialState, createExceptionItemsReducer } from './reducer'; import { ExceptionsFlyoutMeta } from '../flyout_components/item_meta_form'; import { ExceptionsConditions } from '../flyout_components/item_conditions'; import { useFetchIndexPatterns } from '../../logic/use_exception_flyout_data'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; import { ExceptionItemsFlyoutAlertsActions } from '../flyout_components/alerts_actions'; import { ExceptionsAddToRulesOrLists } from '../flyout_components/add_exception_to_rule_or_list'; import { useAddNewExceptionItems } from './use_add_new_exceptions'; import { entrichNewExceptionItems } from '../flyout_components/utils'; import { useCloseAlertsFromExceptions } from '../../logic/use_close_alerts'; import { ruleTypesThatAllowLargeValueLists } from '../../utils/constants'; -import { ExceptionItemComments } from '../item_comments'; const SectionHeader = styled(EuiTitle)` ${() => css` diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/reducer.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/reducer.ts index 3e5f8afd19626..c36c842930b0f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/reducer.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/reducer.ts @@ -12,7 +12,7 @@ import type { ExceptionsBuilderReturnExceptionItem, } from '@kbn/securitysolution-list-utils'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; export interface State { exceptionItemMeta: { name: string }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/use_add_new_exceptions.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/use_add_new_exceptions.ts index 909d8e8580472..7aa686ed43cdf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/use_add_new_exceptions.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/add_exception_flyout/use_add_new_exceptions.ts @@ -22,7 +22,7 @@ import type { ExceptionsBuilderReturnExceptionItem } from '@kbn/securitysolution import * as i18n from './translations'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; import { useCreateOrUpdateException } from '../../logic/use_create_update_exception'; import { useAddRuleDefaultException } from '../../logic/use_add_rule_exception'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.test.tsx index 6f42a4627135a..dc6a0ea238310 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.test.tsx @@ -13,8 +13,8 @@ import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { ExceptionsViewer } from '.'; import { useKibana } from '../../../../common/lib/kibana'; import { TestProviders } from '../../../../common/mock'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; -import { mockRule } from '../../../../detections/pages/detection_engine/rules/all/__mocks__/mock'; +import type { Rule } from '../../../rule_management/logic/types'; +import { mockRule } from '../../../rule_management_ui/components/rules_table/__mocks__/mock'; import { useFindExceptionListReferences } from '../../logic/use_find_references'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx index 6de23a76981b8..f0c71819d4bce 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/all_exception_items_table/index.tsx @@ -38,7 +38,7 @@ import { EditExceptionFlyout } from '../edit_exception_flyout'; import { AddExceptionFlyout } from '../add_exception_flyout'; import * as i18n from './translations'; import { useFindExceptionListReferences } from '../../logic/use_find_references'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; const StyledText = styled(EuiText)` font-style: italic; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.test.tsx index c313d8cc2aeeb..09ed03130ef08 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.test.tsx @@ -19,13 +19,14 @@ import { useFetchIndex } from '../../../../common/containers/source'; import { createStubIndexPattern, stubIndexPattern } from '@kbn/data-plugin/common/stubs'; import { useSignalIndex } from '../../../../detections/containers/detection_engine/alerts/use_signal_index'; import { getExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_item_schema.mock'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; import type { EntriesArray } from '@kbn/securitysolution-io-ts-list-types'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { getRulesEqlSchemaMock, getRulesSchemaMock, -} from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; +} from '../../../../../common/detection_engine/rule_schema/mocks'; + import { getMockTheme } from '../../../../common/lib/kibana/kibana_react.mock'; import { getExceptionBuilderComponentLazy } from '@kbn/lists-plugin/public'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; @@ -44,14 +45,13 @@ const mockTheme = getMockTheme({ }); jest.mock('../../../../common/lib/kibana'); -jest.mock('../../../../detections/containers/detection_engine/rules'); jest.mock('../../logic/use_create_update_exception'); jest.mock('../../logic/use_exception_flyout_data'); jest.mock('../../../../common/containers/source'); jest.mock('../../logic/use_find_references'); jest.mock('../../logic/use_fetch_or_create_rule_exception_list'); jest.mock('../../../../detections/containers/detection_engine/alerts/use_signal_index'); -jest.mock('../../../../detections/containers/detection_engine/rules/use_rule_async'); +jest.mock('../../../rule_management/logic/use_rule'); jest.mock('@kbn/lists-plugin/public'); const mockGetExceptionBuilderComponentLazy = getExceptionBuilderComponentLazy as jest.Mock< diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx index d6dbc402a92e6..6b85b4bf7302f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/edit_exception_flyout/index.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import { isEmpty } from 'lodash/fp'; import React, { useCallback, useEffect, useMemo, useReducer } from 'react'; import styled, { css } from 'styled-components'; import { @@ -30,28 +31,31 @@ import { exceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; -import { isEmpty } from 'lodash/fp'; import type { ExceptionsBuilderReturnExceptionItem } from '@kbn/securitysolution-list-utils'; -import * as i18n from './translations'; -import { ExceptionsFlyoutMeta } from '../flyout_components/item_meta_form'; -import { createExceptionItemsReducer } from './reducer'; -import { ExceptionsLinkedToLists } from '../flyout_components/linked_to_list'; -import { ExceptionsLinkedToRule } from '../flyout_components/linked_to_rule'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; -import { ExceptionItemsFlyoutAlertsActions } from '../flyout_components/alerts_actions'; -import { ExceptionsConditions } from '../flyout_components/item_conditions'; + import { isEqlRule, isNewTermsRule, isThresholdRule, } from '../../../../../common/detection_engine/utils'; -import { useFetchIndexPatterns } from '../../logic/use_exception_flyout_data'; + +import type { Rule } from '../../../rule_management/logic/types'; +import { ExceptionsFlyoutMeta } from '../flyout_components/item_meta_form'; +import { ExceptionsLinkedToLists } from '../flyout_components/linked_to_list'; +import { ExceptionsLinkedToRule } from '../flyout_components/linked_to_rule'; +import { ExceptionItemsFlyoutAlertsActions } from '../flyout_components/alerts_actions'; +import { ExceptionsConditions } from '../flyout_components/item_conditions'; + import { filterIndexPatterns } from '../../utils/helpers'; -import { entrichExceptionItemsForUpdate } from '../flyout_components/utils'; -import { useEditExceptionItems } from './use_edit_exception'; +import { useFetchIndexPatterns } from '../../logic/use_exception_flyout_data'; import { useCloseAlertsFromExceptions } from '../../logic/use_close_alerts'; import { useFindExceptionListReferences } from '../../logic/use_find_references'; +import { entrichExceptionItemsForUpdate } from '../flyout_components/utils'; import { ExceptionItemComments } from '../item_comments'; +import { createExceptionItemsReducer } from './reducer'; +import { useEditExceptionItems } from './use_edit_exception'; + +import * as i18n from './translations'; interface EditExceptionFlyoutProps { list: ExceptionListSchema; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.test.tsx index d67e62dcb52dc..782066527d13a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.test.tsx @@ -10,21 +10,19 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { coreMock } from '@kbn/core/public/mocks'; import { getListMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; -import { useDissasociateExceptionList } from '../../../../detections/containers/detection_engine/rules/use_dissasociate_exception_list'; +import { useDisassociateExceptionList } from '../../../rule_management/logic/use_disassociate_exception_list'; import { ErrorCallout } from '.'; -import { savedRuleMock } from '../../../../detections/containers/detection_engine/rules/mock'; +import { savedRuleMock } from '../../../rule_management/logic/mock'; -jest.mock( - '../../../../detections/containers/detection_engine/rules/use_dissasociate_exception_list' -); +jest.mock('../../../rule_management/logic/use_disassociate_exception_list'); const mockKibanaHttpService = coreMock.createStart().http; describe('ErrorCallout', () => { - const mockDissasociate = jest.fn(); + const mockDisassociate = jest.fn(); beforeEach(() => { - (useDissasociateExceptionList as jest.Mock).mockReturnValue([false, mockDissasociate]); + (useDisassociateExceptionList as jest.Mock).mockReturnValue([false, mockDisassociate]); }); it('it renders error details', () => { @@ -104,7 +102,7 @@ describe('ErrorCallout', () => { expect(wrapper.find('[data-test-subj="errorCalloutMessage"]').at(0).text()).toEqual( 'Error fetching exception list' ); - expect(wrapper.find('[data-test-subj="errorCalloutDissasociateButton"]').exists()).toBeFalsy(); + expect(wrapper.find('[data-test-subj="errorCalloutDisassociateButton"]').exists()).toBeFalsy(); }); it('it renders specific missing exceptions list error', () => { @@ -133,10 +131,10 @@ describe('ErrorCallout', () => { expect(wrapper.find('[data-test-subj="errorCalloutMessage"]').at(0).text()).toEqual( 'The associated exception list (some_uuid) no longer exists. Please remove the missing exception list to add additional exceptions to the detection rule.' ); - expect(wrapper.find('[data-test-subj="errorCalloutDissasociateButton"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="errorCalloutDisassociateButton"]').exists()).toBeTruthy(); }); - it('it dissasociates list from rule when remove exception list clicked ', () => { + it('it disassociates list from rule when remove exception list clicked ', () => { const wrapper = mountWithIntl( { /> ); - wrapper.find('[data-test-subj="errorCalloutDissasociateButton"]').at(0).simulate('click'); + wrapper.find('[data-test-subj="errorCalloutDisassociateButton"]').at(0).simulate('click'); - expect(mockDissasociate).toHaveBeenCalledWith([]); + expect(mockDisassociate).toHaveBeenCalledWith([]); }); }); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.tsx index 84583ad5f3139..104481b6e111a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/error_callout/index.tsx @@ -18,9 +18,9 @@ import { import type { List } from '@kbn/securitysolution-io-ts-list-types'; import type { HttpSetup } from '@kbn/core/public'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../rule_management/logic/types'; import * as i18n from '../../utils/translations'; -import { useDissasociateExceptionList } from '../../../../detections/containers/detection_engine/rules/use_dissasociate_exception_list'; +import { useDisassociateExceptionList } from '../../../rule_management/logic/use_disassociate_exception_list'; export interface ErrorInfo { reason: string | null; @@ -54,7 +54,7 @@ const ErrorCalloutComponent = ({ onSuccess(listToDelete != null ? listToDelete.id : ''); }, [onSuccess, listToDelete]); - const [isDissasociatingList, handleDissasociateExceptionList] = useDissasociateExceptionList({ + const [isDisassociatingList, handleDisassociateExceptionList] = useDisassociateExceptionList({ http, ruleRuleId: rule != null ? rule.rule_id : '', onSuccess: handleOnSuccess, @@ -66,8 +66,8 @@ const ErrorCalloutComponent = ({ errorInfo.code === 404 && rule != null && listToDelete != null && - handleDissasociateExceptionList != null, - [errorInfo.code, listToDelete, handleDissasociateExceptionList, rule] + handleDisassociateExceptionList != null, + [errorInfo.code, listToDelete, handleDisassociateExceptionList, rule] ); useEffect((): void => { @@ -80,23 +80,23 @@ const ErrorCalloutComponent = ({ setErrorTitle(`${errorInfo.reason}${errorInfo.code != null ? ` (${errorInfo.code})` : ''}`); }, [errorInfo.reason, errorInfo.code, listToDelete, canDisplay404Actions]); - const handleDissasociateList = useCallback((): void => { + const handleDisassociateList = useCallback((): void => { // Yes, it's redundant, unfortunately typescript wasn't picking up - // that `handleDissasociateExceptionList` and `list` are checked in + // that `handleDisassociateExceptionList` and `list` are checked in // canDisplay404Actions if ( canDisplay404Actions && rule != null && listToDelete != null && - handleDissasociateExceptionList != null + handleDisassociateExceptionList != null ) { const exceptionLists = (rule.exceptions_list ?? []).filter( ({ id }) => id !== listToDelete.id ); - handleDissasociateExceptionList(exceptionLists); + handleDisassociateExceptionList(exceptionLists); } - }, [handleDissasociateExceptionList, listToDelete, canDisplay404Actions, rule]); + }, [handleDisassociateExceptionList, listToDelete, canDisplay404Actions, rule]); useEffect((): void => { if (errorInfo.code === 404 && rule != null && rule.exceptions_list != null) { @@ -144,16 +144,16 @@ const ErrorCalloutComponent = ({ {i18n.CANCEL} {canDisplay404Actions && ( {i18n.CLEAR_EXCEPTIONS_LABEL} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/index.tsx index 233e11b0709eb..b841bac12f9d9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/index.tsx @@ -16,7 +16,7 @@ import * as i18n from './translations'; import { ExceptionItemCardHeader } from './header'; import { ExceptionItemCardConditions } from './conditions'; import { ExceptionItemCardMetaInfo } from './meta'; -import type { ExceptionListRuleReferencesSchema } from '../../../../../common/detection_engine/schemas/response'; +import type { ExceptionListRuleReferencesSchema } from '../../../../../common/detection_engine/rule_exceptions'; import { ExceptionItemCardComments } from './comments'; export interface ExceptionItemProps { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/meta.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/meta.tsx index 8005264636bfa..c025a2dc2a2cb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/meta.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/exception_item_card/meta.tsx @@ -25,9 +25,9 @@ import styled from 'styled-components'; import * as i18n from './translations'; import { FormattedDate } from '../../../../common/components/formatted_date'; import { SecurityPageName } from '../../../../../common/constants'; -import type { ExceptionListRuleReferencesSchema } from '../../../../../common/detection_engine/schemas/response'; +import type { ExceptionListRuleReferencesSchema } from '../../../../../common/detection_engine/rule_exceptions'; import { SecuritySolutionLinkAnchor } from '../../../../common/components/links'; -import { RuleDetailTabs } from '../../../../detections/pages/detection_engine/rules/details'; +import { RuleDetailTabs } from '../../../rule_details_ui/pages/rule_details'; import { getRuleDetailsTabUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; const StyledFlexItem = styled(EuiFlexItem)` diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.test.tsx index d9038b0c3fd04..6f81b8177b5f6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.test.tsx @@ -8,8 +8,8 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { getRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import { getRulesSchemaMock } from '../../../../../../common/detection_engine/rule_schema/mocks'; +import type { Rule } from '../../../../rule_management/logic/types'; import { ExceptionsAddToRulesOrLists } from '.'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.tsx index aa705891ecfe7..67e66cc8faa13 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_exception_to_rule_or_list/index.tsx @@ -12,7 +12,7 @@ import type { ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import * as i18n from './translations'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../../rule_management/logic/types'; import { ExceptionsAddToRulesOptions } from '../add_to_rules_options'; import { ExceptionsAddToListsOptions } from '../add_to_lists_options'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_options/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_options/index.test.tsx index 4b55522a638e2..b8911e47d1eb6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_options/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_options/index.test.tsx @@ -11,7 +11,7 @@ import { shallow } from 'enzyme'; import { ExceptionsAddToListsOptions } from '.'; -jest.mock('../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'); +jest.mock('../../../../rule_management/logic/use_find_rules'); describe('ExceptionsAddToListsOptions', () => { it('it displays radio option as disabled if there are no "sharedLists"', () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/index.tsx index f8dc8e41a6df4..d99480ae565cb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_lists_table/index.tsx @@ -11,11 +11,11 @@ import { EuiText, EuiSpacer, EuiInMemoryTable, EuiPanel, EuiLoadingContent } fro import type { ExceptionListSchema, ListArray } from '@kbn/securitysolution-io-ts-list-types'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; -import type { FindRulesReferencedByExceptionsListProp } from '../../../../../detections/containers/detection_engine/rules'; +import type { FindRulesReferencedByExceptionsListProp } from '../../../../rule_management/logic'; import * as i18n from './translations'; import { getSharedListsTableColumns } from '../utils'; import { useFindExceptionListReferences } from '../../../logic/use_find_references'; -import type { ExceptionListRuleReferencesSchema } from '../../../../../../common/detection_engine/schemas/response'; +import type { ExceptionListRuleReferencesSchema } from '../../../../../../common/detection_engine/rule_exceptions'; interface ExceptionsAddToListsComponentProps { /** diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.test.tsx index 8084231a53676..fe65b3ce0384e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.test.tsx @@ -10,15 +10,17 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { ExceptionsAddToRulesOptions } from '.'; import { TestProviders } from '../../../../../common/mock'; -import { useFindRules } from '../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'; -import { getRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import { useFindRulesInMemory } from '../../../../rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory'; +import { getRulesSchemaMock } from '../../../../../../common/detection_engine/rule_schema/mocks'; +import type { Rule } from '../../../../rule_management/logic/types'; -jest.mock('../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'); +jest.mock( + '../../../../rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory' +); describe('ExceptionsAddToRulesOptions', () => { beforeEach(() => { - (useFindRules as jest.Mock).mockReturnValue({ + (useFindRulesInMemory as jest.Mock).mockReturnValue({ data: { rules: [getRulesSchemaMock(), { ...getRulesSchemaMock(), id: '345', name: 'My rule' }], total: 0, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.tsx index 424f8221b5a48..67ef993479713 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_options/index.tsx @@ -9,7 +9,7 @@ import React, { useMemo } from 'react'; import { EuiRadio, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../../rule_management/logic/types'; import { ExceptionsAddToRulesTable } from '../add_to_rules_table'; export type AddToRuleListsRadioOptions = 'select_rules_to_add_to' | 'add_to_rules' | 'add_to_rule'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.test.tsx index d0d5a265a2c4f..48a710cc66ad8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.test.tsx @@ -10,15 +10,17 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { ExceptionsAddToRulesTable } from '.'; import { TestProviders } from '../../../../../common/mock'; -import { useFindRules } from '../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'; -import { getRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import { useFindRulesInMemory } from '../../../../rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory'; +import { getRulesSchemaMock } from '../../../../../../common/detection_engine/rule_schema/mocks'; +import type { Rule } from '../../../../rule_management/logic/types'; -jest.mock('../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'); +jest.mock( + '../../../../rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory' +); describe('ExceptionsAddToRulesTable', () => { it('it displays loading state while fetching rules', () => { - (useFindRules as jest.Mock).mockReturnValue({ + (useFindRulesInMemory as jest.Mock).mockReturnValue({ data: { rules: [], total: 0 }, isFetched: false, }); @@ -34,7 +36,7 @@ describe('ExceptionsAddToRulesTable', () => { }); it('it displays fetched rules', () => { - (useFindRules as jest.Mock).mockReturnValue({ + (useFindRulesInMemory as jest.Mock).mockReturnValue({ data: { rules: [getRulesSchemaMock(), { ...getRulesSchemaMock(), id: '345', name: 'My rule' }], total: 0, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.tsx index 6b56b0eceb2f3..b4112228c923f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/add_to_rules_table/index.tsx @@ -11,8 +11,8 @@ import { EuiSpacer, EuiPanel, EuiText, EuiInMemoryTable, EuiLoadingContent } fro import { i18n } from '@kbn/i18n'; import * as myI18n from './translations'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; -import { useFindRules } from '../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'; +import type { Rule } from '../../../../rule_management/logic/types'; +import { useFindRulesInMemory } from '../../../../rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory'; import { getRulesTableColumn } from '../utils'; interface ExceptionsAddToRulesComponentProps { @@ -24,7 +24,7 @@ const ExceptionsAddToRulesTableComponent: React.FC { - const { data: { rules } = { rules: [], total: 0 }, isFetched } = useFindRules({ + const { data: { rules } = { rules: [], total: 0 }, isFetched } = useFindRulesInMemory({ isInMemorySorting: true, filterOptions: { filter: '', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.test.tsx index a5d6de83b0655..81f8925565f36 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.test.tsx @@ -10,8 +10,8 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { ExceptionsConditions } from '.'; import { TestProviders, mockIndexPattern } from '../../../../../common/mock'; -import { getRulesEqlSchemaMock } from '../../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import { getRulesEqlSchemaMock } from '../../../../../../common/detection_engine/rule_schema/mocks'; +import type { Rule } from '../../../../rule_management/logic/types'; import { getExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_item_schema.mock'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx index 4869c80c172a2..c1f11b17cbbd9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/item_conditions/index.tsx @@ -27,7 +27,7 @@ import type { DataViewBase } from '@kbn/es-query'; import styled, { css } from 'styled-components'; import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; import { hasEqlSequenceQuery, isEqlRule } from '../../../../../../common/detection_engine/utils'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../../rule_management/logic/types'; import { useKibana } from '../../../../../common/lib/kibana'; import * as i18n from './translations'; import * as sharedI18n from '../../../utils/translations'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_list/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_list/index.tsx index 55a748ae7dffd..f09b15bda16a1 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_list/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_list/index.tsx @@ -10,7 +10,7 @@ import { EuiTitle, EuiSpacer, EuiPanel, EuiInMemoryTable, EuiLoadingContent } fr import styled, { css } from 'styled-components'; import * as i18n from './translations'; -import type { ExceptionListRuleReferencesSchema } from '../../../../../../common/detection_engine/schemas/response'; +import type { ExceptionListRuleReferencesSchema } from '../../../../../../common/detection_engine/rule_exceptions'; import { getSharedListsTableColumns } from '../utils'; interface ExceptionsLinkedToListComponentProps { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.test.tsx index 56cf481282d34..42e59832f8abb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.test.tsx @@ -10,10 +10,10 @@ import { mountWithIntl } from '@kbn/test-jest-helpers'; import { ExceptionsLinkedToRule } from '.'; import { TestProviders } from '../../../../../common/mock'; -import { getRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import { getRulesSchemaMock } from '../../../../../../common/detection_engine/rule_schema/mocks'; +import type { Rule } from '../../../../rule_management/logic/types'; -jest.mock('../../../../../detections/pages/detection_engine/rules/all/rules_table/use_find_rules'); +jest.mock('../../../../rule_management/logic/use_find_rules'); describe('ExceptionsLinkedToRule', () => { it('it displays rule name and link', () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.tsx index 289660317025c..64a378e8fb33a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/linked_to_rule/index.tsx @@ -10,7 +10,7 @@ import { EuiTitle, EuiSpacer, EuiInMemoryTable } from '@elastic/eui'; import styled, { css } from 'styled-components'; import * as i18n from './translations'; -import type { Rule } from '../../../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../../../rule_management/logic/types'; import { getRulesTableColumn } from '../utils'; interface ExceptionsLinkedToRuleComponentProps { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/utils.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/utils.tsx index 77e881fdad6f0..a8674883253c0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/utils.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/components/flyout_components/utils.tsx @@ -22,14 +22,14 @@ import { } from '../../utils/helpers'; import { SecuritySolutionLinkAnchor } from '../../../../common/components/links'; import { getRuleDetailsTabUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; -import { RuleDetailTabs } from '../../../../detections/pages/detection_engine/rules/details'; +import { RuleDetailTabs } from '../../../rule_details_ui/pages/rule_details'; import { SecurityPageName } from '../../../../../common/constants'; import { PopoverItems } from '../../../../common/components/popover_items'; import type { ExceptionListRuleReferencesInfoSchema, ExceptionListRuleReferencesSchema, -} from '../../../../../common/detection_engine/schemas/response'; -import type { Rule } from '../../../../detections/containers/detection_engine/rules/types'; +} from '../../../../../common/detection_engine/rule_exceptions'; +import type { Rule } from '../../../rule_management/logic/types'; import * as i18n from './translations'; /** diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_add_rule_exception.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_add_rule_exception.tsx index 7cf4ff2d8417d..c25ffda8ece14 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_add_rule_exception.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_add_rule_exception.tsx @@ -11,8 +11,8 @@ import type { } from '@kbn/securitysolution-io-ts-list-types'; import { useEffect, useRef, useState } from 'react'; -import { addRuleExceptions } from '../../../detections/containers/detection_engine/rules/api'; -import type { Rule } from '../../../detections/containers/detection_engine/rules/types'; +import { addRuleExceptions } from '../../rule_management/api/api'; +import type { Rule } from '../../rule_management/logic/types'; /** * Adds exception items to rules default exception list diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx index 5dc960cb96e2c..a6dce444527d0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_close_alerts.tsx @@ -16,7 +16,7 @@ import { buildAlertsFilter, } from '../../../detections/components/alerts_table/default_config'; import { getEsQueryFilter } from '../../../detections/containers/detection_engine/exceptions/get_es_query_filter'; -import type { Index } from '../../../../common/detection_engine/schemas/common/schemas'; +import type { IndexPatternArray } from '../../../../common/detection_engine/rule_schema'; import { prepareExceptionItemsForBulkClose } from '../utils/helpers'; import * as i18nCommon from '../../../common/translations'; import * as i18n from './translations'; @@ -35,7 +35,7 @@ export type AddOrUpdateExceptionItemsFunc = ( ruleStaticIds: string[], exceptionItems: ExceptionListItemSchema[], alertIdToClose?: string, - bulkCloseIndex?: Index + bulkCloseIndex?: IndexPatternArray ) => Promise; export type ReturnUseCloseAlertsFromExceptions = [boolean, AddOrUpdateExceptionItemsFunc | null]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_exception_flyout_data.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_exception_flyout_data.tsx index 57cfda994d37c..cec9be976592e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_exception_flyout_data.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_exception_flyout_data.tsx @@ -8,7 +8,7 @@ import { useEffect, useState, useMemo } from 'react'; import type { DataViewBase } from '@kbn/es-query'; -import type { Rule } from '../../../detections/containers/detection_engine/rules/types'; +import type { Rule } from '../../rule_management/logic/types'; import { useGetInstalledJob } from '../../../common/components/ml/hooks/use_get_jobs'; import { useKibana } from '../../../common/lib/kibana'; import { useFetchIndex } from '../../../common/containers/source'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.test.tsx index d3bc6214b28ac..c4085910faf25 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.test.tsx @@ -9,10 +9,10 @@ import type { RenderHookResult } from '@testing-library/react-hooks'; import { act, renderHook } from '@testing-library/react-hooks'; import { coreMock } from '@kbn/core/public/mocks'; -import * as rulesApi from '../../../detections/containers/detection_engine/rules/api'; +import * as rulesApi from '../../rule_management/api/api'; import * as listsApi from '@kbn/securitysolution-list-api'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; -import { savedRuleMock } from '../../../detections/containers/detection_engine/rules/mock'; +import { savedRuleMock } from '../../rule_management/logic/mock'; import type { ExceptionListType, ListArray, @@ -26,7 +26,7 @@ import type { import { useFetchOrCreateRuleExceptionList } from './use_fetch_or_create_rule_exception_list'; const mockKibanaHttpService = coreMock.createStart().http; -jest.mock('../../../detections/containers/detection_engine/rules/api'); +jest.mock('../../rule_management/api/api'); jest.mock('@kbn/securitysolution-list-api'); describe('useFetchOrCreateRuleExceptionList', () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.tsx index ff7883ba910cb..a42ecbf586440 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_fetch_or_create_rule_exception_list.tsx @@ -20,11 +20,8 @@ import { import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; import type { HttpStart } from '@kbn/core/public'; -import type { Rule } from '../../../detections/containers/detection_engine/rules/types'; -import { - fetchRuleById, - patchRule, -} from '../../../detections/containers/detection_engine/rules/api'; +import type { Rule } from '../../rule_management/logic/types'; +import { fetchRuleById, patchRule } from '../../rule_management/api/api'; export type ReturnUseFetchOrCreateRuleExceptionList = [boolean, ExceptionListSchema | null]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_find_references.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_find_references.tsx index a051f140ec2cb..b039f32c5e17f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_find_references.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/logic/use_find_references.tsx @@ -7,10 +7,10 @@ import { useEffect, useRef, useState } from 'react'; -import type { ExceptionListRuleReferencesSchema } from '../../../../common/detection_engine/schemas/response'; -import { findRuleExceptionReferences } from '../../../detections/containers/detection_engine/rules/api'; +import type { ExceptionListRuleReferencesSchema } from '../../../../common/detection_engine/rule_exceptions'; +import { findRuleExceptionReferences } from '../../rule_management/api/api'; import { useToasts } from '../../../common/lib/kibana'; -import type { FindRulesReferencedByExceptionsListProp } from '../../../detections/containers/detection_engine/rules/types'; +import type { FindRulesReferencedByExceptionsListProp } from '../../rule_management/logic/types'; import * as i18n from '../utils/translations'; export interface RuleReferences { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/translations.ts index 8f189c7aaf7db..012f4e677a5b2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions/utils/translations.ts @@ -94,14 +94,14 @@ export const MODAL_ERROR_ACCORDION_TEXT = i18n.translate( } ); -export const DISSASOCIATE_LIST_SUCCESS = (id: string) => - i18n.translate('xpack.securitySolution.exceptions.dissasociateListSuccessText', { +export const DISASSOCIATE_LIST_SUCCESS = (id: string) => + i18n.translate('xpack.securitySolution.exceptions.disassociateListSuccessText', { values: { id }, defaultMessage: 'Exception list ({id}) has successfully been removed', }); -export const DISSASOCIATE_EXCEPTION_LIST_ERROR = i18n.translate( - 'xpack.securitySolution.exceptions.dissasociateExceptionListError', +export const DISASSOCIATE_EXCEPTION_LIST_ERROR = i18n.translate( + 'xpack.securitySolution.exceptions.disassociateExceptionListError', { defaultMessage: 'Failed to remove exception list', } diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/columns.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/columns.tsx index 2257d9b79905c..4b196968de008 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/columns.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/columns.tsx @@ -10,12 +10,12 @@ import type { EuiBasicTableColumn } from '@elastic/eui'; import { EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import type { NamespaceType } from '@kbn/securitysolution-io-ts-list-types'; -import { DEFAULT_RELATIVE_DATE_THRESHOLD } from '../../../../../../../common/constants'; -import type { FormatUrl } from '../../../../../../common/components/link_to'; -import { PopoverItems } from '../../../../../../common/components/popover_items'; -import { FormattedRelativePreferenceDate } from '../../../../../../common/components/formatted_date'; -import { getRuleDetailsUrl } from '../../../../../../common/components/link_to/redirect_to_detection_engine'; -import { LinkAnchor } from '../../../../../../common/components/links'; +import { DEFAULT_RELATIVE_DATE_THRESHOLD } from '../../../../../common/constants'; +import type { FormatUrl } from '../../../../common/components/link_to'; +import { PopoverItems } from '../../../../common/components/popover_items'; +import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; +import { getRuleDetailsUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; +import { LinkAnchor } from '../../../../common/components/links'; import * as i18n from './translations'; import type { ExceptionListInfo } from './use_all_exception_lists'; import type { ExceptionsTableItem } from './types'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_search_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_search_bar.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_search_bar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_search_bar.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table.test.tsx similarity index 89% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table.test.tsx index 5c1300ce377a2..c443968c14015 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table.test.tsx @@ -8,18 +8,18 @@ import React from 'react'; import { mount } from 'enzyme'; -import { TestProviders } from '../../../../../../common/mock'; +import { TestProviders } from '../../../../common/mock'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; -import { useUserData } from '../../../../../components/user_info'; +import { useUserData } from '../../../../detections/components/user_info'; import { ExceptionListsTable } from './exceptions_table'; import { useApi, useExceptionLists } from '@kbn/securitysolution-list-hooks'; import { useAllExceptionLists } from './use_all_exception_lists'; import { useHistory } from 'react-router-dom'; -import { generateHistoryMock } from '../../../../../../common/utils/route/mocks'; +import { generateHistoryMock } from '../../../../common/utils/route/mocks'; -jest.mock('../../../../../components/user_info'); -jest.mock('../../../../../../common/lib/kibana'); +jest.mock('../../../../detections/components/user_info'); +jest.mock('../../../../common/lib/kibana'); jest.mock('./use_all_exception_lists'); jest.mock('@kbn/securitysolution-list-hooks'); jest.mock('react-router-dom', () => { @@ -39,7 +39,7 @@ jest.mock('@kbn/i18n-react', () => { }; }); -jest.mock('../../../../../containers/detection_engine/lists/use_lists_config', () => ({ +jest.mock('../../../../detections/containers/detection_engine/lists/use_lists_config', () => ({ useListsConfig: jest.fn().mockReturnValue({ loading: false }), })); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table.tsx index 98e552b1c174a..b2d3d078abb54 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table.tsx @@ -19,28 +19,29 @@ import { import type { NamespaceType, ExceptionListFilter } from '@kbn/securitysolution-io-ts-list-types'; import { useApi, useExceptionLists } from '@kbn/securitysolution-list-hooks'; -import { hasUserCRUDPermission } from '../../../../../../common/utils/privileges'; -import { useAppToasts } from '../../../../../../common/hooks/use_app_toasts'; -import { AutoDownload } from '../../../../../../common/components/auto_download/auto_download'; -import { useKibana } from '../../../../../../common/lib/kibana'; -import { useFormatUrl } from '../../../../../../common/components/link_to'; -import { Loader } from '../../../../../../common/components/loader'; + +import { AutoDownload } from '../../../../common/components/auto_download/auto_download'; +import { useFormatUrl } from '../../../../common/components/link_to'; +import { Loader } from '../../../../common/components/loader'; +import { useKibana } from '../../../../common/lib/kibana'; +import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import * as i18n from './translations'; import { ExceptionsTableUtilityBar } from './exceptions_table_utility_bar'; import type { AllExceptionListsColumns } from './columns'; import { getAllExceptionListsColumns } from './columns'; import { useAllExceptionLists } from './use_all_exception_lists'; -import { ReferenceErrorModal } from '../../../../../components/value_lists_management_flyout/reference_error_modal'; -import { patchRule } from '../../../../../containers/detection_engine/rules/api'; +import { ReferenceErrorModal } from '../../../../detections/components/value_lists_management_flyout/reference_error_modal'; +import { patchRule } from '../../../rule_management/api/api'; import { ExceptionsSearchBar } from './exceptions_search_bar'; -import { getSearchFilters } from '../helpers'; -import { SecurityPageName } from '../../../../../../../common/constants'; -import { useUserData } from '../../../../../components/user_info'; -import { useListsConfig } from '../../../../../containers/detection_engine/lists/use_lists_config'; +import { getSearchFilters } from '../../../rule_management_ui/components/rules_table/helpers'; +import { SecurityPageName } from '../../../../../common/constants'; +import { useUserData } from '../../../../detections/components/user_info'; +import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; import type { ExceptionsTableItem } from './types'; -import { MissingPrivilegesCallOut } from '../../../../../components/callouts/missing_privileges_callout'; -import { ALL_ENDPOINT_ARTIFACT_LIST_IDS } from '../../../../../../../common/endpoint/service/artifacts/constants'; +import { MissingPrivilegesCallOut } from '../../../../detections/components/callouts/missing_privileges_callout'; +import { ALL_ENDPOINT_ARTIFACT_LIST_IDS } from '../../../../../common/endpoint/service/artifacts/constants'; export type Func = () => Promise; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table_utility_bar.test.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table_utility_bar.test.tsx index d2bf2b8547f68..f40e0d66cb492 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table_utility_bar.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { TestProviders } from '../../../../../../common/mock'; +import { TestProviders } from '../../../../common/mock'; import { render, screen, within } from '@testing-library/react'; import { ExceptionsTableUtilityBar } from './exceptions_table_utility_bar'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table_utility_bar.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table_utility_bar.tsx index 062b4b0fef8f9..98ac0bf25d8ec 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table_utility_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table_utility_bar.tsx @@ -13,7 +13,7 @@ import { UtilityBarGroup, UtilityBarSection, UtilityBarText, -} from '../../../../../../common/components/utility_bar'; +} from '../../../../common/components/utility_bar'; import * as i18n from './translations'; interface ExceptionsTableUtilityBarProps { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/translations.ts diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/types.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/types.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/types.ts diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/use_all_exception_lists.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/use_all_exception_lists.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/use_all_exception_lists.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/use_all_exception_lists.tsx index f48de2459fea7..cd77e72722132 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/use_all_exception_lists.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_exceptions_ui/pages/exceptions/use_all_exception_lists.tsx @@ -8,8 +8,8 @@ import { useCallback, useEffect, useState } from 'react'; import type { ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; -import type { Rule } from '../../../../../containers/detection_engine/rules'; -import { fetchRules } from '../../../../../containers/detection_engine/rules/api'; +import type { Rule } from '../../../rule_management/logic'; +import { fetchRules } from '../../../rule_management/api/api'; export interface ExceptionListInfo extends ExceptionListSchema { rules: Rule[]; } diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/__mocks__/api.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/__mocks__/api.ts similarity index 56% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/__mocks__/api.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/api/__mocks__/api.ts index e445e5b935af2..e02e0c83dfe70 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/__mocks__/api.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/__mocks__/api.ts @@ -5,11 +5,9 @@ * 2.0. */ -import type { FullResponseSchema } from '../../../../../../common/detection_engine/schemas/request'; -import type { GetInstalledIntegrationsResponse } from '../../../../../../common/detection_engine/schemas/response'; - -import { getRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import { savedRuleMock, rulesMock } from '../mock'; +import type { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; +import { getRulesSchemaMock } from '../../../../../common/detection_engine/rule_schema/mocks'; +import { savedRuleMock, rulesMock } from '../../logic/mock'; import type { PatchRuleProps, @@ -21,18 +19,18 @@ import type { FetchRuleProps, FetchRulesResponse, FetchRulesProps, -} from '../types'; +} from '../../logic/types'; -export const updateRule = async ({ rule, signal }: UpdateRulesProps): Promise => +export const updateRule = async ({ rule, signal }: UpdateRulesProps): Promise => Promise.resolve(getRulesSchemaMock()); -export const createRule = async ({ rule, signal }: CreateRulesProps): Promise => +export const createRule = async ({ rule, signal }: CreateRulesProps): Promise => Promise.resolve(getRulesSchemaMock()); export const patchRule = async ({ ruleProperties, signal, -}: PatchRuleProps): Promise => Promise.resolve(getRulesSchemaMock()); +}: PatchRuleProps): Promise => Promise.resolve(getRulesSchemaMock()); export const getPrePackagedRulesStatus = async ({ signal, @@ -62,30 +60,4 @@ export const fetchRules = async (_: FetchRulesProps): Promise => Promise.resolve(['elastic', 'love', 'quality', 'code']); -// do not delete -export const fetchInstalledIntegrations = async ({ - packages, - signal, -}: { - packages?: string[]; - signal?: AbortSignal; -}): Promise => { - return Promise.resolve({ - installed_integrations: [ - { - package_name: 'atlassian_bitbucket', - package_title: 'Atlassian Bitbucket', - package_version: '1.0.1', - integration_name: 'audit', - integration_title: 'Audit Logs', - is_enabled: true, - }, - { - package_name: 'system', - package_title: 'System', - package_version: '1.6.4', - is_enabled: true, - }, - ], - }); -}; +export const performBulkAction = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.test.ts similarity index 97% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.test.ts index 2511e8da834f0..ca84045e06c65 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.test.ts @@ -6,7 +6,18 @@ */ import { buildEsQuery } from '@kbn/es-query'; -import { KibanaServices } from '../../../../common/lib/kibana'; +import { KibanaServices } from '../../../common/lib/kibana'; + +import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '../../../../common/detection_engine/rule_exceptions'; +import { getPatchRulesSchemaMock } from '../../../../common/detection_engine/rule_management/mocks'; +import { + getCreateRulesSchemaMock, + getUpdateRulesSchemaMock, + getRulesSchemaMock, +} from '../../../../common/detection_engine/rule_schema/mocks'; + +import { rulesMock } from '../logic/mock'; +import type { FindRulesReferencedByExceptionsListProp } from '../logic/types'; import { createRule, @@ -22,19 +33,10 @@ import { previewRule, findRuleExceptionReferences, } from './api'; -import { getRulesSchemaMock } from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import { - getCreateRulesSchemaMock, - getUpdateRulesSchemaMock, -} from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getPatchRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/patch_rules_schema.mock'; -import { rulesMock } from './mock'; -import type { FindRulesReferencedByExceptionsListProp } from './types'; -import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '../../../../../common/constants'; const abortCtrl = new AbortController(); const mockKibanaServices = KibanaServices.get as jest.Mock; -jest.mock('../../../../common/lib/kibana'); +jest.mock('../../../common/lib/kibana'); const fetchMock = jest.fn(); mockKibanaServices.mockReturnValue({ http: { fetch: fetchMock } }); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts similarity index 69% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts index e2c1e0d31cd57..3fd5fd65bb639 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/api.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts @@ -6,64 +6,65 @@ */ import { camelCase } from 'lodash'; -import type { HttpStart } from '@kbn/core/public'; - import type { CreateRuleExceptionListItemSchema, ExceptionListItemSchema, } from '@kbn/securitysolution-io-ts-list-types'; + +import type { BulkActionsDryRunErrCode } from '../../../../common/constants'; import { - DETECTION_ENGINE_RULES_URL, - DETECTION_ENGINE_PREPACKAGED_URL, - DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL, - DETECTION_ENGINE_TAGS_URL, DETECTION_ENGINE_RULES_BULK_ACTION, DETECTION_ENGINE_RULES_PREVIEW, - DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL, + DETECTION_ENGINE_RULES_URL, DETECTION_ENGINE_RULES_URL_FIND, - DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL, -} from '../../../../../common/constants'; -import type { BulkAction } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; + DETECTION_ENGINE_TAGS_URL, +} from '../../../../common/constants'; + +import { + PREBUILT_RULES_STATUS_URL, + PREBUILT_RULES_URL, +} from '../../../../common/detection_engine/prebuilt_rules'; + +import type { RulesReferencedByExceptionListsSchema } from '../../../../common/detection_engine/rule_exceptions'; +import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '../../../../common/detection_engine/rule_exceptions'; + +import type { BulkActionEditPayload } from '../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkAction } from '../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; + import type { - FullResponseSchema, + RuleResponse, PreviewResponse, -} from '../../../../../common/detection_engine/schemas/request'; -import type { - GetInstalledIntegrationsResponse, - RulesReferencedByExceptionListsSchema, -} from '../../../../../common/detection_engine/schemas/response'; +} from '../../../../common/detection_engine/rule_schema'; +import { KibanaServices } from '../../../common/lib/kibana'; +import * as i18n from '../../../detections/pages/detection_engine/rules/translations'; import type { - UpdateRulesProps, CreateRulesProps, + ExportDocumentsProps, + FetchRuleProps, FetchRulesProps, FetchRulesResponse, - Rule, - FetchRuleProps, + FindRulesReferencedByExceptionsProps, ImportDataProps, - ExportDocumentsProps, ImportDataResponse, - PrePackagedRulesStatusResponse, PatchRuleProps, - BulkActionProps, - BulkActionResponseMap, + PrePackagedRulesStatusResponse, PreviewRulesProps, - FindRulesReferencedByExceptionsProps, -} from './types'; -import { KibanaServices } from '../../../../common/lib/kibana'; -import * as i18n from '../../../pages/detection_engine/rules/translations'; -import { convertRulesFilterToKQL } from './utils'; + Rule, + UpdateRulesProps, +} from '../logic/types'; +import { convertRulesFilterToKQL } from '../logic/utils'; /** * Create provided Rule * - * @param rule CreateRulesSchema to add + * @param rule RuleCreateProps to add * @param signal to cancel request * * @throws An error if response is not OK */ -export const createRule = async ({ rule, signal }: CreateRulesProps): Promise => - KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { +export const createRule = async ({ rule, signal }: CreateRulesProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { method: 'POST', body: JSON.stringify(rule), signal, @@ -72,13 +73,13 @@ export const createRule = async ({ rule, signal }: CreateRulesProps): Promise => - KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { +export const updateRule = async ({ rule, signal }: UpdateRulesProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { method: 'PUT', body: JSON.stringify(rule), signal, @@ -98,8 +99,8 @@ export const updateRule = async ({ rule, signal }: UpdateRulesProps): Promise => - KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { +}: PatchRuleProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { method: 'PATCH', body: JSON.stringify(ruleProperties), signal, @@ -108,7 +109,7 @@ export const patchRule = async ({ /** * Preview provided Rule * - * @param rule CreateRulesSchema to add + * @param rule RuleCreateProps to add * @param signal to cancel request * * @throws An error if response is not OK @@ -177,28 +178,49 @@ export const fetchRules = async ({ * @throws An error if response is not OK */ export const fetchRuleById = async ({ id, signal }: FetchRuleProps): Promise => - pureFetchRuleById({ id, http: KibanaServices.get().http, signal }); - -/** - * Fetch a Rule by providing a Rule ID - * - * @param id Rule ID's (not rule_id) - * @param http Kibana http service - * @param signal to cancel request - * - * @throws An error if response is not OK - */ -export const pureFetchRuleById = async ({ - id, - http, - signal, -}: FetchRuleProps & { http: HttpStart }): Promise => - http.fetch(DETECTION_ENGINE_RULES_URL, { + KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_URL, { method: 'GET', query: { id }, signal, }); +export interface BulkActionSummary { + failed: number; + succeeded: number; + total: number; +} + +export interface BulkActionResult { + updated: Rule[]; + created: Rule[]; + deleted: Rule[]; +} + +export interface BulkActionAggregatedError { + message: string; + status_code: number; + err_code?: BulkActionsDryRunErrCode; + rules: Array<{ id: string; name?: string }>; +} + +export interface BulkActionResponse { + success?: boolean; + rules_count?: number; + attributes: { + summary: BulkActionSummary; + results: BulkActionResult; + errors?: BulkActionAggregatedError[]; + }; +} + +export interface BulkActionProps { + action: Exclude; + query?: string; + ids?: string[]; + edit?: BulkActionEditPayload[]; + isDryRun?: boolean; +} + /** * Perform bulk action with rules selected by a filter query * @@ -210,48 +232,75 @@ export const pureFetchRuleById = async ({ * * @throws An error if response is not OK */ -export const performBulkAction = async ({ +export const performBulkAction = async ({ action, query, edit, ids, isDryRun, -}: BulkActionProps): Promise> => - KibanaServices.get().http.fetch>( - DETECTION_ENGINE_RULES_BULK_ACTION, - { - method: 'POST', - body: JSON.stringify({ - action, - ...(edit ? { edit } : {}), - ...(ids ? { ids } : {}), - ...(query !== undefined ? { query } : {}), - }), - query: { - ...(isDryRun ? { dry_run: isDryRun } : {}), - }, - } - ); +}: BulkActionProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_BULK_ACTION, { + method: 'POST', + body: JSON.stringify({ + action, + ...(edit ? { edit } : {}), + ...(ids ? { ids } : {}), + ...(query !== undefined ? { query } : {}), + }), + query: { + ...(isDryRun ? { dry_run: isDryRun } : {}), + }, + }); + +export interface BulkExportProps { + query?: string; + ids?: string[]; +} + +export type BulkExportResponse = Blob; /** - * Create Prepackaged Rules + * Bulk export rules selected by a filter query * - * @param signal AbortSignal for cancelling request + * @param query filter query to select rules to perform bulk action with + * @param ids string[] rule ids to select rules to perform bulk action with * * @throws An error if response is not OK */ -export const createPrepackagedRules = async (): Promise<{ +export const bulkExportRules = async ({ + query, + ids, +}: BulkExportProps): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_RULES_BULK_ACTION, { + method: 'POST', + body: JSON.stringify({ + action: BulkAction.export, + ...(ids ? { ids } : {}), + ...(query !== undefined ? { query } : {}), + }), + }); + +export interface CreatePrepackagedRulesResponse { rules_installed: number; rules_updated: number; timelines_installed: number; timelines_updated: number; -}> => { +} + +/** + * Create Prepackaged Rules + * + * @param signal AbortSignal for cancelling request + * + * @throws An error if response is not OK + */ +export const createPrepackagedRules = async (): Promise => { const result = await KibanaServices.get().http.fetch<{ rules_installed: number; rules_updated: number; timelines_installed: number; timelines_updated: number; - }>(DETECTION_ENGINE_PREPACKAGED_URL, { + }>(PREBUILT_RULES_URL, { method: 'PUT', }); @@ -320,6 +369,8 @@ export const exportRules = async ({ }); }; +export type FetchTagsResponse = string[]; + /** * Fetch all unique Tags used by Rules * @@ -327,8 +378,8 @@ export const exportRules = async ({ * * @throws An error if response is not OK */ -export const fetchTags = async ({ signal }: { signal: AbortSignal }): Promise => - KibanaServices.get().http.fetch(DETECTION_ENGINE_TAGS_URL, { +export const fetchTags = async ({ signal }: { signal?: AbortSignal }): Promise => + KibanaServices.get().http.fetch(DETECTION_ENGINE_TAGS_URL, { method: 'GET', signal, }); @@ -345,39 +396,10 @@ export const getPrePackagedRulesStatus = async ({ }: { signal: AbortSignal | undefined; }): Promise => - KibanaServices.get().http.fetch( - DETECTION_ENGINE_PREPACKAGED_RULES_STATUS_URL, - { - method: 'GET', - signal, - } - ); - -/** - * Fetch all installed integrations - * - * @param packages array of packages to filter for - * @param signal to cancel request - * - * @throws An error if response is not OK - */ -export const fetchInstalledIntegrations = async ({ - packages, - signal, -}: { - packages?: string[]; - signal?: AbortSignal; -}): Promise => - KibanaServices.get().http.fetch( - DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL, - { - method: 'GET', - query: { - packages: packages?.sort()?.join(','), - }, - signal, - } - ); + KibanaServices.get().http.fetch(PREBUILT_RULES_STATUS_URL, { + method: 'GET', + signal, + }); /** * Fetch info on what exceptions lists are referenced by what rules diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/__mocks__/mock_react_query_response.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/__mocks__/mock_react_query_response.ts new file mode 100644 index 0000000000000..8a5728bac5462 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/__mocks__/mock_react_query_response.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryResult } from '@tanstack/react-query'; + +export const mockReactQueryResponse = (result: Partial>) => ({ + isLoading: false, + error: null, + isError: false, + isLoadingError: false, + isRefetchError: false, + isSuccess: true, + status: 'success', + dataUpdatedAt: 0, + errorUpdatedAt: 0, + failureCount: 0, + errorUpdateCount: 0, + isFetched: true, + isFetchedAfterMount: true, + isFetching: false, + isPaused: false, + isPlaceholderData: false, + isPreviousData: false, + isRefetching: false, + isStale: false, + refetch: jest.fn(), + remove: jest.fn(), + fetchStatus: 'idle', + data: undefined, + ...result, +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/__mocks__/use_prebuilt_rules_status_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/__mocks__/use_prebuilt_rules_status_query.ts new file mode 100644 index 0000000000000..ea8c6b53a35b5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/__mocks__/use_prebuilt_rules_status_query.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PrePackagedRulesStatusResponse } from '../../../logic'; +import { mockReactQueryResponse } from './mock_react_query_response'; + +export const usePrebuiltRulesStatusQuery = jest.fn(() => + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 0, + timelines_installed: 0, + timelines_not_installed: 0, + timelines_not_updated: 0, + }, + }) +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/constants.ts new file mode 100644 index 0000000000000..61e0d1e05f7f0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/constants.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +const ONE_MINUTE = 60000; + +export const DEFAULT_QUERY_OPTIONS = { + refetchIntervalInBackground: false, + staleTime: ONE_MINUTE * 5, +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts new file mode 100644 index 0000000000000..e52a5cd8e0618 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { BulkActionProps, BulkActionResponse } from '../api'; +import { performBulkAction } from '../api'; +import { useInvalidateFetchPrebuiltRulesStatusQuery } from './use_fetch_prebuilt_rules_status_query'; +import { useInvalidateFindRulesQuery, useUpdateRulesCache } from './use_find_rules_query'; +import { useInvalidateFetchTagsQuery } from './use_fetch_tags_query'; +import { useInvalidateFetchRuleByIdQuery } from './use_fetch_rule_by_id_query'; + +export const useBulkActionMutation = ( + options?: UseMutationOptions +) => { + const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); + const invalidateFetchRuleByIdQuery = useInvalidateFetchRuleByIdQuery(); + const invalidateFetchTagsQuery = useInvalidateFetchTagsQuery(); + const invalidateFetchPrebuiltRulesStatusQuery = useInvalidateFetchPrebuiltRulesStatusQuery(); + const updateRulesCache = useUpdateRulesCache(); + + return useMutation( + (action: BulkActionProps) => performBulkAction(action), + { + ...options, + onSuccess: (...args) => { + const [res, { action }] = args; + switch (action) { + case BulkAction.enable: + case BulkAction.disable: { + invalidateFetchRuleByIdQuery(); + // This action doesn't affect rule content, no need for invalidation + updateRulesCache(res?.attributes?.results?.updated ?? []); + break; + } + case BulkAction.delete: + invalidateFindRulesQuery(); + invalidateFetchRuleByIdQuery(); + invalidateFetchTagsQuery(); + invalidateFetchPrebuiltRulesStatusQuery(); + break; + case BulkAction.duplicate: + invalidateFindRulesQuery(); + invalidateFetchPrebuiltRulesStatusQuery(); + break; + case BulkAction.edit: + updateRulesCache(res?.attributes?.results?.updated ?? []); + invalidateFetchRuleByIdQuery(); + invalidateFetchTagsQuery(); + break; + } + + if (options?.onSuccess) { + options.onSuccess(...args); + } + }, + } + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_export_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_export_mutation.ts new file mode 100644 index 0000000000000..bcc5fbcdbb18e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_export_mutation.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { BulkExportProps, BulkExportResponse } from '../api'; +import { bulkExportRules } from '../api'; + +export const useBulkExportMutation = ( + options?: UseMutationOptions +) => { + return useMutation( + (action: BulkExportProps) => bulkExportRules(action), + options + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_prebuilt_rules_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_prebuilt_rules_mutation.ts new file mode 100644 index 0000000000000..2559be0609d08 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_prebuilt_rules_mutation.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { CreatePrepackagedRulesResponse } from '../api'; +import { createPrepackagedRules } from '../api'; +import { useInvalidateFetchPrebuiltRulesStatusQuery } from './use_fetch_prebuilt_rules_status_query'; +import { useInvalidateFindRulesQuery } from './use_find_rules_query'; +import { useInvalidateFetchTagsQuery } from './use_fetch_tags_query'; + +export const useCreatePrebuiltRulesMutation = ( + options?: UseMutationOptions +) => { + const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); + const invalidatePrePackagedRulesStatus = useInvalidateFetchPrebuiltRulesStatusQuery(); + const invalidateFetchTagsQuery = useInvalidateFetchTagsQuery(); + + return useMutation(() => createPrepackagedRules(), { + ...options, + onSuccess: (...args) => { + // Always invalidate all rules and the prepackaged rules status cache as + // the number of rules might change after the installation + invalidatePrePackagedRulesStatus(); + invalidateFindRulesQuery(); + invalidateFetchTagsQuery(); + + if (options?.onSuccess) { + options.onSuccess(...args); + } + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts new file mode 100644 index 0000000000000..8d62927a6261f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { + RuleCreateProps, + RuleResponse, +} from '../../../../../common/detection_engine/rule_schema'; +import { transformOutput } from '../../../../detections/containers/detection_engine/rules/transforms'; +import { createRule } from '../api'; +import { useInvalidateFetchPrebuiltRulesStatusQuery } from './use_fetch_prebuilt_rules_status_query'; +import { useInvalidateFetchTagsQuery } from './use_fetch_tags_query'; +import { useInvalidateFindRulesQuery } from './use_find_rules_query'; + +export const useCreateRuleMutation = ( + options?: UseMutationOptions +) => { + const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); + const invalidateFetchTagsQuery = useInvalidateFetchTagsQuery(); + const invalidateFetchPrePackagedRulesStatusQuery = useInvalidateFetchPrebuiltRulesStatusQuery(); + + return useMutation( + (rule: RuleCreateProps) => createRule({ rule: transformOutput(rule) }), + { + ...options, + onSuccess: (...args) => { + invalidateFetchPrePackagedRulesStatusQuery(); + invalidateFindRulesQuery(); + invalidateFetchTagsQuery(); + + if (options?.onSuccess) { + options.onSuccess(...args); + } + }, + } + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_prebuilt_rules_status_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_prebuilt_rules_status_query.ts new file mode 100644 index 0000000000000..a0344386ffe04 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_prebuilt_rules_status_query.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useCallback } from 'react'; +import type { UseQueryOptions } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { getPrePackagedRulesStatus } from '../api'; +import { DEFAULT_QUERY_OPTIONS } from './constants'; +import type { PrePackagedRulesStatusResponse } from '../../logic'; + +export const PREBUILT_RULES_STATUS_QUERY_KEY = 'prePackagedRulesStatus'; + +export const useFetchPrebuiltRulesStatusQuery = ( + options: UseQueryOptions +) => { + return useQuery( + [PREBUILT_RULES_STATUS_QUERY_KEY], + async ({ signal }) => { + const response = await getPrePackagedRulesStatus({ signal }); + return response; + }, + { + ...DEFAULT_QUERY_OPTIONS, + ...options, + } + ); +}; + +/** + * We should use this hook to invalidate the prepackaged rules cache. For + * example, rule mutations that affect rule set size, like creation or deletion, + * should lead to cache invalidation. + * + * @returns A rules cache invalidation callback + */ +export const useInvalidateFetchPrebuiltRulesStatusQuery = () => { + const queryClient = useQueryClient(); + + return useCallback(() => { + queryClient.invalidateQueries([PREBUILT_RULES_STATUS_QUERY_KEY], { + refetchType: 'active', + }); + }, [queryClient]); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_rule_by_id_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_rule_by_id_query.ts new file mode 100644 index 0000000000000..03fe7c6e2df17 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_rule_by_id_query.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryOptions } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { useCallback } from 'react'; +import { transformInput } from '../../../../detections/containers/detection_engine/rules/transforms'; +import type { Rule } from '../../logic'; +import { fetchRuleById } from '../api'; +import { DEFAULT_QUERY_OPTIONS } from './constants'; + +const FIND_ONE_RULE_QUERY_KEY = 'findOneRule'; + +/** + * A wrapper around useQuery provides default values to the underlying query, + * like query key, abortion signal, and error handler. + * + * @param id - rule's id, not rule_id + * @param options - react-query options + * @returns useQuery result + */ +export const useFetchRuleByIdQuery = (id: string, options: UseQueryOptions) => { + return useQuery( + [FIND_ONE_RULE_QUERY_KEY, id], + async ({ signal }) => { + const response = await fetchRuleById({ signal, id }); + + return transformInput(response); + }, + { + ...DEFAULT_QUERY_OPTIONS, + ...options, + } + ); +}; + +/** + * We should use this hook to invalidate the rules cache. For example, rule + * mutations that affect rule set size, like creation or deletion, should lead + * to cache invalidation. + * + * @returns A rules cache invalidation callback + */ +export const useInvalidateFetchRuleByIdQuery = () => { + const queryClient = useQueryClient(); + + return useCallback(() => { + queryClient.invalidateQueries([FIND_ONE_RULE_QUERY_KEY], { + refetchType: 'active', + }); + }, [queryClient]); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_tags_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_tags_query.ts new file mode 100644 index 0000000000000..1be43f992f07f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_tags_query.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryOptions } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { useCallback } from 'react'; +import type { FetchTagsResponse } from '../api'; +import { fetchTags } from '../api'; +import { DEFAULT_QUERY_OPTIONS } from './constants'; + +// TODO: https://github.com/elastic/kibana/pull/142950 Let's use more detailed cache keys, e.g. ['GET', DETECTION_ENGINE_TAGS_URL] +const TAGS_QUERY_KEY = 'tags'; + +/** + * Hook for using the list of Tags from the Detection Engine API + * + */ +export const useFetchTagsQuery = (options?: UseQueryOptions) => { + return useQuery( + [TAGS_QUERY_KEY], + async ({ signal }) => { + return fetchTags({ signal }); + }, + { + ...DEFAULT_QUERY_OPTIONS, + ...options, + } + ); +}; + +export const useInvalidateFetchTagsQuery = () => { + const queryClient = useQueryClient(); + + return useCallback(() => { + queryClient.invalidateQueries([TAGS_QUERY_KEY], { + refetchType: 'active', + }); + }, [queryClient]); +}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_find_rules_query.ts similarity index 85% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_find_rules_query.ts index 523a05012ca19..ad50ab471a7fd 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_find_rules_query.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_find_rules_query.ts @@ -5,13 +5,12 @@ * 2.0. */ -import { useCallback } from 'react'; import type { UseQueryOptions } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { fetchRules } from './api'; -import * as i18n from './translations'; -import type { FilterOptions, PaginationOptions, Rule, SortingOptions } from './types'; +import { useCallback } from 'react'; +import type { FilterOptions, PaginationOptions, Rule, SortingOptions } from '../../logic'; +import { fetchRules } from '../api'; +import { DEFAULT_QUERY_OPTIONS } from './constants'; export interface FindRulesQueryArgs { filterOptions?: FilterOptions; @@ -21,14 +20,14 @@ export interface FindRulesQueryArgs { const FIND_RULES_QUERY_KEY = 'findRules'; -export interface RulesQueryData { +export interface RulesQueryResponse { rules: Rule[]; total: number; } /** * A wrapper around useQuery provides default values to the underlying query, - * like query key, abortion signal, and error handler. + * like query key, abortion signal. * * @param queryPrefix - query prefix used to differentiate the query from other * findRules queries @@ -37,27 +36,23 @@ export interface RulesQueryData { * @returns useQuery result */ export const useFindRulesQuery = ( - queryPrefix: string[], queryArgs: FindRulesQueryArgs, queryOptions: UseQueryOptions< - RulesQueryData, + RulesQueryResponse, Error, - RulesQueryData, + RulesQueryResponse, [...string[], FindRulesQueryArgs] > ) => { - const { addError } = useAppToasts(); - return useQuery( - [FIND_RULES_QUERY_KEY, ...queryPrefix, queryArgs], + [FIND_RULES_QUERY_KEY, queryArgs], async ({ signal }) => { const response = await fetchRules({ signal, ...queryArgs }); return { rules: response.data, total: response.total }; }, { - refetchIntervalInBackground: false, - onError: (error: Error) => addError(error, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }), + ...DEFAULT_QUERY_OPTIONS, ...queryOptions, } ); @@ -70,7 +65,7 @@ export const useFindRulesQuery = ( * * @returns A rules cache invalidation callback */ -export const useInvalidateRules = () => { +export const useInvalidateFindRulesQuery = () => { const queryClient = useQueryClient(); return useCallback(() => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts new file mode 100644 index 0000000000000..6f15fb4fdd8ce --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { UseMutationOptions } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; +import type { + RuleResponse, + RuleUpdateProps, +} from '../../../../../common/detection_engine/rule_schema'; +import { transformOutput } from '../../../../detections/containers/detection_engine/rules/transforms'; +import { updateRule } from '../api'; +import { useInvalidateFindRulesQuery } from './use_find_rules_query'; +import { useInvalidateFetchTagsQuery } from './use_fetch_tags_query'; +import { useInvalidateFetchRuleByIdQuery } from './use_fetch_rule_by_id_query'; + +export const useUpdateRuleMutation = ( + options?: UseMutationOptions +) => { + const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); + const invalidateFetchTagsQuery = useInvalidateFetchTagsQuery(); + const invalidateFetchRuleByIdQuery = useInvalidateFetchRuleByIdQuery(); + + return useMutation( + (rule: RuleUpdateProps) => updateRule({ rule: transformOutput(rule) }), + { + ...options, + onSuccess: (...args) => { + invalidateFindRulesQuery(); + invalidateFetchRuleByIdQuery(); + invalidateFetchTagsQuery(); + + if (options?.onSuccess) { + options.onSuccess(...args); + } + }, + } + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/__mocks__/use_bulk_export.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/__mocks__/use_bulk_export.ts new file mode 100644 index 0000000000000..c72ba1fab45f9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/__mocks__/use_bulk_export.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const useBulkExport = jest.fn(() => ({ + bulkExport: jest.fn(), +})); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/__mocks__/use_execute_bulk_action.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/__mocks__/use_execute_bulk_action.ts new file mode 100644 index 0000000000000..8e8ad47288027 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/__mocks__/use_execute_bulk_action.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const useExecuteBulkAction = jest.fn(() => ({ + executeBulkAction: jest.fn(), +})); + +export const goToRuleEditPage = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/translations.ts new file mode 100644 index 0000000000000..314811d0b142d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/translations.ts @@ -0,0 +1,106 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ErrorToastOptions } from '@kbn/core-notifications-browser'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import type { BulkActionSummary } from '../../api/api'; + +export function getErrorToastContent( + action: BulkAction, + summary: BulkActionSummary +): ErrorToastOptions { + let title: string; + let toastMessage: string | undefined; + + switch (action) { + case BulkAction.export: + title = i18n.RULES_BULK_EXPORT_FAILURE; + if (summary) { + toastMessage = i18n.RULES_BULK_EXPORT_FAILURE_DESCRIPTION(summary.failed); + } + break; + case BulkAction.duplicate: + title = i18n.RULES_BULK_DUPLICATE_FAILURE; + if (summary) { + toastMessage = i18n.RULES_BULK_DUPLICATE_FAILURE_DESCRIPTION(summary.failed); + } + break; + case BulkAction.delete: + title = i18n.RULES_BULK_DELETE_FAILURE; + if (summary) { + toastMessage = i18n.RULES_BULK_DELETE_FAILURE_DESCRIPTION(summary.failed); + } + break; + case BulkAction.enable: + title = i18n.RULES_BULK_ENABLE_FAILURE; + if (summary) { + toastMessage = i18n.RULES_BULK_ENABLE_FAILURE_DESCRIPTION(summary.failed); + } + break; + case BulkAction.disable: + title = i18n.RULES_BULK_DISABLE_FAILURE; + if (summary) { + toastMessage = i18n.RULES_BULK_DISABLE_FAILURE_DESCRIPTION(summary.failed); + } + break; + case BulkAction.edit: + title = i18n.RULES_BULK_EDIT_FAILURE; + if (summary) { + toastMessage = i18n.RULES_BULK_EDIT_FAILURE_DESCRIPTION(summary.failed); + } + break; + } + + return { title, toastMessage }; +} + +export function getSuccessToastContent(action: BulkAction, summary: BulkActionSummary) { + let title: string; + let text: string | undefined; + + switch (action) { + case BulkAction.export: + title = i18n.RULES_BULK_EXPORT_SUCCESS; + text = getExportSuccessToastMessage(summary.succeeded, summary.total); + break; + case BulkAction.duplicate: + title = i18n.RULES_BULK_DUPLICATE_SUCCESS; + text = i18n.RULES_BULK_DUPLICATE_SUCCESS_DESCRIPTION(summary.succeeded); + break; + case BulkAction.delete: + title = i18n.RULES_BULK_DELETE_SUCCESS; + text = i18n.RULES_BULK_DELETE_SUCCESS_DESCRIPTION(summary.succeeded); + break; + case BulkAction.enable: + title = i18n.RULES_BULK_ENABLE_SUCCESS; + text = i18n.RULES_BULK_ENABLE_SUCCESS_DESCRIPTION(summary.succeeded); + break; + case BulkAction.disable: + title = i18n.RULES_BULK_DISABLE_SUCCESS; + text = i18n.RULES_BULK_DISABLE_SUCCESS_DESCRIPTION(summary.succeeded); + break; + case BulkAction.edit: + title = i18n.RULES_BULK_EDIT_SUCCESS; + text = i18n.RULES_BULK_EDIT_SUCCESS_DESCRIPTION(summary.succeeded); + break; + } + + return { title, text }; +} + +const getExportSuccessToastMessage = (succeeded: number, total: number) => { + const message = [i18n.RULES_BULK_EXPORT_SUCCESS_DESCRIPTION(succeeded, total)]; + + // if not all rules are successfully exported it means there included prebuilt rules + // display message to users that prebuilt rules were excluded + if (total > succeeded) { + message.push(i18n.RULES_BULK_EXPORT_PREBUILT_RULES_EXCLUDED_DESCRIPTION); + } + + return message.join(' '); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/use_bulk_export.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/use_bulk_export.ts new file mode 100644 index 0000000000000..793580e5d3be0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/use_bulk_export.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import type { BulkActionResponse, BulkActionSummary } from '..'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { HTTPError } from '../../../../../common/detection_engine/types'; +import type { UseAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { downloadBlob } from '../../../../common/utils/download_blob'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import { getExportedRulesCounts } from '../../../rule_management_ui/components/rules_table/helpers'; +import type { RulesTableActions } from '../../../rule_management_ui/components/rules_table/rules_table/rules_table_context'; +import { useBulkExportMutation } from '../../api/hooks/use_bulk_export_mutation'; +import { getErrorToastContent, getSuccessToastContent } from './translations'; + +interface RulesBulkActionArgs { + visibleRuleIds?: string[]; + search: { query: string } | { ids: string[] }; + setLoadingRules?: RulesTableActions['setLoadingRules']; +} + +export const useBulkExport = () => { + const toasts = useAppToasts(); + const { mutateAsync } = useBulkExportMutation(); + + const bulkExport = useCallback( + async ({ visibleRuleIds = [], setLoadingRules, search }: RulesBulkActionArgs) => { + try { + setLoadingRules?.({ ids: visibleRuleIds, action: BulkAction.export }); + return await mutateAsync(search); + } catch (error) { + defaultErrorHandler(toasts, error); + } finally { + setLoadingRules?.({ ids: [], action: null }); + } + }, + [mutateAsync, toasts] + ); + + return { bulkExport }; +}; + +/** + * downloads exported rules, received from export action + * @param params.response - Blob results with exported rules + * @param params.toasts - {@link UseAppToasts} toasts service + * @param params.onSuccess - {@link OnActionSuccessCallback} optional toast to display when action successful + * @param params.onError - {@link OnActionErrorCallback} optional toast to display when action failed + */ +export async function downloadExportedRules({ + response, + toasts, +}: { + response: Blob; + toasts: UseAppToasts; +}) { + try { + downloadBlob(response, `${i18n.EXPORT_FILENAME}.ndjson`); + defaultSuccessHandler(toasts, await getExportedRulesCounts(response)); + } catch (error) { + defaultErrorHandler(toasts, error); + } +} + +function defaultErrorHandler(toasts: UseAppToasts, error: HTTPError): void { + const summary = (error?.body as BulkActionResponse)?.attributes?.summary; + error.stack = JSON.stringify(error.body, null, 2); + + toasts.addError(error, getErrorToastContent(BulkAction.export, summary)); +} + +function defaultSuccessHandler(toasts: UseAppToasts, summary: BulkActionSummary): void { + toasts.addSuccess(getSuccessToastContent(BulkAction.export, summary)); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action.ts new file mode 100644 index 0000000000000..3ba9e353f3fcd --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action.ts @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { NavigateToAppOptions } from '@kbn/core/public'; +import { useCallback } from 'react'; +import type { BulkActionResponse, BulkActionSummary } from '..'; +import { APP_UI_ID } from '../../../../../common/constants'; +import type { BulkActionEditPayload } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { HTTPError } from '../../../../../common/detection_engine/types'; +import { SecurityPageName } from '../../../../app/types'; +import { getEditRuleUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; +import type { UseAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { METRIC_TYPE, TELEMETRY_EVENT, track } from '../../../../common/lib/telemetry'; +import type { RulesTableActions } from '../../../rule_management_ui/components/rules_table/rules_table/rules_table_context'; +import { useBulkActionMutation } from '../../api/hooks/use_bulk_action_mutation'; +import { getErrorToastContent, getSuccessToastContent } from './translations'; + +export const goToRuleEditPage = ( + ruleId: string, + navigateToApp: (appId: string, options?: NavigateToAppOptions | undefined) => Promise +) => { + navigateToApp(APP_UI_ID, { + deepLinkId: SecurityPageName.rules, + path: getEditRuleUrl(ruleId ?? ''), + }); +}; + +type OnActionSuccessCallback = ( + toasts: UseAppToasts, + action: BulkAction, + summary: BulkActionSummary +) => void; + +type OnActionErrorCallback = (toasts: UseAppToasts, action: BulkAction, error: HTTPError) => void; + +interface RulesBulkActionArgs { + action: Exclude; + visibleRuleIds?: string[]; + search: { query: string } | { ids: string[] }; + payload?: { edit?: BulkActionEditPayload[] }; + onError?: OnActionErrorCallback; + onFinish?: () => void; + onSuccess?: OnActionSuccessCallback; + setLoadingRules?: RulesTableActions['setLoadingRules']; +} + +export const useExecuteBulkAction = () => { + const toasts = useAppToasts(); + const { mutateAsync } = useBulkActionMutation(); + + const executeBulkAction = useCallback( + async ({ + visibleRuleIds = [], + action, + setLoadingRules, + search, + payload, + onSuccess = defaultSuccessHandler, + onError = defaultErrorHandler, + onFinish, + }: RulesBulkActionArgs) => { + try { + setLoadingRules?.({ ids: visibleRuleIds, action }); + const response = await mutateAsync({ ...search, action, edit: payload?.edit }); + sendTelemetry(action, response); + onSuccess(toasts, action, response.attributes.summary); + + return response; + } catch (error) { + onError(toasts, action, error); + } finally { + setLoadingRules?.({ ids: [], action: null }); + onFinish?.(); + } + }, + [mutateAsync, toasts] + ); + + return { executeBulkAction }; +}; + +function defaultErrorHandler(toasts: UseAppToasts, action: BulkAction, error: HTTPError) { + const summary = (error?.body as BulkActionResponse)?.attributes?.summary; + error.stack = JSON.stringify(error.body, null, 2); + + toasts.addError(error, getErrorToastContent(action, summary)); +} + +async function defaultSuccessHandler( + toasts: UseAppToasts, + action: BulkAction, + summary: BulkActionSummary +) { + toasts.addSuccess(getSuccessToastContent(action, summary)); +} + +function sendTelemetry(action: BulkAction, response: BulkActionResponse) { + if (action === BulkAction.disable || action === BulkAction.enable) { + if (response.attributes.results.updated.some((rule) => rule.immutable)) { + track( + METRIC_TYPE.COUNT, + action === BulkAction.enable + ? TELEMETRY_EVENT.SIEM_RULE_ENABLED + : TELEMETRY_EVENT.SIEM_RULE_DISABLED + ); + } + if (response.attributes.results.updated.some((rule) => !rule.immutable)) { + track( + METRIC_TYPE.COUNT, + action === BulkAction.disable + ? TELEMETRY_EVENT.CUSTOM_RULE_ENABLED + : TELEMETRY_EVENT.CUSTOM_RULE_DISABLED + ); + } + } +} diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/index.ts similarity index 66% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/index.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/index.ts index 42c1eff7435bc..8caaade79ee40 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/index.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/index.ts @@ -5,9 +5,10 @@ * 2.0. */ -export * from './api'; +// TODO: https://github.com/elastic/kibana/pull/142950 delete this whole index file +// TODO: https://github.com/elastic/kibana/pull/142950 delete api re-export +export * from '../api/api'; export * from './use_update_rule'; export * from './use_create_rule'; export * from './types'; export * from './use_rule'; -export * from './use_pre_packaged_rules'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/mock.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/mock.ts similarity index 99% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/mock.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/mock.ts index bdcc8e0ec5e8a..6e1c53cb2da21 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/mock.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/mock.ts @@ -7,6 +7,7 @@ import type { FetchRulesResponse, Rule } from './types'; +// TODO move to __mocks__ export const savedRuleMock: Rule = { author: [], actions: [], diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/translations.ts new file mode 100644 index 0000000000000..36735f1ff11e1 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/translations.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +export const RULE_AND_TIMELINE_FETCH_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.rulesAndTimelines', + { + defaultMessage: 'Failed to fetch Rules and Timelines', + } +); + +export const RULE_ADD_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.addRuleFailDescription', + { + defaultMessage: 'Failed to add Rule', + } +); + +export const RULE_AND_TIMELINE_PREPACKAGED_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineFailDescription', + { + defaultMessage: 'Failed to installed pre-packaged rules and timelines from elastic', + } +); + +export const RULE_AND_TIMELINE_PREPACKAGED_SUCCESS = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineSuccesDescription', + { + defaultMessage: 'Installed pre-packaged rules and timeline templates from elastic', + } +); + +export const RULE_PREPACKAGED_SUCCESS = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleSuccesDescription', + { + defaultMessage: 'Installed pre-packaged rules from elastic', + } +); + +export const TIMELINE_PREPACKAGED_SUCCESS = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.createPrePackagedTimelineSuccesDescription', + { + defaultMessage: 'Installed pre-packaged timeline templates from elastic', + } +); + +export const TAG_FETCH_FAILURE = i18n.translate( + 'xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription', + { + defaultMessage: 'Failed to fetch Tags', + } +); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts similarity index 58% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts index 842353a6799f8..fa2b7f16ce9f7 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts @@ -7,56 +7,74 @@ import * as t from 'io-ts'; -import type { NamespaceType } from '@kbn/securitysolution-io-ts-list-types'; -import { listArray } from '@kbn/securitysolution-io-ts-list-types'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; import { - risk_score_mapping, - threat_query, + RiskScore, + RiskScoreMapping, + RuleActionArray, + RuleActionThrottle, + RuleInterval, + RuleIntervalFrom, + RuleIntervalTo, + Severity, + SeverityMapping, + threat_filters, threat_index, threat_indicator_path, - threat_mapping, threat_language, - threat_filters, - threats, + threat_mapping, + threat_query, type, - severity_mapping, - severity, } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { NamespaceType } from '@kbn/securitysolution-io-ts-list-types'; -import { RuleExecutionSummary } from '../../../../../common/detection_engine/rule_monitoring'; - -import type { SortOrder } from '../../../../../common/detection_engine/schemas/common'; -import type { - BulkActionEditPayload, - BulkAction, -} from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { RuleExecutionSummary } from '../../../../common/detection_engine/rule_monitoring'; import { - alias_purpose as savedObjectResolveAliasPurpose, - outcome as savedObjectResolveOutcome, - author, - building_block_type, - license, - rule_name_override, - data_view_id, - timestamp_override, - timestamp_override_fallback_disabled, - timestamp_field, - event_category_override, - tiebreaker_field, - threshold, + AlertsIndex, + BuildingBlockType, + DataViewId, + EventCategoryOverride, + ExceptionListArray, + IndexPatternArray, + InvestigationGuide, + IsRuleEnabled, + IsRuleImmutable, + MaxSignals, RelatedIntegrationArray, RequiredFieldArray, + RuleAuthorArray, + RuleDescription, + RuleFalsePositiveArray, + RuleFilterArray, + RuleLicense, + RuleName, + RuleNameOverride, + RuleObjectId, + RuleQuery, + RuleReferenceArray, + RuleSignatureId, + RuleTagArray, + RuleVersion, + SavedObjectResolveAliasPurpose, + SavedObjectResolveAliasTargetId, + SavedObjectResolveOutcome, SetupGuide, -} from '../../../../../common/detection_engine/schemas/common'; - + ThreatArray, + Threshold, + TiebreakerField, + TimelineTemplateId, + TimelineTemplateTitle, + TimestampField, + TimestampOverride, + TimestampOverrideFallbackDisabled, +} from '../../../../common/detection_engine/rule_schema'; + +import type { PatchRuleRequestBody } from '../../../../common/detection_engine/rule_management'; import type { - CreateRulesSchema, - PatchRulesSchema, - UpdateRulesSchema, -} from '../../../../../common/detection_engine/schemas/request'; - -import type { BulkActionsDryRunErrCode } from '../../../../../common/constants'; + RuleCreateProps, + RuleUpdateProps, +} from '../../../../common/detection_engine/rule_schema'; +import type { SortOrder } from '../../../../common/detection_engine/schemas/common'; /** * Params is an "record", since it is a type of RuleActionParams which is action templates. @@ -73,23 +91,23 @@ export const action = t.exact( ); export interface CreateRulesProps { - rule: CreateRulesSchema; - signal: AbortSignal; + rule: RuleCreateProps; + signal?: AbortSignal; } export interface PreviewRulesProps { - rule: CreateRulesSchema & { invocationCount: number; timeframeEnd: string }; - signal: AbortSignal; + rule: RuleCreateProps & { invocationCount: number; timeframeEnd: string }; + signal?: AbortSignal; } export interface UpdateRulesProps { - rule: UpdateRulesSchema; - signal: AbortSignal; + rule: RuleUpdateProps; + signal?: AbortSignal; } export interface PatchRuleProps { - ruleProperties: PatchRulesSchema; - signal: AbortSignal; + ruleProperties: PatchRuleRequestBody; + signal?: AbortSignal; } const MetaRule = t.intersection([ @@ -105,73 +123,73 @@ const MetaRule = t.intersection([ // TODO: make a ticket export const RuleSchema = t.intersection([ t.type({ - author, + author: RuleAuthorArray, created_at: t.string, created_by: t.string, - description: t.string, - enabled: t.boolean, - false_positives: t.array(t.string), - from: t.string, - id: t.string, - interval: t.string, - immutable: t.boolean, - name: t.string, - max_signals: t.number, - references: t.array(t.string), + description: RuleDescription, + enabled: IsRuleEnabled, + false_positives: RuleFalsePositiveArray, + from: RuleIntervalFrom, + id: RuleObjectId, + interval: RuleInterval, + immutable: IsRuleImmutable, + name: RuleName, + max_signals: MaxSignals, + references: RuleReferenceArray, related_integrations: RelatedIntegrationArray, required_fields: RequiredFieldArray, - risk_score: t.number, - risk_score_mapping, - rule_id: t.string, - severity, - severity_mapping, + risk_score: RiskScore, + risk_score_mapping: RiskScoreMapping, + rule_id: RuleSignatureId, + severity: Severity, + severity_mapping: SeverityMapping, setup: SetupGuide, - tags: t.array(t.string), + tags: RuleTagArray, type, - to: t.string, - threat: threats, + to: RuleIntervalTo, + threat: ThreatArray, updated_at: t.string, updated_by: t.string, - actions: t.array(action), - throttle: t.union([t.string, t.null]), + actions: RuleActionArray, + throttle: t.union([RuleActionThrottle, t.null]), }), t.partial({ - outcome: savedObjectResolveOutcome, - alias_target_id: t.string, - alias_purpose: savedObjectResolveAliasPurpose, - building_block_type, + outcome: SavedObjectResolveOutcome, + alias_target_id: SavedObjectResolveAliasTargetId, + alias_purpose: SavedObjectResolveAliasPurpose, + building_block_type: BuildingBlockType, anomaly_threshold: t.number, - filters: t.array(t.unknown), - index: t.array(t.string), - data_view_id, + filters: RuleFilterArray, + index: IndexPatternArray, + data_view_id: DataViewId, language: t.string, - license, + license: RuleLicense, meta: MetaRule, machine_learning_job_id: t.array(t.string), new_terms_fields: t.array(t.string), history_window_start: t.string, - output_index: t.string, - query: t.string, - rule_name_override, + output_index: AlertsIndex, + query: RuleQuery, + rule_name_override: RuleNameOverride, saved_id: t.string, - threshold, + threshold: Threshold, threat_query, threat_filters, threat_index, threat_indicator_path, threat_mapping, threat_language, - timeline_id: t.string, - timeline_title: t.string, - timestamp_override, - timestamp_override_fallback_disabled, - timestamp_field, - event_category_override, - tiebreaker_field, - note: t.string, - exceptions_list: listArray, + timeline_id: TimelineTemplateId, + timeline_title: TimelineTemplateTitle, + timestamp_override: TimestampOverride, + timestamp_override_fallback_disabled: TimestampOverrideFallbackDisabled, + event_category_override: EventCategoryOverride, + timestamp_field: TimestampField, + tiebreaker_field: TiebreakerField, + note: InvestigationGuide, + exceptions_list: ExceptionListArray, uuid: t.string, - version: t.number, + version: RuleVersion, execution_summary: RuleExecutionSummary, }), ]); @@ -230,55 +248,9 @@ export interface FetchRulesResponse { export interface FetchRuleProps { id: string; - signal: AbortSignal; -} - -export interface BulkActionProps { - action: Action; - query?: string; - ids?: string[]; - edit?: BulkActionEditPayload[]; - isDryRun?: boolean; -} - -export interface BulkActionSummary { - failed: number; - succeeded: number; - total: number; -} - -export interface BulkActionResult { - updated: Rule[]; - created: Rule[]; - deleted: Rule[]; -} - -export interface BulkActionAggregatedError { - message: string; - status_code: number; - err_code?: BulkActionsDryRunErrCode; - rules: Array<{ id: string; name?: string }>; -} - -export interface BulkActionResponse { - success?: boolean; - rules_count?: number; - attributes: { - summary: BulkActionSummary; - results: BulkActionResult; - errors?: BulkActionAggregatedError[]; - }; + signal?: AbortSignal; } -export type BulkActionResponseMap = { - [BulkAction.delete]: BulkActionResponse; - [BulkAction.disable]: BulkActionResponse; - [BulkAction.enable]: BulkActionResponse; - [BulkAction.duplicate]: BulkActionResponse; - [BulkAction.export]: Blob; - [BulkAction.edit]: BulkActionResponse; -}[Action]; - export interface BasicFetchProps { signal: AbortSignal; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_create_pre_packaged_rules.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_create_pre_packaged_rules.ts new file mode 100644 index 0000000000000..c1de79159918f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_create_pre_packaged_rules.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useCallback } from 'react'; +import { useUserData } from '../../../detections/components/user_info'; +import { useInstallPrePackagedRules } from './use_install_pre_packaged_rules'; + +export const useCreatePrePackagedRules = () => { + const [{ isSignalIndexExists, isAuthenticated, hasEncryptionKey, canUserCRUD, hasIndexWrite }] = + useUserData(); + const { mutateAsync: installPrePackagedRules, isLoading } = useInstallPrePackagedRules(); + + const canCreatePrePackagedRules = + canUserCRUD && hasIndexWrite && isAuthenticated && hasEncryptionKey && isSignalIndexExists; + + const createPrePackagedRules = useCallback(async () => { + if (canCreatePrePackagedRules) { + await installPrePackagedRules(); + } + }, [canCreatePrePackagedRules, installPrePackagedRules]); + + return { + isLoading, + createPrePackagedRules, + canCreatePrePackagedRules, + }; +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_create_rule.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_create_rule.ts new file mode 100644 index 0000000000000..65cb3a8bc0460 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_create_rule.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useCreateRuleMutation } from '../api/hooks/use_create_rule_mutation'; +import * as i18n from './translations'; + +export const useCreateRule = () => { + const { addError } = useAppToasts(); + + return useCreateRuleMutation({ + onError: (error) => { + addError(error, { title: i18n.RULE_ADD_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_dissasociate_exception_list.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_disassociate_exception_list.ts similarity index 78% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_dissasociate_exception_list.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_disassociate_exception_list.ts index ecb9b7c095786..67a30233c59d7 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_dissasociate_exception_list.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_disassociate_exception_list.ts @@ -9,12 +9,12 @@ import { useEffect, useState, useRef } from 'react'; import type { List } from '@kbn/securitysolution-io-ts-list-types'; import type { HttpStart } from '@kbn/core/public'; -import { patchRule } from './api'; +import { patchRule } from '../api/api'; type Func = (lists: List[]) => void; -export type ReturnUseDissasociateExceptionList = [boolean, Func | null]; +export type ReturnUseDisassociateExceptionList = [boolean, Func | null]; -export interface UseDissasociateExceptionListProps { +export interface UseDisassociateExceptionListProps { http: HttpStart; ruleRuleId: string; onError: (arg: Error) => void; @@ -30,20 +30,20 @@ export interface UseDissasociateExceptionListProps { * @param onSuccess success callback * */ -export const useDissasociateExceptionList = ({ +export const useDisassociateExceptionList = ({ http, ruleRuleId, onError, onSuccess, -}: UseDissasociateExceptionListProps): ReturnUseDissasociateExceptionList => { +}: UseDisassociateExceptionListProps): ReturnUseDisassociateExceptionList => { const [isLoading, setLoading] = useState(false); - const dissasociateList = useRef(null); + const disassociateList = useRef(null); useEffect(() => { let isSubscribed = true; const abortCtrl = new AbortController(); - const dissasociateListFromRule = + const disassociateListFromRule = (id: string) => async (exceptionLists: List[]): Promise => { try { @@ -69,7 +69,7 @@ export const useDissasociateExceptionList = ({ } }; - dissasociateList.current = dissasociateListFromRule(ruleRuleId); + disassociateList.current = disassociateListFromRule(ruleRuleId); return (): void => { isSubscribed = false; @@ -77,5 +77,5 @@ export const useDissasociateExceptionList = ({ }; }, [http, ruleRuleId, onError, onSuccess]); - return [isLoading, dissasociateList.current]; + return [isLoading, disassociateList.current]; }; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_dissasociate_exception_list.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_dissasociate_exception_list.test.ts similarity index 67% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_dissasociate_exception_list.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_dissasociate_exception_list.test.ts index 1a40d260b476c..9671dac1039a1 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_dissasociate_exception_list.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_dissasociate_exception_list.test.ts @@ -9,17 +9,17 @@ import { act, renderHook } from '@testing-library/react-hooks'; import { coreMock } from '@kbn/core/public/mocks'; -import * as api from './api'; -import { getRulesSchemaMock } from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; +import * as api from '../api/api'; +import { getRulesSchemaMock } from '../../../../common/detection_engine/rule_schema/mocks'; import type { - ReturnUseDissasociateExceptionList, - UseDissasociateExceptionListProps, -} from './use_dissasociate_exception_list'; -import { useDissasociateExceptionList } from './use_dissasociate_exception_list'; + ReturnUseDisassociateExceptionList, + UseDisassociateExceptionListProps, +} from './use_disassociate_exception_list'; +import { useDisassociateExceptionList } from './use_disassociate_exception_list'; const mockKibanaHttpService = coreMock.createStart().http; -describe('useDissasociateExceptionList', () => { +describe('useDisassociateExceptionList', () => { const onError = jest.fn(); const onSuccess = jest.fn(); @@ -34,10 +34,10 @@ describe('useDissasociateExceptionList', () => { test('initializes hook', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook< - UseDissasociateExceptionListProps, - ReturnUseDissasociateExceptionList + UseDisassociateExceptionListProps, + ReturnUseDisassociateExceptionList >(() => - useDissasociateExceptionList({ + useDisassociateExceptionList({ http: mockKibanaHttpService, ruleRuleId: 'rule_id', onError, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_find_rules.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_find_rules.ts new file mode 100644 index 0000000000000..653f1de8e3b3f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_find_rules.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryOptions } from '@tanstack/react-query'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import type { FindRulesQueryArgs } from '../api/hooks/use_find_rules_query'; +import { useFindRulesQuery } from '../api/hooks/use_find_rules_query'; +import * as i18n from './translations'; +import type { Rule } from './types'; + +export interface RulesQueryData { + rules: Rule[]; + total: number; +} + +/** + * A wrapper around useQuery provides default values to the underlying query, + * like query key, abortion signal, and error handler. + * + * @param requestArgs - fetch rules filters/pagination + * @param options - react-query options + * @returns useQuery result + */ +export const useFindRules = ( + requestArgs: FindRulesQueryArgs, + options: UseQueryOptions +) => { + const { addError } = useAppToasts(); + + return useFindRulesQuery(requestArgs, { + onError: (error: Error) => addError(error, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }), + ...options, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_install_pre_packaged_rules.ts similarity index 63% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_install_pre_packaged_rules.ts index 3f56cac04fb02..21ea298986598 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_install_pre_packaged_rules.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_install_pre_packaged_rules.ts @@ -4,28 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { useMutation } from '@tanstack/react-query'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { createPrepackagedRules } from './api'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useCreatePrebuiltRulesMutation } from '../api/hooks/use_create_prebuilt_rules_mutation'; import * as i18n from './translations'; -import { useInvalidateRules } from './use_find_rules_query'; -import { useInvalidatePrePackagedRulesStatus } from './use_pre_packaged_rules_status'; export const useInstallPrePackagedRules = () => { const { addError, addSuccess } = useAppToasts(); - const invalidateRules = useInvalidateRules(); - const invalidatePrePackagedRulesStatus = useInvalidatePrePackagedRulesStatus(); - return useMutation(() => createPrepackagedRules(), { + return useCreatePrebuiltRulesMutation({ onError: (err) => { addError(err, { title: i18n.RULE_AND_TIMELINE_PREPACKAGED_FAILURE }); }, onSuccess: (result) => { addSuccess(getSuccessToastMessage(result)); - // Always invalidate all rules and the prepackaged rules status cache as - // the number of rules might change after the installation - invalidatePrePackagedRulesStatus(); - invalidateRules(); }, }); }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_rules_installation_status.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_rules_installation_status.ts new file mode 100644 index 0000000000000..d45109ee078ed --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_rules_installation_status.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getPrePackagedRuleInstallationStatus } from '../../../detections/pages/detection_engine/rules/helpers'; +import { usePrePackagedRulesStatus } from './use_pre_packaged_rules_status'; + +export const usePrePackagedRulesInstallationStatus = () => { + const { data: prePackagedRulesStatus } = usePrePackagedRulesStatus(); + + return getPrePackagedRuleInstallationStatus( + prePackagedRulesStatus?.rules_installed, + prePackagedRulesStatus?.rules_not_installed, + prePackagedRulesStatus?.rules_not_updated + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_rules_status.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_rules_status.ts new file mode 100644 index 0000000000000..889b670432d54 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_rules_status.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useFetchPrebuiltRulesStatusQuery } from '../api/hooks/use_fetch_prebuilt_rules_status_query'; +import * as i18n from './translations'; + +export const usePrePackagedRulesStatus = () => { + const { addError } = useAppToasts(); + + return useFetchPrebuiltRulesStatusQuery({ + onError: (err) => { + addError(err, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_timelines_installation_status.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_timelines_installation_status.ts new file mode 100644 index 0000000000000..61933d625ba18 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_pre_packaged_timelines_installation_status.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getPrePackagedTimelineInstallationStatus } from '../../../detections/pages/detection_engine/rules/helpers'; +import { usePrePackagedRulesStatus } from './use_pre_packaged_rules_status'; + +export const usePrePackagedTimelinesInstallationStatus = () => { + const { data: prePackagedRulesStatus } = usePrePackagedRulesStatus(); + + return getPrePackagedTimelineInstallationStatus( + prePackagedRulesStatus?.timelines_installed, + prePackagedRulesStatus?.timelines_not_installed, + prePackagedRulesStatus?.timelines_not_updated + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule.ts new file mode 100644 index 0000000000000..234ba95de54d6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useFetchRuleByIdQuery } from '../api/hooks/use_fetch_rule_by_id_query'; +import * as i18n from './translations'; + +/** + * Hook for using to get a Rule from the Detection Engine API + * + * @param id desired Rule ID's (not rule_id) + * + */ +export const useRule = (id: string) => { + const { addError } = useAppToasts(); + + return useFetchRuleByIdQuery(id, { + onError: (error) => { + addError(error, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_indices.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_indices.test.ts similarity index 92% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_indices.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_indices.test.ts index d22b9a8d83220..b04cda31daf5f 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_indices.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_indices.test.ts @@ -8,9 +8,9 @@ import { renderHook } from '@testing-library/react-hooks'; import { useRuleIndices } from './use_rule_indices'; -import { useGetInstalledJob } from '../../../../common/components/ml/hooks/use_get_jobs'; +import { useGetInstalledJob } from '../../../common/components/ml/hooks/use_get_jobs'; -jest.mock('../../../../common/components/ml/hooks/use_get_jobs'); +jest.mock('../../../common/components/ml/hooks/use_get_jobs'); describe('useRuleIndices', () => { beforeEach(() => { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_indices.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_indices.ts similarity index 90% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_indices.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_indices.ts index 77ffc49bb7413..4dbb28514255a 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_indices.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_indices.ts @@ -6,7 +6,7 @@ */ import { useMemo } from 'react'; -import { useGetInstalledJob } from '../../../../common/components/ml/hooks/use_get_jobs'; +import { useGetInstalledJob } from '../../../common/components/ml/hooks/use_get_jobs'; export const useRuleIndices = (machineLearningJobId?: string[], defaultRuleIndices?: string[]) => { const memoMlJobIds = useMemo(() => machineLearningJobId ?? [], [machineLearningJobId]); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_with_fallback.ts similarity index 79% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_with_fallback.ts index d832dd64cff70..6290c4ae6622f 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_rule_with_fallback.ts @@ -5,20 +5,18 @@ * 2.0. */ -import { useCallback, useEffect, useMemo } from 'react'; import { ALERT_RULE_UUID } from '@kbn/rule-data-utils'; -import { useAsync, withOptionalSignal } from '@kbn/securitysolution-hook-utils'; import { isNotFoundError } from '@kbn/securitysolution-t-grid'; -import { expandDottedObject } from '../../../../../common/utils/expand_dotted'; - -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import type { AlertSearchResponse } from '../alerts/types'; -import { useQueryAlerts } from '../alerts/use_query'; -import { ALERTS_QUERY_NAMES } from '../alerts/constants'; -import { fetchRuleById } from './api'; -import { transformInput } from './transforms'; +import { useEffect, useMemo } from 'react'; +import { expandDottedObject } from '../../../../common/utils/expand_dotted'; +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { ALERTS_QUERY_NAMES } from '../../../detections/containers/detection_engine/alerts/constants'; +import type { AlertSearchResponse } from '../../../detections/containers/detection_engine/alerts/types'; +import { useQueryAlerts } from '../../../detections/containers/detection_engine/alerts/use_query'; +import { transformInput } from '../../../detections/containers/detection_engine/rules/transforms'; import * as i18n from './translations'; import type { Rule } from './types'; +import { useRule } from './use_rule'; interface UseRuleWithFallback { error: unknown; @@ -55,10 +53,6 @@ interface RACRule { }; } -const fetchWithOptionsSignal = withOptionalSignal(fetchRuleById); - -const useFetchRule = () => useAsync(fetchWithOptionsSignal); - const buildLastAlertQuery = (ruleId: string) => ({ query: { bool: { @@ -83,17 +77,9 @@ const buildLastAlertQuery = (ruleId: string) => ({ * In that case, try to fetch the latest alert generated by the rule and retrieve the rule data from the alert (fallback). */ export const useRuleWithFallback = (ruleId: string): UseRuleWithFallback => { - const { start, loading: ruleLoading, result: ruleData, error } = useFetchRule(); + const { isLoading: ruleLoading, data: ruleData, error, refetch } = useRule(ruleId); const { addError } = useAppToasts(); - const fetch = useCallback(() => { - start({ id: ruleId }); - }, [ruleId, start]); - - useEffect(() => { - fetch(); - }, [fetch]); - const isExistingRule = !isNotFoundError(error); const { loading: alertsLoading, data: alertsData } = useQueryAlerts({ @@ -122,7 +108,7 @@ export const useRuleWithFallback = (ruleId: string): UseRuleWithFallback => { return { error, loading: ruleLoading || alertsLoading, - refresh: fetch, + refresh: refetch, rule: rule ?? null, isExistingRule, }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_tags.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_tags.ts new file mode 100644 index 0000000000000..ab3671f262f8a --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_tags.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useFetchTagsQuery } from '../api/hooks/use_fetch_tags_query'; +import * as i18n from './translations'; + +/** + * Hook for using the list of Tags from the Detection Engine API + * + */ +export const useTags = () => { + const { addError } = useAppToasts(); + + return useFetchTagsQuery({ + onError: (err) => { + addError(err, { title: i18n.TAG_FETCH_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_update_rule.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_update_rule.ts new file mode 100644 index 0000000000000..900b3c30ccaa2 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/use_update_rule.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useAppToasts } from '../../../common/hooks/use_app_toasts'; +import { useUpdateRuleMutation } from '../api/hooks/use_update_rule_mutation'; +import * as i18n from './translations'; + +export const useUpdateRule = () => { + const { addError } = useAppToasts(); + + return useUpdateRuleMutation({ + onError: (error) => { + addError(error, { title: i18n.RULE_ADD_FAILURE }); + }, + }); +}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/utils.test.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.test.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/utils.test.ts diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/utils.ts similarity index 97% rename from x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/utils.ts index b4de6a95daaf1..67e64dab36a36 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/utils.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { escapeKuery } from '../../../../common/lib/kuery'; +import { escapeKuery } from '../../../common/lib/kuery'; import type { FilterOptions } from './types'; const SEARCHABLE_RULE_PARAMS = [ diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/__mocks__/mock.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts similarity index 89% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/__mocks__/mock.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts index 967ba8a90d4f4..ac22095820255 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/__mocks__/mock.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/__mocks__/mock.ts @@ -6,12 +6,17 @@ */ import { FilterStateStore } from '@kbn/es-query'; -import type { Rule } from '../../../../../containers/detection_engine/rules'; -import type { AboutStepRule, ActionsStepRule, DefineStepRule, ScheduleStepRule } from '../../types'; -import { DataSourceType } from '../../types'; -import type { FieldValueQueryBar } from '../../../../../components/rules/query_bar'; -import { fillEmptySeverityMappings } from '../../helpers'; -import { getThreatMock } from '../../../../../../../common/detection_engine/schemas/types/threat.mock'; +import type { Rule } from '../../../../rule_management/logic'; +import type { + AboutStepRule, + ActionsStepRule, + DefineStepRule, + ScheduleStepRule, +} from '../../../../../detections/pages/detection_engine/rules/types'; +import { DataSourceType } from '../../../../../detections/pages/detection_engine/rules/types'; +import type { FieldValueQueryBar } from '../../../../../detections/components/rules/query_bar'; +import { fillEmptySeverityMappings } from '../../../../../detections/pages/detection_engine/rules/helpers'; +import { getThreatMock } from '../../../../../../common/detection_engine/schemas/types/threat.mock'; export const mockQueryBar: FieldValueQueryBar = { query: { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_dry_run_confirmation.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_dry_run_confirmation.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_dry_run_confirmation.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_dry_run_confirmation.tsx index 9207e0813ab70..941339be4fa31 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_dry_run_confirmation.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_dry_run_confirmation.tsx @@ -8,10 +8,10 @@ import React from 'react'; import { EuiConfirmModal } from '@elastic/eui'; -import * as i18n from '../../translations'; +import * as i18n from '../../../../../detections/pages/detection_engine/rules/translations'; import { BulkActionRuleErrorsList } from './bulk_action_rule_errors_list'; -import { BulkAction } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; +import { BulkAction } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { assertUnreachable } from '../../../../../../common/utility_types'; import type { BulkActionForConfirmation, DryRunResult } from './types'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_rule_errors_list.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_rule_errors_list.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx index 987b244dd9fc6..758ccf0893e36 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_rule_errors_list.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.test.tsx @@ -11,9 +11,9 @@ import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { render, screen } from '@testing-library/react'; import { BulkActionRuleErrorsList } from './bulk_action_rule_errors_list'; -import { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; +import { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; import type { DryRunResult } from './types'; -import { BulkAction } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkAction } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; const Wrapper: FC = ({ children }) => { return ( diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_rule_errors_list.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.tsx similarity index 96% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_rule_errors_list.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.tsx index 8f0275000a4ef..9789377f13ef3 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_action_rule_errors_list.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_action_rule_errors_list.tsx @@ -9,8 +9,8 @@ import React from 'react'; import { EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; -import { BulkAction } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; +import { BulkAction } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import type { DryRunResult, BulkActionForConfirmation } from './types'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_edit_flyout.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_edit_flyout.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_edit_flyout.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_edit_flyout.tsx index 194d4d90f860a..4f109fab7a8ba 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/bulk_edit_flyout.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/bulk_edit_flyout.tsx @@ -7,8 +7,8 @@ import React from 'react'; -import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import type { BulkActionEditPayload } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { IndexPatternsForm } from './forms/index_patterns_form'; import { TagsForm } from './forms/tags_form'; @@ -21,10 +21,9 @@ interface BulkEditFlyoutProps { onConfirm: (bulkActionEditPayload: BulkActionEditPayload) => void; editAction: BulkActionEditType; rulesCount: number; - tags: string[]; } -const BulkEditFlyoutComponent = ({ editAction, tags, ...props }: BulkEditFlyoutProps) => { +const BulkEditFlyoutComponent = ({ editAction, ...props }: BulkEditFlyoutProps) => { switch (editAction) { case BulkActionEditType.add_index_patterns: case BulkActionEditType.delete_index_patterns: @@ -34,7 +33,7 @@ const BulkEditFlyoutComponent = ({ editAction, tags, ...props }: BulkEditFlyoutP case BulkActionEditType.add_tags: case BulkActionEditType.delete_tags: case BulkActionEditType.set_tags: - return ; + return ; case BulkActionEditType.set_timeline: return ; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/bulk_edit_form_wrapper.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/bulk_edit_form_wrapper.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/bulk_edit_form_wrapper.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/bulk_edit_form_wrapper.tsx index a4fafd8d21bfd..364774465bd2d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/bulk_edit_form_wrapper.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/bulk_edit_form_wrapper.tsx @@ -21,10 +21,10 @@ import { EuiFlyoutBody, } from '@elastic/eui'; -import type { FormHook } from '../../../../../../../shared_imports'; -import { Form } from '../../../../../../../shared_imports'; +import type { FormHook } from '../../../../../../shared_imports'; +import { Form } from '../../../../../../shared_imports'; -import * as i18n from '../../../translations'; +import * as i18n from '../../../../../../detections/pages/detection_engine/rules/translations'; interface BulkEditFormWrapperProps { form: FormHook; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/index_patterns_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/index_patterns_form.tsx similarity index 92% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/index_patterns_form.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/index_patterns_form.tsx index adb19e397027b..2ea8b20dcd42c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/index_patterns_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/index_patterns_form.tsx @@ -9,15 +9,15 @@ import React from 'react'; import { EuiFormRow, EuiCallOut } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import * as i18n from '../../../translations'; +import * as i18n from '../../../../../../detections/pages/detection_engine/rules/translations'; -import { DEFAULT_INDEX_KEY } from '../../../../../../../../common/constants'; -import { useKibana } from '../../../../../../../common/lib/kibana'; +import { DEFAULT_INDEX_KEY } from '../../../../../../../common/constants'; +import { useKibana } from '../../../../../../common/lib/kibana'; -import { BulkActionEditType } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { BulkActionEditPayload } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkActionEditType } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; -import type { FormSchema } from '../../../../../../../shared_imports'; +import type { FormSchema } from '../../../../../../shared_imports'; import { Field, getUseField, @@ -25,7 +25,7 @@ import { useForm, FIELD_TYPES, fieldValidators, -} from '../../../../../../../shared_imports'; +} from '../../../../../../shared_imports'; import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; const CommonUseField = getUseField({ component: Field }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx similarity index 87% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx index ec7d81e8b08a9..0bff754f20f4f 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/rule_actions_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx @@ -13,7 +13,7 @@ import type { ActionTypeRegistryContract, } from '@kbn/triggers-actions-ui-plugin/public'; -import type { FormSchema } from '../../../../../../../shared_imports'; +import type { FormSchema } from '../../../../../../shared_imports'; import { useForm, UseField, @@ -21,27 +21,27 @@ import { useFormData, getUseField, Field, -} from '../../../../../../../shared_imports'; -import { BulkActionEditType } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +} from '../../../../../../shared_imports'; +import { BulkActionEditType } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import type { BulkActionEditPayload, ThrottleForBulkActions, -} from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { NOTIFICATION_THROTTLE_RULE } from '../../../../../../../../common/constants'; +} from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { NOTIFICATION_THROTTLE_RULE } from '../../../../../../../common/constants'; import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; import { bulkAddRuleActions as i18n } from '../translations'; -import { useKibana } from '../../../../../../../common/lib/kibana'; +import { useKibana } from '../../../../../../common/lib/kibana'; import { ThrottleSelectField, THROTTLE_OPTIONS_FOR_BULK_RULE_ACTIONS, -} from '../../../../../../components/rules/throttle_select_field'; -import { getAllActionMessageParams } from '../../../helpers'; +} from '../../../../../../detections/components/rules/throttle_select_field'; +import { getAllActionMessageParams } from '../../../../../../detections/pages/detection_engine/rules/helpers'; -import { RuleActionsField } from '../../../../../../components/rules/rule_actions_field'; -import { validateRuleActionsField } from '../../../../../../containers/detection_engine/rules/validate_rule_actions_field'; +import { RuleActionsField } from '../../../../../../detections/components/rules/rule_actions_field'; +import { validateRuleActionsField } from '../../../../../../detections/containers/detection_engine/rules/validate_rule_actions_field'; const CommonUseField = getUseField({ component: Field }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/schedule_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/schedule_form.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/schedule_form.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/schedule_form.tsx index eb27aee61f93b..68e7a4ddfb2d3 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/schedule_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/schedule_form.tsx @@ -5,16 +5,15 @@ * 2.0. */ -import React, { useCallback } from 'react'; import { EuiCallOut } from '@elastic/eui'; -import type { BulkActionEditPayload } from '../../../../../../../../common/detection_engine/schemas/request'; -import { BulkActionEditType } from '../../../../../../../../common/detection_engine/schemas/request'; -import { useForm, UseField } from '../../../../../../../shared_imports'; -import type { FormSchema } from '../../../../../../../shared_imports'; -import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; -import { ScheduleItem } from '../../../../../../components/rules/schedule_item_form'; - +import React, { useCallback } from 'react'; +import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { ScheduleItem } from '../../../../../../detections/components/rules/schedule_item_form'; +import type { FormSchema } from '../../../../../../shared_imports'; +import { UseField, useForm } from '../../../../../../shared_imports'; import { bulkSetSchedule as i18n } from '../translations'; +import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; export interface ScheduleFormData { interval: string; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/tags_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/tags_form.tsx similarity index 87% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/tags_form.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/tags_form.tsx index e53469e27a09a..4288342c03d10 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/tags_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/tags_form.tsx @@ -5,26 +5,27 @@ * 2.0. */ -import React, { useMemo } from 'react'; -import { EuiFormRow, EuiCallOut } from '@elastic/eui'; +import { EuiCallOut, EuiFormRow } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import React, { useMemo } from 'react'; -import * as i18n from '../../../translations'; +import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import * as i18n from '../../../../../../detections/pages/detection_engine/rules/translations'; import { caseInsensitiveSort } from '../../helpers'; -import type { BulkActionEditPayload } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { FormSchema } from '../../../../../../../shared_imports'; +import type { FormSchema } from '../../../../../../shared_imports'; import { - useForm, Field, + fieldValidators, + FIELD_TYPES, getUseField, + useForm, useFormData, - FIELD_TYPES, - fieldValidators, -} from '../../../../../../../shared_imports'; +} from '../../../../../../shared_imports'; import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; +import { useTags } from '../../../../../rule_management/logic/use_tags'; type TagsEditActions = | BulkActionEditType.add_tags @@ -74,10 +75,10 @@ interface TagsFormProps { rulesCount: number; onClose: () => void; onConfirm: (bulkActionEditPayload: BulkActionEditPayload) => void; - tags: string[]; } -const TagsFormComponent = ({ editAction, rulesCount, onClose, onConfirm, tags }: TagsFormProps) => { +const TagsFormComponent = ({ editAction, rulesCount, onClose, onConfirm }: TagsFormProps) => { + const { data: tags = [] } = useTags(); const { form } = useForm({ defaultValue: initialFormData, schema, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/timeline_template_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/timeline_template_form.tsx similarity index 85% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/timeline_template_form.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/timeline_template_form.tsx index 6aa5a3100c100..4ad3d04af03d5 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/forms/timeline_template_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/timeline_template_form.tsx @@ -8,11 +8,11 @@ import React, { useCallback } from 'react'; import { EuiCallOut } from '@elastic/eui'; -import type { FormSchema } from '../../../../../../../shared_imports'; -import { useForm, UseField } from '../../../../../../../shared_imports'; -import { PickTimeline } from '../../../../../../components/rules/pick_timeline'; -import type { BulkActionEditPayload } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import type { FormSchema } from '../../../../../../shared_imports'; +import { useForm, UseField } from '../../../../../../shared_imports'; +import { PickTimeline } from '../../../../../../detections/components/rules/pick_timeline'; +import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { BulkEditFormWrapper } from './bulk_edit_form_wrapper'; import { bulkApplyTimelineTemplate as i18n } from '../translations'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/translations.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/translations.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/translations.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/translations.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/types.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/types.ts similarity index 86% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/types.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/types.ts index d81c7c995a2fe..c8250269dbe61 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/types.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/types.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; -import type { BulkAction } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import type { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; +import type { BulkAction } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; /** * Only 2 bulk actions are supported for for confirmation dry run modal: diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx similarity index 81% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx index 05dee7d20823b..48e45e144e479 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx @@ -6,43 +6,39 @@ */ /* eslint-disable complexity */ -import React, { useCallback } from 'react'; import type { EuiContextMenuPanelDescriptor } from '@elastic/eui'; -import { EuiTextColor, EuiFlexGroup, EuiButton, EuiFlexItem } from '@elastic/eui'; -import { euiThemeVars } from '@kbn/ui-theme'; -import { useIsMounted } from '@kbn/securitysolution-hook-utils'; - +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTextColor } from '@elastic/eui'; import type { Toast } from '@kbn/core/public'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; -import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { euiThemeVars } from '@kbn/ui-theme'; +import React, { useCallback } from 'react'; +import type { BulkActionEditPayload } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { BulkAction, BulkActionEditType, -} from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { isMlRule } from '../../../../../../../common/machine_learning/helpers'; -import { canEditRuleWithActions } from '../../../../../../common/utils/privileges'; -import { useRulesTableContext } from '../rules_table/rules_table_context'; -import * as detectionI18n from '../../../translations'; -import * as i18n from '../../translations'; -import { executeRulesBulkAction, downloadExportedRules } from '../actions'; +} from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { isMlRule } from '../../../../../../common/machine_learning/helpers'; +import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; +import { BULK_RULE_ACTIONS } from '../../../../../common/lib/apm/user_actions'; +import { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; +import { canEditRuleWithActions } from '../../../../../common/utils/privileges'; +import * as i18n from '../../../../../detections/pages/detection_engine/rules/translations'; +import * as detectionI18n from '../../../../../detections/pages/detection_engine/translations'; +import { + downloadExportedRules, + useBulkExport, +} from '../../../../rule_management/logic/bulk_actions/use_bulk_export'; +import { useExecuteBulkAction } from '../../../../rule_management/logic/bulk_actions/use_execute_bulk_action'; +import type { FilterOptions } from '../../../../rule_management/logic/types'; +import { convertRulesFilterToKQL } from '../../../../rule_management/logic/utils'; import { getExportedRulesDetails } from '../helpers'; +import { useRulesTableContext } from '../rules_table/rules_table_context'; import { useHasActionsPrivileges } from '../use_has_actions_privileges'; import { useHasMlPermissions } from '../use_has_ml_permissions'; -import { transformExportDetailsToDryRunResult } from './utils/dry_run_result'; +import type { BulkActionForConfirmation, DryRunResult } from './types'; import type { ExecuteBulkActionsDryRun } from './use_bulk_actions_dry_run'; -import { useAppToasts } from '../../../../../../common/hooks/use_app_toasts'; -import { convertRulesFilterToKQL } from '../../../../../containers/detection_engine/rules/utils'; +import { transformExportDetailsToDryRunResult } from './utils/dry_run_result'; import { prepareSearchParams } from './utils/prepare_search_params'; -import type { FilterOptions } from '../../../../../containers/detection_engine/rules/types'; -import { - useInvalidateRules, - useUpdateRulesCache, -} from '../../../../../containers/detection_engine/rules/use_find_rules_query'; -import { BULK_RULE_ACTIONS } from '../../../../../../common/lib/apm/user_actions'; -import { useStartTransaction } from '../../../../../../common/lib/apm/use_start_transaction'; -import { useInvalidatePrePackagedRulesStatus } from '../../../../../containers/detection_engine/rules/use_pre_packaged_rules_status'; - -import type { DryRunResult, BulkActionForConfirmation } from './types'; interface UseBulkActionsArgs { filterOptions: FilterOptions; @@ -54,7 +50,6 @@ interface UseBulkActionsArgs { completeBulkEditForm: ( bulkActionEditType: BulkActionEditType ) => Promise; - reFetchTags: () => void; executeBulkActionsDryRun: ExecuteBulkActionsDryRun; } @@ -63,33 +58,16 @@ export const useBulkActions = ({ confirmDeletion, showBulkActionConfirmation, completeBulkEditForm, - reFetchTags, executeBulkActionsDryRun, }: UseBulkActionsArgs) => { const hasMlPermissions = useHasMlPermissions(); const rulesTableContext = useRulesTableContext(); - const invalidateRules = useInvalidateRules(); - const updateRulesCache = useUpdateRulesCache(); - const invalidatePrePackagedRulesStatus = useInvalidatePrePackagedRulesStatus(); const hasActionsPrivileges = useHasActionsPrivileges(); const toasts = useAppToasts(); - const getIsMounted = useIsMounted(); const filterQuery = convertRulesFilterToKQL(filterOptions); const { startTransaction } = useStartTransaction(); - - // refetch tags if edit action is related to tags: add_tags/delete_tags/set_tags - const resolveTagsRefetch = useCallback( - async (bulkEditActionType: BulkActionEditType) => { - const isTagsAction = [ - BulkActionEditType.add_tags, - BulkActionEditType.set_tags, - BulkActionEditType.delete_tags, - ].includes(bulkEditActionType); - - return isTagsAction ? reFetchTags() : null; - }, - [reFetchTags] - ); + const { executeBulkAction } = useExecuteBulkAction(); + const { bulkExport } = useBulkExport(); const { state: { isAllSelected, rules, loadingRuleIds, selectedRuleIds }, @@ -125,14 +103,12 @@ export const useBulkActions = ({ ? disabledRules.map(({ id }) => id) : disabledRulesNoML.map(({ id }) => id); - const res = await executeRulesBulkAction({ + await executeBulkAction({ visibleRuleIds: ruleIds, action: BulkAction.enable, setLoadingRules, - toasts, search: isAllSelected ? { query: filterQuery } : { ids: ruleIds }, }); - updateRulesCache(res?.attributes?.results?.updated ?? []); }; const handleDisableActions = async () => { @@ -141,32 +117,24 @@ export const useBulkActions = ({ const enabledIds = selectedRules.filter(({ enabled }) => enabled).map(({ id }) => id); - const res = await executeRulesBulkAction({ + await executeBulkAction({ visibleRuleIds: enabledIds, action: BulkAction.disable, setLoadingRules, - toasts, search: isAllSelected ? { query: filterQuery } : { ids: enabledIds }, }); - updateRulesCache(res?.attributes?.results?.updated ?? []); }; const handleDuplicateAction = async () => { startTransaction({ name: BULK_RULE_ACTIONS.DUPLICATE }); closePopover(); - await executeRulesBulkAction({ + await executeBulkAction({ visibleRuleIds: selectedRuleIds, action: BulkAction.duplicate, setLoadingRules, - toasts, search: isAllSelected ? { query: filterQuery } : { ids: selectedRuleIds }, }); - invalidateRules(); - // We use prePackagedRulesStatus to display Prebuilt/Custom rules - // counters, so we need to invalidate it when the total number of rules - // changes. - invalidatePrePackagedRulesStatus(); clearRulesSelection(); }; @@ -182,29 +150,21 @@ export const useBulkActions = ({ startTransaction({ name: BULK_RULE_ACTIONS.DELETE }); - await executeRulesBulkAction({ + await executeBulkAction({ visibleRuleIds: selectedRuleIds, action: BulkAction.delete, setLoadingRules, - toasts, search: isAllSelected ? { query: filterQuery } : { ids: selectedRuleIds }, }); - invalidateRules(); - // We use prePackagedRulesStatus to display Prebuilt/Custom rules - // counters, so we need to invalidate it when the total number of rules - // changes. - invalidatePrePackagedRulesStatus(); }; const handleExportAction = async () => { closePopover(); startTransaction({ name: BULK_RULE_ACTIONS.EXPORT }); - const response = await executeRulesBulkAction({ + const response = await bulkExport({ visibleRuleIds: selectedRuleIds, - action: BulkAction.export, setLoadingRules, - toasts, search: isAllSelected ? { query: filterQuery } : { ids: selectedRuleIds }, }); @@ -232,7 +192,6 @@ export const useBulkActions = ({ let longTimeWarningToast: Toast; let isBulkEditFinished = false; - // disabling auto-refresh so user's selected rules won't disappear after table refresh closePopover(); const dryRunResult = await executeBulkActionsDryRun({ @@ -296,11 +255,10 @@ export const useBulkActions = ({ ); }, 5 * 1000); - const res = await executeRulesBulkAction({ + await executeBulkAction({ visibleRuleIds: selectedRuleIds, action: BulkAction.edit, setLoadingRules, - toasts, payload: { edit: [editPayload] }, onFinish: () => hideWarningToast(), search: prepareSearchParams({ @@ -310,10 +268,6 @@ export const useBulkActions = ({ }); isBulkEditFinished = true; - updateRulesCache(res?.attributes?.results?.updated ?? []); - if (getIsMounted()) { - await resolveTagsRefetch(bulkEditActionType); - } }; const isDeleteDisabled = containsLoading || selectedRuleIds.length === 0; @@ -507,20 +461,17 @@ export const useBulkActions = ({ loadingRuleIds, startTransaction, hasMlPermissions, + executeBulkAction, setLoadingRules, - toasts, filterQuery, - updateRulesCache, - invalidateRules, - invalidatePrePackagedRulesStatus, + toasts, clearRulesSelection, confirmDeletion, + bulkExport, showBulkActionConfirmation, executeBulkActionsDryRun, filterOptions, completeBulkEditForm, - getIsMounted, - resolveTagsRefetch, ] ); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_confirmation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions_confirmation.ts similarity index 89% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_confirmation.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions_confirmation.ts index d840abae1f2e2..9ce813fc6d9a2 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_confirmation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions_confirmation.ts @@ -7,13 +7,14 @@ import { useState, useCallback } from 'react'; import { useAsyncConfirmation } from '../rules_table/use_async_confirmation'; -import { useBoolState } from '../../../../../../common/hooks/use_bool_state'; +import { useBoolState } from '../../../../../common/hooks/use_bool_state'; import type { DryRunResult, BulkActionForConfirmation } from './types'; /** * hook that controls bulk actions confirmation modal window and its content */ +// TODO Why does this hook exist? Consider removing it altogether export const useBulkActionsConfirmation = () => { const [bulkAction, setBulkAction] = useState(); const [dryRunResult, setDryRunResult] = useState(); @@ -31,6 +32,7 @@ export const useBulkActionsConfirmation = () => { // show bulk action confirmation window only if there is at least one failed rule, otherwise return early const hasFailedRules = (result?.failedRulesCount ?? 0) > 0; + // TODO Why is this logic here? Extract it out of this hook. if (!hasFailedRules) { return true; } diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions_dry_run.ts similarity index 88% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions_dry_run.ts index 5e14c0a57bf51..d11a2d6c167b8 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_actions_dry_run.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions_dry_run.ts @@ -11,9 +11,9 @@ import { useMutation } from '@tanstack/react-query'; import type { BulkAction, BulkActionEditType, -} from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { BulkActionResponse } from '../../../../../containers/detection_engine/rules'; -import { performBulkAction } from '../../../../../containers/detection_engine/rules'; +} from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { BulkActionResponse } from '../../../../rule_management/logic'; +import { performBulkAction } from '../../../../rule_management/logic'; import { computeDryRunPayload } from './utils/compute_dry_run_payload'; import { processDryRunResult } from './utils/dry_run_result'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_edit_form_flyout.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_edit_form_flyout.ts similarity index 89% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_edit_form_flyout.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_edit_form_flyout.ts index 6d629ae1869b4..063d10a737810 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/use_bulk_edit_form_flyout.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_edit_form_flyout.ts @@ -10,8 +10,8 @@ import { useAsyncConfirmation } from '../rules_table/use_async_confirmation'; import type { BulkActionEditPayload, BulkActionEditType, -} from '../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { useBoolState } from '../../../../../../common/hooks/use_bool_state'; +} from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { useBoolState } from '../../../../../common/hooks/use_bool_state'; export const useBulkEditFormFlyout = () => { const dataFormRef = useRef(null); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/compute_dry_run_payload.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_payload.test.ts similarity index 93% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/compute_dry_run_payload.test.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_payload.test.ts index 361f7edc4823f..b3fe47dd214a0 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/compute_dry_run_payload.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_payload.test.ts @@ -8,7 +8,7 @@ import { BulkAction, BulkActionEditType, -} from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +} from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { computeDryRunPayload } from './compute_dry_run_payload'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/compute_dry_run_payload.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_payload.ts similarity index 87% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/compute_dry_run_payload.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_payload.ts index d8e6f78e33397..36ebb0d5a644d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/compute_dry_run_payload.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_payload.ts @@ -5,12 +5,12 @@ * 2.0. */ -import type { BulkActionEditPayload } from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import type { BulkActionEditPayload } from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { BulkAction, BulkActionEditType, -} from '../../../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { assertUnreachable } from '../../../../../../../../common/utility_types'; +} from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; /** * helper utility that creates payload for _bulk_action API in dry mode diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/dry_run_result.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/dry_run_result.ts similarity index 85% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/dry_run_result.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/dry_run_result.ts index 5a15f03b9810d..627b7bf54cfd3 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/dry_run_result.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/dry_run_result.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { BulkActionsDryRunErrCode } from '../../../../../../../../common/constants'; -import type { ExportRulesDetails } from '../../../../../../../../common/detection_engine/schemas/response/export_rules_details_schema'; -import type { BulkActionResponse } from '../../../../../../containers/detection_engine/rules'; +import { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; +import type { ExportRulesDetails } from '../../../../../../../common/detection_engine/rule_management'; +import type { BulkActionResponse } from '../../../../../rule_management/logic'; import type { DryRunResult } from '../types'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/prepare_search_params.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/prepare_search_params.test.ts similarity index 87% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/prepare_search_params.test.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/prepare_search_params.test.ts index ed7f18376c3f4..3c5dc13ffab66 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/prepare_search_params.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/prepare_search_params.test.ts @@ -6,14 +6,14 @@ */ import type { DryRunResult } from '../types'; -import type { FilterOptions } from '../../../../../../containers/detection_engine/rules/types'; +import type { FilterOptions } from '../../../../../rule_management/logic/types'; -import { convertRulesFilterToKQL } from '../../../../../../containers/detection_engine/rules/utils'; -import { BulkActionsDryRunErrCode } from '../../../../../../../../common/constants'; +import { convertRulesFilterToKQL } from '../../../../../rule_management/logic/utils'; +import { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; import { prepareSearchParams } from './prepare_search_params'; -jest.mock('../../../../../../containers/detection_engine/rules/utils', () => ({ +jest.mock('../../../../../rule_management/logic/utils', () => ({ convertRulesFilterToKQL: jest.fn().mockReturnValue('str'), })); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/prepare_search_params.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/prepare_search_params.ts similarity index 88% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/prepare_search_params.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/prepare_search_params.ts index 72a74a9fa500d..c761e56f4bfef 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/bulk_actions/utils/prepare_search_params.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/prepare_search_params.ts @@ -6,10 +6,10 @@ */ import type { DryRunResult } from '../types'; -import type { FilterOptions } from '../../../../../../containers/detection_engine/rules/types'; +import type { FilterOptions } from '../../../../../rule_management/logic/types'; -import { convertRulesFilterToKQL } from '../../../../../../containers/detection_engine/rules/utils'; -import { BulkActionsDryRunErrCode } from '../../../../../../../../common/constants'; +import { convertRulesFilterToKQL } from '../../../../../rule_management/logic/utils'; +import { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; type PrepareSearchFilterProps = | { selectedRuleIds: string[]; dryRunResult?: DryRunResult } diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/README.md b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/README.md similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/README.md rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/README.md diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/rules_feature_tour.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx similarity index 98% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/rules_feature_tour.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx index 9558aab5239bb..d2f64ec882840 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/rules_feature_tour.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/rules_feature_tour.tsx @@ -23,8 +23,8 @@ import { import { noop } from 'lodash'; import type { FC } from 'react'; import React, { useEffect, useMemo, useState } from 'react'; -import { NEW_FEATURES_TOUR_STORAGE_KEYS } from '../../../../../../../common/constants'; -import { useKibana } from '../../../../../../common/lib/kibana'; +import { NEW_FEATURES_TOUR_STORAGE_KEYS } from '../../../../../../common/constants'; +import { useKibana } from '../../../../../common/lib/kibana'; import * as i18n from './translations'; export interface RulesFeatureTourContextType { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/translations.ts similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/feature_tour/translations.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/feature_tour/translations.ts diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/helpers.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/helpers.test.ts similarity index 60% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/helpers.test.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/helpers.test.ts index aa65c05db762c..babedf3c14905 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/helpers.test.ts @@ -6,52 +6,10 @@ */ import { Query } from '@elastic/eui'; -import { EXCEPTIONS_SEARCH_SCHEMA } from './exceptions/exceptions_search_bar'; -import { caseInsensitiveSort, getSearchFilters, showRulesTable } from './helpers'; +import { EXCEPTIONS_SEARCH_SCHEMA } from '../../../rule_exceptions_ui/pages/exceptions/exceptions_search_bar'; +import { caseInsensitiveSort, getSearchFilters } from './helpers'; describe('AllRulesTable Helpers', () => { - describe('showRulesTable', () => { - test('returns false when rulesCustomInstalled and rulesInstalled are null', () => { - const result = showRulesTable({ - rulesCustomInstalled: undefined, - rulesInstalled: undefined, - }); - expect(result).toBeFalsy(); - }); - - test('returns false when rulesCustomInstalled and rulesInstalled are 0', () => { - const result = showRulesTable({ - rulesCustomInstalled: 0, - rulesInstalled: 0, - }); - expect(result).toBeFalsy(); - }); - - test('returns false when both rulesCustomInstalled and rulesInstalled checks return false', () => { - const result = showRulesTable({ - rulesCustomInstalled: 0, - rulesInstalled: undefined, - }); - expect(result).toBeFalsy(); - }); - - test('returns true if rulesCustomInstalled is not null or 0', () => { - const result = showRulesTable({ - rulesCustomInstalled: 5, - rulesInstalled: undefined, - }); - expect(result).toBeTruthy(); - }); - - test('returns true if rulesInstalled is not null or 0', () => { - const result = showRulesTable({ - rulesCustomInstalled: undefined, - rulesInstalled: 5, - }); - expect(result).toBeTruthy(); - }); - }); - describe('caseInsensitiveSort', () => { describe('when an array of differently cased tags is passed', () => { const unsortedTags = ['atest', 'Ctest', 'Btest', 'ctest', 'btest', 'Atest']; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/helpers.ts similarity index 82% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/helpers.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/helpers.ts index bc95640d2d292..13666f514b0be 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/helpers.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/helpers.ts @@ -6,18 +6,8 @@ */ import type { Query } from '@elastic/eui'; -import type { ExportRulesDetails } from '../../../../../../common/detection_engine/schemas/response/export_rules_details_schema'; -import type { BulkActionSummary } from '../../../../containers/detection_engine/rules'; - -export const showRulesTable = ({ - rulesCustomInstalled, - rulesInstalled, -}: { - rulesCustomInstalled?: number; - rulesInstalled?: number; -}) => - (rulesCustomInstalled != null && rulesCustomInstalled > 0) || - (rulesInstalled != null && rulesInstalled > 0); +import type { ExportRulesDetails } from '../../../../../common/detection_engine/rule_management'; +import type { BulkActionSummary } from '../../../rule_management/logic'; export const caseInsensitiveSort = (tags: string[]): string[] => { return tags.sort((a: string, b: string) => a.toLowerCase().localeCompare(b.toLowerCase())); // Case insensitive diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/index.tsx new file mode 100644 index 0000000000000..5e93508339980 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/index.tsx @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiSpacer } from '@elastic/eui'; +import React, { useState } from 'react'; +import { RulesTables } from './rules_tables'; +import { AllRulesTabs, RulesTableToolbar } from './rules_table_toolbar'; + +/** + * Table Component for displaying all Rules for a given cluster. Provides the ability to filter + * by name, sort by enabled, and perform the following actions: + * * Enable/Disable + * * Duplicate + * * Delete + * * Import/Export + */ +export const AllRules = React.memo(() => { + const [activeTab, setActiveTab] = useState(AllRulesTabs.rules); + + return ( + <> + + + + + ); +}); + +AllRules.displayName = 'AllRules'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/popover_tooltip.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/popover_tooltip.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/popover_tooltip.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/popover_tooltip.tsx index 564f73c379c63..2d11e2e9a8009 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/popover_tooltip.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/popover_tooltip.tsx @@ -7,7 +7,7 @@ import React, { useState } from 'react'; import { EuiPopover, EuiButtonIcon } from '@elastic/eui'; -import * as i18n from '../translations'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; interface PopoverTooltipProps { columnName: string; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/__mocks__/rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/__mocks__/rules_table_context.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/__mocks__/rules_table_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/__mocks__/rules_table_context.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/rules_table_context.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context.tsx similarity index 96% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/rules_table_context.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context.tsx index 91f7079011aa1..78c391d175747 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/rules_table_context.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context.tsx @@ -14,16 +14,16 @@ import React, { useState, useRef, } from 'react'; -import { DEFAULT_RULES_TABLE_REFRESH_SETTING } from '../../../../../../../common/constants'; -import { invariant } from '../../../../../../../common/utils/invariant'; -import { useKibana, useUiSetting$ } from '../../../../../../common/lib/kibana'; +import { DEFAULT_RULES_TABLE_REFRESH_SETTING } from '../../../../../../common/constants'; +import { invariant } from '../../../../../../common/utils/invariant'; +import { useKibana, useUiSetting$ } from '../../../../../common/lib/kibana'; import type { FilterOptions, PaginationOptions, Rule, SortingOptions, -} from '../../../../../containers/detection_engine/rules/types'; -import { useFindRules } from './use_find_rules'; +} from '../../../../rule_management/logic/types'; +import { useFindRulesInMemory } from './use_find_rules_in_memory'; import { getRulesComparator } from './utils'; export interface RulesTableState { @@ -121,7 +121,7 @@ export interface LoadingRules { } export interface RulesTableActions { - reFetchRules: ReturnType['refetch']; + reFetchRules: ReturnType['refetch']; setFilterOptions: (newFilter: Partial) => void; setIsAllSelected: React.Dispatch>; setIsInMemorySorting: (value: boolean) => void; @@ -239,7 +239,7 @@ export const RulesTableContextProvider = ({ children }: RulesTableContextProvide isFetching, isLoading, isRefetching, - } = useFindRules({ + } = useFindRulesInMemory({ isInMemorySorting, filterOptions, sortingOptions, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/use_async_confirmation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/use_async_confirmation.ts similarity index 97% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/use_async_confirmation.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/use_async_confirmation.ts index cce45f87d8ce3..3042906f87cf3 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/use_async_confirmation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/use_async_confirmation.ts @@ -18,6 +18,7 @@ interface UseAsyncConfirmationArgs { onFinish: () => void; } +// TODO move to common hooks export const useAsyncConfirmation = ({ onInit, onFinish, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/use_find_rules.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory.ts similarity index 79% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/use_find_rules.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory.ts index 2cdd3ab4b8e46..c1429fddbd312 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/use_find_rules.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/use_find_rules_in_memory.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { FindRulesQueryArgs } from '../../../../../containers/detection_engine/rules/use_find_rules_query'; -import { useFindRulesQuery } from '../../../../../containers/detection_engine/rules/use_find_rules_query'; +import type { FindRulesQueryArgs } from '../../../../rule_management/api/hooks/use_find_rules_query'; +import { useFindRules } from '../../../../rule_management/logic/use_find_rules'; interface UseFindRulesArgs extends FindRulesQueryArgs { isInMemorySorting: boolean; @@ -23,12 +23,11 @@ const MAX_RULES_PER_PAGE = 10000; * @param args - find rules arguments * @returns rules query result */ -export const useFindRules = (args: UseFindRulesArgs) => { +export const useFindRulesInMemory = (args: UseFindRulesArgs) => { const { pagination, filterOptions, sortingOptions, isInMemorySorting, refetchInterval } = args; // Use this query result when isInMemorySorting = true - const allRules = useFindRulesQuery( - ['all'], + const allRules = useFindRules( { pagination: { page: 1, perPage: MAX_RULES_PER_PAGE }, filterOptions }, { refetchInterval, @@ -38,8 +37,7 @@ export const useFindRules = (args: UseFindRulesArgs) => { ); // Use this query result when isInMemorySorting = false - const pagedRules = useFindRulesQuery( - ['paged'], + const pagedRules = useFindRules( { pagination, filterOptions, sortingOptions }, { refetchInterval, diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/utils.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/utils.ts similarity index 95% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/utils.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/utils.ts index 13fe9230d2114..5382a740f8213 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table/utils.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table/utils.ts @@ -6,7 +6,7 @@ */ import { get } from 'lodash'; -import type { Rule, SortingOptions } from '../../../../../containers/detection_engine/rules/types'; +import type { Rule, SortingOptions } from '../../../../rule_management/logic/types'; /** * Returns a comparator function to be used with .sort() diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx similarity index 84% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx index 1f266fd62ff82..784d3dfc62427 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/rules_table_filters.tsx @@ -15,11 +15,13 @@ import { import { isEqual } from 'lodash/fp'; import React, { useCallback } from 'react'; import styled from 'styled-components'; -import { RULES_TABLE_ACTIONS } from '../../../../../../common/lib/apm/user_actions'; -import { useStartTransaction } from '../../../../../../common/lib/apm/use_start_transaction'; -import * as i18n from '../../translations'; +import { RULES_TABLE_ACTIONS } from '../../../../../common/lib/apm/user_actions'; +import { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; +import { usePrePackagedRulesStatus } from '../../../../rule_management/logic/use_pre_packaged_rules_status'; +import * as i18n from '../../../../../detections/pages/detection_engine/rules/translations'; import { useRulesTableContext } from '../rules_table/rules_table_context'; import { TagsFilterPopover } from './tags_filter_popover'; +import { useTags } from '../../../../rule_management/logic/use_tags'; const FilterWrapper = styled(EuiFlexGroup)` margin-bottom: ${({ theme }) => theme.eui.euiSizeXS}; @@ -34,26 +36,20 @@ const SearchBarWrapper = styled(EuiFlexItem)` } `; -interface RulesTableFiltersProps { - rulesCustomInstalled?: number; - rulesInstalled?: number; - allTags: string[]; -} - /** * Collection of filters for filtering data within the RulesTable. Contains search bar, Elastic/Custom * Rules filter button toggle, and tag selection */ -const RulesTableFiltersComponent = ({ - rulesCustomInstalled, - rulesInstalled, - allTags, -}: RulesTableFiltersProps) => { +const RulesTableFiltersComponent = () => { const { startTransaction } = useStartTransaction(); const { state: { filterOptions }, actions: { setFilterOptions }, } = useRulesTableContext(); + const { data: allTags = [] } = useTags(); + const { data: prePackagedRulesStatus } = usePrePackagedRulesStatus(); + const rulesCustomInstalled = prePackagedRulesStatus?.rules_custom_installed; + const rulesInstalled = prePackagedRulesStatus?.rules_installed; const { showCustomRules, showElasticRules, tags: selectedTags } = filterOptions; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/tags_filter_popover.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/tags_filter_popover.test.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/tags_filter_popover.tsx similarity index 94% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/tags_filter_popover.tsx index 683e36c391614..b74cf38cc9266 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/tags_filter_popover.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_filters/tags_filter_popover.tsx @@ -19,8 +19,8 @@ import { EuiPopoverTitle, } from '@elastic/eui'; import styled from 'styled-components'; -import * as i18n from '../../translations'; -import { toggleSelectedGroup } from '../../../../../../common/components/ml_popover/jobs_table/filters/toggle_selected_group'; +import * as i18n from '../../../../../detections/pages/detection_engine/rules/translations'; +import { toggleSelectedGroup } from '../../../../../common/components/ml_popover/jobs_table/filters/toggle_selected_group'; import { caseInsensitiveSort } from '../helpers'; interface TagsFilterPopoverProps { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_toolbar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx similarity index 91% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_toolbar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx index cf8d253dbcc89..7d9fda7203702 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_toolbar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_toolbar.tsx @@ -10,9 +10,9 @@ import { EuiSwitch, EuiTab, EuiTabs, EuiToolTip } from '@elastic/eui'; import React, { useCallback } from 'react'; import styled from 'styled-components'; import { useRulesTableContext } from './rules_table/rules_table_context'; -import * as i18n from '../translations'; -import { RULES_TABLE_ACTIONS } from '../../../../../common/lib/apm/user_actions'; -import { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import { RULES_TABLE_ACTIONS } from '../../../../common/lib/apm/user_actions'; +import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; const ToolbarLayout = styled.div` display: grid; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_utility_bar.test.tsx similarity index 67% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_utility_bar.test.tsx index 4fecfc4afa6a2..2b88020f4ff35 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.test.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_utility_bar.test.tsx @@ -10,26 +10,28 @@ import { mount } from 'enzyme'; import { waitFor } from '@testing-library/react'; import { getShowingRulesParams, RulesTableUtilityBar } from './rules_table_utility_bar'; -import { TestProviders } from '../../../../../common/mock'; +import { TestProviders } from '../../../../common/mock'; +import { useRulesTableContextMock } from './rules_table/__mocks__/rules_table_context'; +import { useRulesTableContext } from './rules_table/rules_table_context'; jest.mock('./rules_table/rules_table_context'); describe('RulesTableUtilityBar', () => { it('renders RulesTableUtilityBar total rules and selected rules', () => { + const rulesTableContext = useRulesTableContextMock.create(); + rulesTableContext.state.pagination = { + page: 1, + perPage: 10, + total: 21, + }; + rulesTableContext.state.selectedRuleIds = ['testId']; + (useRulesTableContext as jest.Mock).mockReturnValue(rulesTableContext); + const wrapper = mount( @@ -43,45 +45,12 @@ describe('RulesTableUtilityBar', () => { ); }); - it('renders correct pagination label according to pagination data', () => { - const wrapper = mount( - - - - ); - expect(wrapper.find('[data-test-subj="showingRules"]').at(0).text()).toEqual( - 'Showing 1-10 of 21 rules' - ); - }); - it('renders utility actions if user has permissions', () => { const wrapper = mount( @@ -95,16 +64,7 @@ describe('RulesTableUtilityBar', () => { @@ -113,22 +73,15 @@ describe('RulesTableUtilityBar', () => { expect(wrapper.find('[data-test-subj="bulkActions"]').exists()).toBeFalsy(); }); - it('invokes refresh on refresh action click', () => { - const mockRefresh = jest.fn(); + it('invokes rules refetch on refresh action click', () => { + const rulesTableContext = useRulesTableContextMock.create(); + (useRulesTableContext as jest.Mock).mockReturnValue(rulesTableContext); + const wrapper = mount( @@ -136,25 +89,19 @@ describe('RulesTableUtilityBar', () => { wrapper.find('[data-test-subj="refreshRulesAction"] button').at(0).simulate('click'); - expect(mockRefresh).toHaveBeenCalled(); + expect(rulesTableContext.actions.reFetchRules).toHaveBeenCalledTimes(1); }); - it('invokes onRefreshSwitch when auto refresh switch is clicked if there are not selected items', async () => { - const mockSwitch = jest.fn(); + it('invokes rule refetch when auto refresh switch is clicked if there are not selected items', async () => { + const rulesTableContext = useRulesTableContextMock.create(); + rulesTableContext.state.isRefreshOn = false; + (useRulesTableContext as jest.Mock).mockReturnValue(rulesTableContext); + const wrapper = mount( @@ -163,26 +110,21 @@ describe('RulesTableUtilityBar', () => { await waitFor(() => { wrapper.find('[data-test-subj="refreshSettings"] button').first().simulate('click'); wrapper.find('[data-test-subj="refreshSettingsSwitch"] button').first().simulate('click'); - expect(mockSwitch).toHaveBeenCalledTimes(1); + expect(rulesTableContext.actions.reFetchRules).toHaveBeenCalledTimes(1); }); }); it('does not invokes onRefreshSwitch when auto refresh switch is clicked if there are selected items', async () => { - const mockSwitch = jest.fn(); + const rulesTableContext = useRulesTableContextMock.create(); + rulesTableContext.state.isRefreshOn = false; + rulesTableContext.state.selectedRuleIds = ['testId']; + (useRulesTableContext as jest.Mock).mockReturnValue(rulesTableContext); + const wrapper = mount( @@ -191,7 +133,7 @@ describe('RulesTableUtilityBar', () => { await waitFor(() => { wrapper.find('[data-test-subj="refreshSettings"] button').first().simulate('click'); wrapper.find('[data-test-subj="refreshSettingsSwitch"] button').first().simulate('click'); - expect(mockSwitch).not.toHaveBeenCalled(); + expect(rulesTableContext.actions.reFetchRules).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_utility_bar.tsx similarity index 78% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_utility_bar.tsx index 7f9b0dba04881..7c91e27423697 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_utility_bar.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_table_utility_bar.tsx @@ -22,11 +22,13 @@ import { UtilityBarGroup, UtilityBarSection, UtilityBarText, -} from '../../../../../common/components/utility_bar'; -import * as i18n from '../translations'; -import { useKibana } from '../../../../../common/lib/kibana'; +} from '../../../../common/components/utility_bar'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import { useKibana } from '../../../../common/lib/kibana'; import { useRulesTableContext } from './rules_table/rules_table_context'; -import type { PaginationOptions } from '../../../../containers/detection_engine/rules/types'; +import type { PaginationOptions } from '../../../rule_management/logic/types'; +import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; +import { RULES_TABLE_ACTIONS } from '../../../../common/lib/apm/user_actions'; export const getShowingRulesParams = ({ page, perPage, total: totalRules }: PaginationOptions) => { const firstInPage = totalRules === 0 ? 0 : (page - 1) * perPage + 1; @@ -37,35 +39,27 @@ export const getShowingRulesParams = ({ page, perPage, total: totalRules }: Pagi interface RulesTableUtilityBarProps { canBulkEdit: boolean; - isAllSelected?: boolean; - isAutoRefreshOn?: boolean; - numberSelectedItems: number; onGetBulkItemsPopoverContent?: (closePopover: () => void) => EuiContextMenuPanelDescriptor[]; - onRefresh: () => void; - onRefreshSwitch: (checked: boolean) => void; onToggleSelectAll: () => void; - pagination: PaginationOptions; isBulkActionInProgress?: boolean; - hasDisabledActions?: boolean; } export const RulesTableUtilityBar = React.memo( - ({ - canBulkEdit, - isAllSelected, - isAutoRefreshOn, - numberSelectedItems, - onGetBulkItemsPopoverContent, - onRefresh, - onRefreshSwitch, - onToggleSelectAll, - pagination, - isBulkActionInProgress, - hasDisabledActions, - }) => { + ({ canBulkEdit, onGetBulkItemsPopoverContent, onToggleSelectAll, isBulkActionInProgress }) => { const { timelines } = useKibana().services; + const { startTransaction } = useStartTransaction(); const rulesTableContext = useRulesTableContext(); - const isAnyRuleSelected = numberSelectedItems > 0; + const { pagination, selectedRuleIds, isRefreshOn, isAllSelected, loadingRulesAction } = + rulesTableContext.state; + const { reFetchRules, setIsRefreshOn } = rulesTableContext.actions; + const selectedRulesCount = isAllSelected ? pagination.total : selectedRuleIds.length; + const isAnyRuleSelected = selectedRulesCount > 0; + const hasDisabledActions = loadingRulesAction != null; + + const handleRefreshRules = useCallback(() => { + startTransaction({ name: RULES_TABLE_ACTIONS.REFRESH }); + reFetchRules(); + }, [reFetchRules, startTransaction]); const handleGetBulkItemsPopoverContent = useCallback( (closePopover: () => void): JSX.Element | null => { @@ -85,12 +79,14 @@ export const RulesTableUtilityBar = React.memo( const handleAutoRefreshSwitch = useCallback( (closePopover: () => void) => (e: EuiSwitchEvent) => { - if (onRefreshSwitch != null) { - onRefreshSwitch(e.target.checked); - closePopover(); + const refreshOn = e.target.checked; + if (refreshOn) { + reFetchRules(); } + setIsRefreshOn(refreshOn); + closePopover(); }, - [onRefreshSwitch] + [reFetchRules, setIsRefreshOn] ); const handleGetRefreshSettingsPopoverContent = useCallback( @@ -100,7 +96,7 @@ export const RulesTableUtilityBar = React.memo( ( ]} /> ), - [isAutoRefreshOn, handleAutoRefreshSwitch, isAnyRuleSelected] + [isRefreshOn, handleAutoRefreshSwitch, isAnyRuleSelected] ); return ( @@ -136,7 +132,7 @@ export const RulesTableUtilityBar = React.memo( <> - {i18n.SELECTED_RULES(numberSelectedItems)} + {i18n.SELECTED_RULES(selectedRulesCount)} {canBulkEdit && ( @@ -170,7 +166,7 @@ export const RulesTableUtilityBar = React.memo( dataTestSubj="refreshRulesAction" iconSide="left" iconType="refresh" - onClick={onRefresh} + onClick={handleRefreshRules} > {i18n.REFRESH} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx new file mode 100644 index 0000000000000..4379674c9738f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/rules_tables.tsx @@ -0,0 +1,290 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiBasicTable, + EuiConfirmModal, + EuiEmptyPrompt, + EuiLoadingContent, + EuiProgress, +} from '@elastic/eui'; +import React, { useCallback, useMemo, useRef } from 'react'; +import { RULES_TABLE_PAGE_SIZE_OPTIONS } from '../../../../../common/constants'; +import { Loader } from '../../../../common/components/loader'; +import { useBoolState } from '../../../../common/hooks/use_bool_state'; +import { useValueChanged } from '../../../../common/hooks/use_value_changed'; +import { PrePackagedRulesPrompt } from '../../../../detections/components/rules/pre_packaged_rules/load_empty_prompt'; +import type { Rule, RulesSortingFields } from '../../../rule_management/logic'; +import { usePrePackagedRulesStatus } from '../../../rule_management/logic/use_pre_packaged_rules_status'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import type { EuiBasicTableOnChange } from '../../../../detections/pages/detection_engine/rules/types'; +import { BulkActionDryRunConfirmation } from './bulk_actions/bulk_action_dry_run_confirmation'; +import { BulkEditFlyout } from './bulk_actions/bulk_edit_flyout'; +import { useBulkActions } from './bulk_actions/use_bulk_actions'; +import { useBulkActionsConfirmation } from './bulk_actions/use_bulk_actions_confirmation'; +import { useBulkActionsDryRun } from './bulk_actions/use_bulk_actions_dry_run'; +import { useBulkEditFormFlyout } from './bulk_actions/use_bulk_edit_form_flyout'; +import { useRulesTableContext } from './rules_table/rules_table_context'; +import { useAsyncConfirmation } from './rules_table/use_async_confirmation'; +import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; +import { AllRulesTabs } from './rules_table_toolbar'; +import { RulesTableUtilityBar } from './rules_table_utility_bar'; +import { useMonitoringColumns, useRulesColumns } from './use_columns'; +import { useUserData } from '../../../../detections/components/user_info'; +import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; + +const INITIAL_SORT_FIELD = 'enabled'; + +interface RulesTableProps { + selectedTab: AllRulesTabs; +} + +const NO_ITEMS_MESSAGE = ( + {i18n.NO_RULES}} titleSize="xs" body={i18n.NO_RULES_BODY} /> +); + +/** + * Table Component for displaying all Rules for a given cluster. Provides the ability to filter + * by name, sort by enabled, and perform the following actions: + * * Enable/Disable + * * Duplicate + * * Delete + * * Import/Export + */ +// eslint-disable-next-line complexity +export const RulesTables = React.memo(({ selectedTab }) => { + const [{ canUserCRUD }] = useUserData(); + const hasPermissions = hasUserCRUDPermission(canUserCRUD); + + const tableRef = useRef(null); + const rulesTableContext = useRulesTableContext(); + const { data: prePackagedRulesStatus, isLoading: isPrepackagedStatusLoading } = + usePrePackagedRulesStatus(); + + const { + state: { + rules, + filterOptions, + isActionInProgress, + isAllSelected, + isFetched, + isLoading, + isRefetching, + loadingRuleIds, + loadingRulesAction, + pagination, + selectedRuleIds, + sortingOptions, + }, + actions: { setIsAllSelected, setPage, setPerPage, setSelectedRuleIds, setSortingOptions }, + } = rulesTableContext; + + const [isDeleteConfirmationVisible, showDeleteConfirmation, hideDeleteConfirmation] = + useBoolState(); + + const [confirmDeletion, handleDeletionConfirm, handleDeletionCancel] = useAsyncConfirmation({ + onInit: showDeleteConfirmation, + onFinish: hideDeleteConfirmation, + }); + + const { + bulkActionsDryRunResult, + bulkAction, + isBulkActionConfirmationVisible, + showBulkActionConfirmation, + cancelBulkActionConfirmation, + approveBulkActionConfirmation, + } = useBulkActionsConfirmation(); + + const { + bulkEditActionType, + isBulkEditFlyoutVisible, + handleBulkEditFormConfirm, + handleBulkEditFormCancel, + completeBulkEditForm, + } = useBulkEditFormFlyout(); + + const { isBulkActionsDryRunLoading, executeBulkActionsDryRun } = useBulkActionsDryRun(); + + const getBulkItemsPopoverContent = useBulkActions({ + filterOptions, + confirmDeletion, + showBulkActionConfirmation, + completeBulkEditForm, + executeBulkActionsDryRun, + }); + + const paginationMemo = useMemo( + () => ({ + pageIndex: pagination.page - 1, + pageSize: pagination.perPage, + totalItemCount: pagination.total, + pageSizeOptions: RULES_TABLE_PAGE_SIZE_OPTIONS, + }), + [pagination] + ); + + const tableOnChangeCallback = useCallback( + ({ page, sort }: EuiBasicTableOnChange) => { + setSortingOptions({ + field: (sort?.field as RulesSortingFields) ?? INITIAL_SORT_FIELD, // Narrowing EuiBasicTable sorting types + order: sort?.direction ?? 'desc', + }); + setPage(page.index + 1); + setPerPage(page.size); + }, + [setPage, setPerPage, setSortingOptions] + ); + + const rulesColumns = useRulesColumns({ hasCRUDPermissions: hasPermissions }); + const monitoringColumns = useMonitoringColumns({ hasCRUDPermissions: hasPermissions }); + + const isSelectAllCalled = useRef(false); + + // TODO Remove this synchronization logic after https://github.com/elastic/eui/issues/6184 is implemented + // Synchronize selectedRuleIds with EuiBasicTable's selected rows + useValueChanged((ruleIds) => { + if (tableRef.current != null) { + tableRef.current.setSelection(rules.filter((rule) => ruleIds.includes(rule.id))); + } + }, selectedRuleIds); + + const euiBasicTableSelectionProps = useMemo( + () => ({ + selectable: (item: Rule) => !loadingRuleIds.includes(item.id), + onSelectionChange: (selected: Rule[]) => { + /** + * EuiBasicTable doesn't provide declarative API to control selected rows. + * This limitation requires us to synchronize selection state manually using setSelection(). + * But it creates a chain reaction when the user clicks Select All: + * selectAll() -> setSelection() -> onSelectionChange() -> setSelection(). + * To break the chain we should check whether the onSelectionChange was triggered + * by the Select All action or not. + * + */ + if (isSelectAllCalled.current) { + isSelectAllCalled.current = false; + // Handle special case of unselecting all rules via checkbox + // after all rules were selected via Bulk select. + if (selected.length === 0) { + setIsAllSelected(false); + setSelectedRuleIds([]); + } + } else { + setSelectedRuleIds(selected.map(({ id }) => id)); + setIsAllSelected(false); + } + }, + }), + [loadingRuleIds, setIsAllSelected, setSelectedRuleIds] + ); + + const toggleSelectAll = useCallback(() => { + isSelectAllCalled.current = true; + setIsAllSelected(!isAllSelected); + setSelectedRuleIds(!isAllSelected ? rules.map(({ id }) => id) : []); + }, [rules, isAllSelected, setIsAllSelected, setSelectedRuleIds]); + + const isTableEmpty = + !isPrepackagedStatusLoading && + prePackagedRulesStatus?.rules_custom_installed === 0 && + prePackagedRulesStatus.rules_installed === 0; + + const shouldShowRulesTable = !isPrepackagedStatusLoading && !isLoading && !isTableEmpty; + + const tableProps = + selectedTab === AllRulesTabs.rules + ? { + 'data-test-subj': 'rules-table', + columns: rulesColumns, + } + : { 'data-test-subj': 'monitoring-table', columns: monitoringColumns }; + + const shouldShowLinearProgress = isFetched && isRefetching; + const shouldShowLoadingOverlay = (!isFetched && isRefetching) || isActionInProgress; + + return ( + <> + {shouldShowLinearProgress && ( + + )} + {shouldShowLoadingOverlay && ( + + )} + {shouldShowRulesTable && } + {isTableEmpty && } + {isLoading && ( + + )} + {isDeleteConfirmationVisible && ( + +

{i18n.DELETE_CONFIRMATION_BODY}

+ + )} + {isBulkActionConfirmationVisible && bulkAction && ( + + )} + {isBulkEditFlyoutVisible && bulkEditActionType !== undefined && ( + + )} + {shouldShowRulesTable && ( + <> + + + + )} + + ); +}); + +RulesTables.displayName = 'RulesTables'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/table_header_tooltip_cell.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/table_header_tooltip_cell.test.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/table_header_tooltip_cell.test.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/table_header_tooltip_cell.test.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/table_header_tooltip_cell.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/table_header_tooltip_cell.tsx similarity index 100% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/table_header_tooltip_cell.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/table_header_tooltip_cell.tsx diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx similarity index 82% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx index 2fa479d01b5d2..e169faa0be3a8 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_columns.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_columns.tsx @@ -8,45 +8,41 @@ import type { EuiBasicTableColumn, EuiTableActionsColumnType } from '@elastic/eui'; import { EuiBadge, EuiLink, EuiText, EuiToolTip } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import React, { useMemo } from 'react'; import moment from 'moment'; -import { IntegrationsPopover } from '../../../../components/rules/related_integrations/integrations_popover'; +import React, { useMemo } from 'react'; import { DEFAULT_RELATIVE_DATE_THRESHOLD, SecurityPageName, SHOW_RELATED_INTEGRATIONS_SETTING, -} from '../../../../../../common/constants'; -import { isMlRule } from '../../../../../../common/machine_learning/helpers'; -import { getEmptyTagValue } from '../../../../../common/components/empty_value'; -import { FormattedRelativePreferenceDate } from '../../../../../common/components/formatted_date'; -import { getRuleDetailsTabUrl } from '../../../../../common/components/link_to/redirect_to_detection_engine'; -import { PopoverItems } from '../../../../../common/components/popover_items'; -import { useKibana, useUiSetting$ } from '../../../../../common/lib/kibana'; +} from '../../../../../common/constants'; +import type { + DurationMetric, + RuleExecutionSummary, +} from '../../../../../common/detection_engine/rule_monitoring'; +import { isMlRule } from '../../../../../common/machine_learning/helpers'; +import { getEmptyTagValue } from '../../../../common/components/empty_value'; +import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; +import { SecuritySolutionLinkAnchor } from '../../../../common/components/links'; +import { getRuleDetailsTabUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; +import { PopoverItems } from '../../../../common/components/popover_items'; +import { useKibana, useUiSetting$ } from '../../../../common/lib/kibana'; import { canEditRuleWithActions, explainLackOfPermission, -} from '../../../../../common/utils/privileges'; -import { RuleSwitch } from '../../../../components/rules/rule_switch'; -import { SeverityBadge } from '../../../../components/rules/severity_badge'; -import type { Rule } from '../../../../containers/detection_engine/rules'; -import { useRulesTableContext } from './rules_table/rules_table_context'; -import * as i18n from '../translations'; +} from '../../../../common/utils/privileges'; +import { IntegrationsPopover } from '../../../../detections/components/rules/related_integrations/integrations_popover'; +import { RuleStatusBadge } from '../../../../detections/components/rules/rule_execution_status'; +import { RuleSwitch } from '../../../../detections/components/rules/rule_switch'; +import { SeverityBadge } from '../../../../detections/components/rules/severity_badge'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import { RuleDetailTabs } from '../../../rule_details_ui/pages/rule_details'; +import type { Rule } from '../../../rule_management/logic'; import { PopoverTooltip } from './popover_tooltip'; +import { useRulesTableContext } from './rules_table/rules_table_context'; import { TableHeaderTooltipCell } from './table_header_tooltip_cell'; import { useHasActionsPrivileges } from './use_has_actions_privileges'; import { useHasMlPermissions } from './use_has_ml_permissions'; -import { getRulesTableActions } from './rules_table_actions'; -import { RuleStatusBadge } from '../../../../components/rules/rule_execution_status'; -import type { - DurationMetric, - RuleExecutionSummary, -} from '../../../../../../common/detection_engine/rule_monitoring'; -import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; -import { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; -import { useInvalidateRules } from '../../../../containers/detection_engine/rules/use_find_rules_query'; -import { useInvalidatePrePackagedRulesStatus } from '../../../../containers/detection_engine/rules/use_pre_packaged_rules_status'; -import { SecuritySolutionLinkAnchor } from '../../../../../common/components/links'; -import { RuleDetailTabs } from '../details'; +import { useRulesTableActions } from './use_rules_table_actions'; export type TableColumn = EuiBasicTableColumn | EuiTableActionsColumnType; @@ -170,37 +166,9 @@ const INTEGRATIONS_COLUMN: TableColumn = { }; const useActionsColumn = (): EuiTableActionsColumnType => { - const { navigateToApp } = useKibana().services.application; - const hasActionsPrivileges = useHasActionsPrivileges(); - const toasts = useAppToasts(); - const { setLoadingRules } = useRulesTableContext().actions; - const { startTransaction } = useStartTransaction(); - const invalidateRules = useInvalidateRules(); - const invalidatePrePackagedRulesStatus = useInvalidatePrePackagedRulesStatus(); + const actions = useRulesTableActions(); - return useMemo( - () => ({ - actions: getRulesTableActions({ - toasts, - navigateToApp, - invalidateRules, - invalidatePrePackagedRulesStatus, - actionsPrivileges: hasActionsPrivileges, - setLoadingRules, - startTransaction, - }), - width: '40px', - }), - [ - hasActionsPrivileges, - invalidatePrePackagedRulesStatus, - invalidateRules, - navigateToApp, - setLoadingRules, - startTransaction, - toasts, - ] - ); + return useMemo(() => ({ actions, width: '40px' }), [actions]); }; export const useRulesColumns = ({ hasCRUDPermissions }: ColumnsProps): TableColumn[] => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_has_actions_privileges.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_has_actions_privileges.ts similarity index 78% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_has_actions_privileges.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_has_actions_privileges.ts index c2acbed3158f1..fddf86e97646d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_has_actions_privileges.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_has_actions_privileges.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { useKibana } from '../../../../../common/lib/kibana'; -import { isBoolean } from '../../../../../common/utils/privileges'; +import { useKibana } from '../../../../common/lib/kibana'; +import { isBoolean } from '../../../../common/utils/privileges'; export const useHasActionsPrivileges = () => { const { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_has_ml_permissions.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_has_ml_permissions.ts similarity index 62% rename from x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_has_ml_permissions.ts rename to x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_has_ml_permissions.ts index c941ba7183b86..cedec36b33ebd 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/use_has_ml_permissions.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_has_ml_permissions.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { hasMlAdminPermissions } from '../../../../../../common/machine_learning/has_ml_admin_permissions'; -import { hasMlLicense } from '../../../../../../common/machine_learning/has_ml_license'; -import { useMlCapabilities } from '../../../../../common/components/ml/hooks/use_ml_capabilities'; +import { hasMlAdminPermissions } from '../../../../../common/machine_learning/has_ml_admin_permissions'; +import { hasMlLicense } from '../../../../../common/machine_learning/has_ml_license'; +import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; export const useHasMlPermissions = () => { const mlCapabilities = useMlCapabilities(); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx new file mode 100644 index 0000000000000..6e0e2bb761007 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/use_rules_table_actions.tsx @@ -0,0 +1,122 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DefaultItemAction } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; +import React from 'react'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions'; +import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; +import { useKibana } from '../../../../common/lib/kibana'; +import { canEditRuleWithActions } from '../../../../common/utils/privileges'; +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; +import type { Rule } from '../../../rule_management/logic'; +import { + downloadExportedRules, + useBulkExport, +} from '../../../rule_management/logic/bulk_actions/use_bulk_export'; +import { + goToRuleEditPage, + useExecuteBulkAction, +} from '../../../rule_management/logic/bulk_actions/use_execute_bulk_action'; +import { useRulesTableContext } from './rules_table/rules_table_context'; +import { useHasActionsPrivileges } from './use_has_actions_privileges'; + +export const useRulesTableActions = (): Array> => { + const { navigateToApp } = useKibana().services.application; + const hasActionsPrivileges = useHasActionsPrivileges(); + const toasts = useAppToasts(); + const { setLoadingRules } = useRulesTableContext().actions; + const { startTransaction } = useStartTransaction(); + const { executeBulkAction } = useExecuteBulkAction(); + const { bulkExport } = useBulkExport(); + + return [ + { + type: 'icon', + 'data-test-subj': 'editRuleAction', + description: i18n.EDIT_RULE_SETTINGS, + name: !hasActionsPrivileges ? ( + + <>{i18n.EDIT_RULE_SETTINGS} + + ) : ( + i18n.EDIT_RULE_SETTINGS + ), + icon: 'controlsHorizontal', + onClick: (rule: Rule) => goToRuleEditPage(rule.id, navigateToApp), + enabled: (rule: Rule) => canEditRuleWithActions(rule, hasActionsPrivileges), + }, + { + type: 'icon', + 'data-test-subj': 'duplicateRuleAction', + description: i18n.DUPLICATE_RULE, + icon: 'copy', + name: !hasActionsPrivileges ? ( + + <>{i18n.DUPLICATE_RULE} + + ) : ( + i18n.DUPLICATE_RULE + ), + enabled: (rule: Rule) => canEditRuleWithActions(rule, hasActionsPrivileges), + // TODO extract those handlers to hooks, like useDuplicateRule + onClick: async (rule: Rule) => { + startTransaction({ name: SINGLE_RULE_ACTIONS.DUPLICATE }); + const result = await executeBulkAction({ + action: BulkAction.duplicate, + setLoadingRules, + visibleRuleIds: [rule.id], + search: { ids: [rule.id] }, + }); + const createdRules = result?.attributes.results.created; + if (createdRules?.length) { + goToRuleEditPage(createdRules[0].id, navigateToApp); + } + }, + }, + { + type: 'icon', + 'data-test-subj': 'exportRuleAction', + description: i18n.EXPORT_RULE, + icon: 'exportAction', + name: i18n.EXPORT_RULE, + onClick: async (rule: Rule) => { + startTransaction({ name: SINGLE_RULE_ACTIONS.EXPORT }); + const response = await bulkExport({ + setLoadingRules, + visibleRuleIds: [rule.id], + search: { ids: [rule.id] }, + }); + if (response) { + await downloadExportedRules({ + response, + toasts, + }); + } + }, + enabled: (rule: Rule) => !rule.immutable, + }, + { + type: 'icon', + 'data-test-subj': 'deleteRuleAction', + description: i18n.DELETE_RULE, + icon: 'trash', + name: i18n.DELETE_RULE, + onClick: async (rule: Rule) => { + startTransaction({ name: SINGLE_RULE_ACTIONS.DELETE }); + await executeBulkAction({ + action: BulkAction.delete, + setLoadingRules, + visibleRuleIds: [rule.id], + search: { ids: [rule.id] }, + }); + }, + }, + ]; +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx new file mode 100644 index 0000000000000..194e16fdb8e4b --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -0,0 +1,163 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; + +import { APP_UI_ID } from '../../../../../common/constants'; +import { SecurityPageName } from '../../../../app/types'; +import { HeaderPage } from '../../../../common/components/header_page'; +import { ImportDataModal } from '../../../../common/components/import_data_modal'; +import { SecuritySolutionLinkButton } from '../../../../common/components/links'; +import { getDetectionEngineUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; +import { useBoolState } from '../../../../common/hooks/use_bool_state'; +import { useKibana } from '../../../../common/lib/kibana'; +import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; +import { SpyRoute } from '../../../../common/utils/route/spy_routes'; + +import { MissingPrivilegesCallOut } from '../../../../detections/components/callouts/missing_privileges_callout'; +import { MlJobCompatibilityCallout } from '../../../../detections/components/callouts/ml_job_compatibility_callout'; +import { NeedAdminForUpdateRulesCallOut } from '../../../../detections/components/callouts/need_admin_for_update_callout'; +import { LoadPrePackagedRules } from '../../../../detections/components/rules/pre_packaged_rules/load_prepackaged_rules'; +import { LoadPrePackagedRulesButton } from '../../../../detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button'; +import { UpdatePrePackagedRulesCallOut } from '../../../../detections/components/rules/pre_packaged_rules/update_callout'; +import { ValueListsFlyout } from '../../../../detections/components/value_lists_management_flyout'; +import { useUserData } from '../../../../detections/components/user_info'; +import { useListsConfig } from '../../../../detections/containers/detection_engine/lists/use_lists_config'; +import { redirectToDetections } from '../../../../detections/pages/detection_engine/rules/helpers'; + +import { useInvalidateFindRulesQuery } from '../../../rule_management/api/hooks/use_find_rules_query'; +import { importRules } from '../../../rule_management/logic'; +import { usePrePackagedRulesInstallationStatus } from '../../../rule_management/logic/use_pre_packaged_rules_installation_status'; +import { usePrePackagedTimelinesInstallationStatus } from '../../../rule_management/logic/use_pre_packaged_timelines_installation_status'; + +import { AllRules } from '../../components/rules_table'; +import { RulesTableContextProvider } from '../../components/rules_table/rules_table/rules_table_context'; + +import * as i18n from '../../../../detections/pages/detection_engine/rules/translations'; + +const RulesPageComponent: React.FC = () => { + const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState(); + const [isValueListFlyoutVisible, showValueListFlyout, hideValueListFlyout] = useBoolState(); + const { navigateToApp } = useKibana().services.application; + const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); + + const [ + { + loading: userInfoLoading, + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + canUserCRUD, + }, + ] = useUserData(); + const { + loading: listsConfigLoading, + canWriteIndex: canWriteListsIndex, + needsConfiguration: needsListsConfiguration, + } = useListsConfig(); + const loading = userInfoLoading || listsConfigLoading; + const prePackagedRuleStatus = usePrePackagedRulesInstallationStatus(); + const prePackagedTimelineStatus = usePrePackagedTimelinesInstallationStatus(); + + if ( + redirectToDetections( + isSignalIndexExists, + isAuthenticated, + hasEncryptionKey, + needsListsConfiguration + ) + ) { + navigateToApp(APP_UI_ID, { + deepLinkId: SecurityPageName.alerts, + path: getDetectionEngineUrl(), + }); + return null; + } + + return ( + <> + + + + + + + + + + + + + {(renderProps) => } + + + + + + {i18n.IMPORT_VALUE_LISTS} + + + + + + {i18n.IMPORT_RULE} + + + + + {i18n.ADD_NEW_RULE} + + + + + {(prePackagedRuleStatus === 'ruleNeedUpdate' || + prePackagedTimelineStatus === 'timelineNeedUpdate') && ( + + )} + + + + + + + ); +}; + +export const RulesPage = React.memo(RulesPageComponent); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx index 03141dfb02f57..842cdfe82fffb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/alert_context_menu.tsx @@ -42,7 +42,7 @@ import { ATTACH_ALERT_TO_CASE_FOR_ROW } from '../../../../timelines/components/t import { useEventFilterAction } from './use_event_filter_action'; import { useAddToCaseActions } from './use_add_to_case_actions'; import { isAlertFromEndpointAlert } from '../../../../common/utils/endpoint_alert_check'; -import type { Rule } from '../../../containers/detection_engine/rules/types'; +import type { Rule } from '../../../../detection_engine/rule_management/logic/types'; interface AlertContextMenuProps { ariaLabel?: string; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx index f084bb68311a3..cf9711c58f8cb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/helpers.tsx @@ -36,7 +36,8 @@ import * as i18nRiskScore from '../risk_score_mapping/translations'; import type { RequiredFieldArray, Threshold, -} from '../../../../../common/detection_engine/schemas/common'; +} from '../../../../../common/detection_engine/rule_schema'; + import * as i18n from './translations'; import type { BuildQueryBarDescription, BuildThreatDescription, ListItems } from './types'; import { SeverityBadge } from '../severity_badge'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx index 63d2c52323583..aeba71acb6ab8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.test.tsx @@ -21,7 +21,7 @@ import { FilterStateStore } from '@kbn/es-query'; import { mockAboutStepRule, mockDefineStepRule, -} from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +} from '../../../../detection_engine/rule_management_ui/components/rules_table/__mocks__/mock'; import { coreMock } from '@kbn/core/public/mocks'; import { DEFAULT_TIMELINE_TITLE } from '../../../../timelines/components/timeline/translations'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx index ba0359c4fda3e..92879c56e9885 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/description_step/index.tsx @@ -18,7 +18,7 @@ import { buildRelatedIntegrationsDescription } from '../related_integrations/int import type { RelatedIntegrationArray, RequiredFieldArray, -} from '../../../../../common/detection_engine/schemas/common'; +} from '../../../../../common/detection_engine/rule_schema'; import { DEFAULT_TIMELINE_TITLE } from '../../../../timelines/components/timeline/translations'; import type { EqlOptionsSelected } from '../../../../../common/search_strategy'; import { useKibana } from '../../../../common/lib/kibana'; @@ -48,7 +48,7 @@ import { buildMlJobsDescription } from './ml_job_description'; import { buildActionsDescription } from './actions_description'; import { buildThrottleDescription } from './throttle_description'; import { THREAT_QUERY_LABEL } from './translations'; -import { filterEmptyThreats } from '../../../pages/detection_engine/rules/create/helpers'; +import { filterEmptyThreats } from '../../../../detection_engine/rule_creation_ui/pages/rule_creation/helpers'; const DescriptionListContainer = styled(EuiDescriptionList)` &.euiDescriptionList--column .euiDescriptionList__title { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/eql_query_bar.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/eql_query_bar.test.tsx index f30fd074f0d45..51e1e0683d766 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/eql_query_bar.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/eql_query_bar/eql_query_bar.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { shallow, mount } from 'enzyme'; import { mockIndexPattern, TestProviders, useFormFieldMock } from '../../../../common/mock'; -import { mockQueryBar } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +import { mockQueryBar } from '../../../../detection_engine/rule_management_ui/components/rules_table/__mocks__/mock'; import type { EqlQueryBarProps } from './eql_query_bar'; import { EqlQueryBar } from './eql_query_bar'; import { getEqlValidationError } from './validators.mock'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx index b33281a165b8d..bd1b951a7002f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.test.tsx @@ -13,7 +13,7 @@ import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; import { TestProviders } from '../../../../common/mock'; import '../../../../common/mock/match_media'; -import { getPrePackagedRulesStatus } from '../../../containers/detection_engine/rules/api'; +import { getPrePackagedRulesStatus } from '../../../../detection_engine/rule_management/api/api'; import { PrePackagedRulesPrompt } from './load_empty_prompt'; jest.mock('react-router-dom', () => { @@ -43,7 +43,7 @@ jest.mock('../../../../common/lib/kibana/kibana_react', () => { }; }); -jest.mock('../../../containers/detection_engine/rules/api', () => ({ +jest.mock('../../../../detection_engine/rule_management/api/api', () => ({ getPrePackagedRulesStatus: jest.fn().mockResolvedValue({ rules_not_installed: 0, rules_installed: 0, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx index 252787c9dd853..f44008622eb9e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_empty_prompt.tsx @@ -6,17 +6,15 @@ */ import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import React, { memo, useCallback, useMemo, useState } from 'react'; +import React, { memo } from 'react'; import styled from 'styled-components'; -import { affectedJobIds } from '../../callouts/ml_job_compatibility_callout/affected_job_ids'; -import { MlJobUpgradeModal } from '../../modals/ml_job_upgrade_modal'; -import { useInstalledSecurityJobs } from '../../../../common/components/ml/hooks/use_installed_security_jobs'; - -import * as i18n from './translations'; -import { SecuritySolutionLinkButton } from '../../../../common/components/links'; import { SecurityPageName } from '../../../../app/types'; -import { usePrePackagedRules } from '../../../containers/detection_engine/rules'; +import { SecuritySolutionLinkButton } from '../../../../common/components/links'; +import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; import { useUserData } from '../../user_info'; +import { LoadPrePackagedRules } from './load_prepackaged_rules'; +import { LoadPrePackagedRulesButton } from './load_prepackaged_rules_button'; +import * as i18n from './translations'; const EmptyPrompt = styled(EuiEmptyPrompt)` align-self: center; /* Corrects horizontal centering in IE11 */ @@ -24,62 +22,9 @@ const EmptyPrompt = styled(EuiEmptyPrompt)` EmptyPrompt.displayName = 'EmptyPrompt'; -interface PrePackagedRulesPromptProps { - createPrePackagedRules: () => void; - loading: boolean; - userHasPermissions: boolean; -} - -const PrePackagedRulesPromptComponent: React.FC = ({ - createPrePackagedRules, - loading = false, - userHasPermissions = false, -}) => { - const [{ isSignalIndexExists, isAuthenticated, hasEncryptionKey, canUserCRUD, hasIndexWrite }] = - useUserData(); - - const { loading: loadingJobs, jobs } = useInstalledSecurityJobs(); - const legacyJobsInstalled = jobs.filter((job) => affectedJobIds.includes(job.id)); - const [isUpgradeModalVisible, setIsUpgradeModalVisible] = useState(false); - - const { getLoadPrebuiltRulesAndTemplatesButton } = usePrePackagedRules({ - canUserCRUD, - hasIndexWrite, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - }); - - // Wrapper to add confirmation modal for users who may be running older ML Jobs that would - // be overridden by updating their rules. For details, see: https://github.com/elastic/kibana/issues/128121 - const mlJobUpgradeModalConfirm = useCallback(() => { - setIsUpgradeModalVisible(false); - createPrePackagedRules(); - }, [createPrePackagedRules, setIsUpgradeModalVisible]); - - const loadPrebuiltRulesAndTemplatesButton = useMemo( - () => - getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: !userHasPermissions || loading || loadingJobs, - onClick: () => { - if (legacyJobsInstalled.length > 0) { - setIsUpgradeModalVisible(true); - } else { - createPrePackagedRules(); - } - }, - fill: true, - 'data-test-subj': 'load-prebuilt-rules', - }), - [ - getLoadPrebuiltRulesAndTemplatesButton, - userHasPermissions, - loading, - loadingJobs, - legacyJobsInstalled, - createPrePackagedRules, - ] - ); +const PrePackagedRulesPromptComponent = () => { + const [{ canUserCRUD }] = useUserData(); + const hasPermissions = hasUserCRUDPermission(canUserCRUD); return ( = ( body={

{i18n.PRE_BUILT_MSG}

} actions={ - {loadPrebuiltRulesAndTemplatesButton} + + + {(renderProps) => ( + + )} + + {i18n.CREATE_RULE_ACTION} - {isUpgradeModalVisible && ( - setIsUpgradeModalVisible(false)} - onConfirm={mlJobUpgradeModalConfirm} - /> - )} } /> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules.tsx new file mode 100644 index 0000000000000..e5d05d7e7fbb0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback } from 'react'; +import { useInstalledSecurityJobs } from '../../../../common/components/ml/hooks/use_installed_security_jobs'; +import { useBoolState } from '../../../../common/hooks/use_bool_state'; +import { RULES_TABLE_ACTIONS } from '../../../../common/lib/apm/user_actions'; +import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; +import { useCreatePrePackagedRules } from '../../../../detection_engine/rule_management/logic/use_create_pre_packaged_rules'; +import { usePrePackagedRulesStatus } from '../../../../detection_engine/rule_management/logic/use_pre_packaged_rules_status'; +import { affectedJobIds } from '../../callouts/ml_job_compatibility_callout/affected_job_ids'; +import { MlJobUpgradeModal } from '../../modals/ml_job_upgrade_modal'; + +interface LoadPrePackagedRulesRenderProps { + isLoading: boolean; + isDisabled: boolean; + onClick: () => Promise; +} + +interface LoadPrePackagedRulesProps { + children: (renderProps: LoadPrePackagedRulesRenderProps) => React.ReactNode; +} + +export const LoadPrePackagedRules = ({ children }: LoadPrePackagedRulesProps) => { + const { isFetching: isFetchingPrepackagedStatus } = usePrePackagedRulesStatus(); + const { + createPrePackagedRules, + canCreatePrePackagedRules, + isLoading: loadingCreatePrePackagedRules, + } = useCreatePrePackagedRules(); + + const { startTransaction } = useStartTransaction(); + const handleCreatePrePackagedRules = useCallback(async () => { + startTransaction({ name: RULES_TABLE_ACTIONS.LOAD_PREBUILT }); + await createPrePackagedRules(); + }, [createPrePackagedRules, startTransaction]); + + const [isUpgradeModalVisible, showUpgradeModal, hideUpgradeModal] = useBoolState(false); + const { loading: loadingJobs, jobs } = useInstalledSecurityJobs(); + const legacyJobsInstalled = jobs.filter((job) => affectedJobIds.includes(job.id)); + + const handleInstallPrePackagedRules = useCallback(async () => { + if (legacyJobsInstalled.length > 0) { + showUpgradeModal(); + } else { + await handleCreatePrePackagedRules(); + } + }, [handleCreatePrePackagedRules, legacyJobsInstalled.length, showUpgradeModal]); + + // Wrapper to add confirmation modal for users who may be running older ML Jobs that would + // be overridden by updating their rules. For details, see: https://github.com/elastic/kibana/issues/128121 + const mlJobUpgradeModalConfirm = useCallback(() => { + hideUpgradeModal(); + handleCreatePrePackagedRules(); + }, [handleCreatePrePackagedRules, hideUpgradeModal]); + + const isDisabled = !canCreatePrePackagedRules || isFetchingPrepackagedStatus || loadingJobs; + + return ( + <> + {children({ + isLoading: loadingCreatePrePackagedRules, + isDisabled, + onClick: handleInstallPrePackagedRules, + })} + {isUpgradeModalVisible && ( + hideUpgradeModal()} + onConfirm={mlJobUpgradeModalConfirm} + /> + )} + + ); +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button.tsx new file mode 100644 index 0000000000000..996bbc386be37 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/load_prepackaged_rules_button.tsx @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiButton } from '@elastic/eui'; +import React from 'react'; +import { usePrePackagedRulesInstallationStatus } from '../../../../detection_engine/rule_management/logic/use_pre_packaged_rules_installation_status'; +import { usePrePackagedRulesStatus } from '../../../../detection_engine/rule_management/logic/use_pre_packaged_rules_status'; +import { usePrePackagedTimelinesInstallationStatus } from '../../../../detection_engine/rule_management/logic/use_pre_packaged_timelines_installation_status'; +import type { + PrePackagedRuleInstallationStatus, + PrePackagedTimelineInstallationStatus, +} from '../../../pages/detection_engine/rules/helpers'; +import * as i18n from './translations'; + +const getLoadRulesOrTimelinesButtonTitle = ( + rulesStatus: PrePackagedRuleInstallationStatus, + timelineStatus: PrePackagedTimelineInstallationStatus +) => { + if (rulesStatus === 'ruleNotInstalled' && timelineStatus === 'timelinesNotInstalled') + return i18n.LOAD_PREPACKAGED_RULES_AND_TEMPLATES; + else if (rulesStatus === 'ruleNotInstalled' && timelineStatus !== 'timelinesNotInstalled') + return i18n.LOAD_PREPACKAGED_RULES; + else if (rulesStatus !== 'ruleNotInstalled' && timelineStatus === 'timelinesNotInstalled') + return i18n.LOAD_PREPACKAGED_TIMELINE_TEMPLATES; +}; + +const getMissingRulesOrTimelinesButtonTitle = (missingRules: number, missingTimelines: number) => { + if (missingRules > 0 && missingTimelines === 0) + return i18n.RELOAD_MISSING_PREPACKAGED_RULES(missingRules); + else if (missingRules === 0 && missingTimelines > 0) + return i18n.RELOAD_MISSING_PREPACKAGED_TIMELINES(missingTimelines); + else if (missingRules > 0 && missingTimelines > 0) + return i18n.RELOAD_MISSING_PREPACKAGED_RULES_AND_TIMELINES(missingRules, missingTimelines); +}; + +interface LoadPrePackagedRulesButtonProps { + fill?: boolean; + 'data-test-subj'?: string; + isLoading: boolean; + isDisabled: boolean; + onClick: () => Promise; +} + +export const LoadPrePackagedRulesButton = ({ + fill, + 'data-test-subj': dataTestSubj = 'loadPrebuiltRulesBtn', + isLoading, + isDisabled, + onClick, +}: LoadPrePackagedRulesButtonProps) => { + const { data: prePackagedRulesStatus } = usePrePackagedRulesStatus(); + const prePackagedAssetsStatus = usePrePackagedRulesInstallationStatus(); + const prePackagedTimelineStatus = usePrePackagedTimelinesInstallationStatus(); + + const showInstallButton = + (prePackagedAssetsStatus === 'ruleNotInstalled' || + prePackagedTimelineStatus === 'timelinesNotInstalled') && + prePackagedAssetsStatus !== 'someRuleUninstall'; + + if (showInstallButton) { + return ( + + {getLoadRulesOrTimelinesButtonTitle(prePackagedAssetsStatus, prePackagedTimelineStatus)} + + ); + } + + const showUpdateButton = + prePackagedAssetsStatus === 'someRuleUninstall' || + prePackagedTimelineStatus === 'someTimelineUninstall'; + + if (showUpdateButton) { + return ( + + {getMissingRulesOrTimelinesButtonTitle( + prePackagedRulesStatus?.rules_not_installed ?? 0, + prePackagedRulesStatus?.timelines_not_installed ?? 0 + )} + + ); + } + + return null; +}; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts index 5b66b4611c03d..b1207b59faf8b 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/translations.ts @@ -96,3 +96,57 @@ export const RELEASE_NOTES_HELP = i18n.translate( defaultMessage: 'Release notes', } ); + +export const LOAD_PREPACKAGED_RULES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton', + { + defaultMessage: 'Load Elastic prebuilt rules', + } +); + +export const LOAD_PREPACKAGED_TIMELINE_TEMPLATES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedTimelineTemplatesButton', + { + defaultMessage: 'Load Elastic prebuilt timeline templates', + } +); + +export const LOAD_PREPACKAGED_RULES_AND_TEMPLATES = i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesAndTemplatesButton', + { + defaultMessage: 'Load Elastic prebuilt rules and timeline templates', + } +); + +export const RELOAD_MISSING_PREPACKAGED_RULES = (missingRules: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton', + { + values: { missingRules }, + defaultMessage: + 'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} ', + } + ); + +export const RELOAD_MISSING_PREPACKAGED_TIMELINES = (missingTimelines: number) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedTimelinesButton', + { + values: { missingTimelines }, + defaultMessage: + 'Install {missingTimelines} Elastic prebuilt {missingTimelines, plural, =1 {timeline} other {timelines}} ', + } + ); + +export const RELOAD_MISSING_PREPACKAGED_RULES_AND_TIMELINES = ( + missingRules: number, + missingTimelines: number +) => + i18n.translate( + 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesAndTimelinesButton', + { + values: { missingRules, missingTimelines }, + defaultMessage: + 'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} and {missingTimelines} Elastic prebuilt {missingTimelines, plural, =1 {timeline} other {timelines}} ', + } + ); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx index 70b98eb22fd89..6d882fe2930a3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.test.tsx @@ -5,13 +5,18 @@ * 2.0. */ +import { render } from '@testing-library/react'; import React from 'react'; -import { shallow } from 'enzyme'; - -import { UpdatePrePackagedRulesCallOut } from './update_callout'; import { useKibana } from '../../../../common/lib/kibana'; +import { TestProviders } from '../../../../common/mock'; +import { useFetchPrebuiltRulesStatusQuery } from '../../../../detection_engine/rule_management/api/hooks/use_fetch_prebuilt_rules_status_query'; +import { mockReactQueryResponse } from '../../../../detection_engine/rule_management/api/hooks/__mocks__/mock_react_query_response'; +import { UpdatePrePackagedRulesCallOut } from './update_callout'; jest.mock('../../../../common/lib/kibana'); +jest.mock( + '../../../../detection_engine/rule_management/api/hooks/use_fetch_prebuilt_rules_status_query' +); describe('UpdatePrePackagedRulesCallOut', () => { beforeAll(() => { @@ -28,105 +33,134 @@ describe('UpdatePrePackagedRulesCallOut', () => { }); }); - it('renders correctly', () => { - const wrapper = shallow( - - ); - - expect(wrapper.find('EuiCallOut')).toHaveLength(1); - }); - it('renders callOutMessage correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines = 0', () => { - const wrapper = shallow( - + (useFetchPrebuiltRulesStatusQuery as jest.Mock).mockReturnValue( + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 1, + timelines_updated: 0, + timelines_not_installed: 0, + timelines_not_updated: 0, + }, + }) ); - expect(wrapper.find('[data-test-subj="update-callout"]').find('p').text()).toEqual( + const { getByTestId } = render(, { wrapper: TestProviders }); + + expect(getByTestId('update-callout')).toHaveTextContent( 'You can update 1 Elastic prebuilt ruleRelease notes' ); }); it('renders buttonTitle correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines = 0', () => { - const wrapper = shallow( - + (useFetchPrebuiltRulesStatusQuery as jest.Mock).mockReturnValue( + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 1, + timelines_updated: 0, + timelines_not_installed: 0, + timelines_not_updated: 0, + }, + }) ); - expect(wrapper.find('[data-test-subj="update-callout-button"]').prop('children')).toEqual( + const { getByTestId } = render(, { wrapper: TestProviders }); + + expect(getByTestId('update-callout-button')).toHaveTextContent( 'Update 1 Elastic prebuilt rule' ); }); it('renders callOutMessage correctly: numberOfUpdatedRules = 0 and numberOfUpdatedTimelines > 0', () => { - const wrapper = shallow( - + (useFetchPrebuiltRulesStatusQuery as jest.Mock).mockReturnValue( + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 0, + timelines_updated: 0, + timelines_not_installed: 0, + timelines_not_updated: 1, + }, + }) ); - expect(wrapper.find('[data-test-subj="update-callout"]').find('p').text()).toEqual( + const { getByTestId } = render(, { wrapper: TestProviders }); + + expect(getByTestId('update-callout')).toHaveTextContent( 'You can update 1 Elastic prebuilt timelineRelease notes' ); }); it('renders buttonTitle correctly: numberOfUpdatedRules = 0 and numberOfUpdatedTimelines > 0', () => { - const wrapper = shallow( - + (useFetchPrebuiltRulesStatusQuery as jest.Mock).mockReturnValue( + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 0, + timelines_updated: 0, + timelines_not_installed: 0, + timelines_not_updated: 1, + }, + }) ); - expect(wrapper.find('[data-test-subj="update-callout-button"]').prop('children')).toEqual( + const { getByTestId } = render(, { wrapper: TestProviders }); + + expect(getByTestId('update-callout-button')).toHaveTextContent( 'Update 1 Elastic prebuilt timeline' ); }); it('renders callOutMessage correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines > 0', () => { - const wrapper = shallow( - + (useFetchPrebuiltRulesStatusQuery as jest.Mock).mockReturnValue( + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 1, + timelines_updated: 0, + timelines_not_installed: 0, + timelines_not_updated: 1, + }, + }) ); - expect(wrapper.find('[data-test-subj="update-callout"]').find('p').text()).toEqual( + const { getByTestId } = render(, { wrapper: TestProviders }); + + expect(getByTestId('update-callout')).toHaveTextContent( 'You can update 1 Elastic prebuilt rule and 1 Elastic prebuilt timeline. Note that this will reload deleted Elastic prebuilt rules.Release notes' ); }); it('renders buttonTitle correctly: numberOfUpdatedRules > 0 and numberOfUpdatedTimelines > 0', () => { - const wrapper = shallow( - + (useFetchPrebuiltRulesStatusQuery as jest.Mock).mockReturnValue( + mockReactQueryResponse({ + data: { + rules_custom_installed: 0, + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 1, + timelines_updated: 0, + timelines_not_installed: 0, + timelines_not_updated: 1, + }, + }) ); - expect(wrapper.find('[data-test-subj="update-callout-button"]').prop('children')).toEqual( + const { getByTestId } = render(, { wrapper: TestProviders }); + + expect(getByTestId('update-callout-button')).toHaveTextContent( 'Update 1 Elastic prebuilt rule and 1 Elastic prebuilt timeline' ); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx index 9d67a1e6b9ae8..1526c211990e3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/pre_packaged_rules/update_callout.tsx @@ -5,51 +5,42 @@ * 2.0. */ +import { EuiButton, EuiCallOut, EuiLink } from '@elastic/eui'; import React, { memo, useMemo } from 'react'; - -import { EuiCallOut, EuiButton, EuiLink } from '@elastic/eui'; - import { useKibana } from '../../../../common/lib/kibana'; +import { usePrePackagedRulesStatus } from '../../../../detection_engine/rule_management/logic/use_pre_packaged_rules_status'; +import { LoadPrePackagedRules } from './load_prepackaged_rules'; import * as i18n from './translations'; -interface UpdatePrePackagedRulesCallOutProps { - loading: boolean; - numberOfUpdatedRules: number; - numberOfUpdatedTimelines: number; - updateRules: () => void; -} - -const UpdatePrePackagedRulesCallOutComponent: React.FC = ({ - loading, - numberOfUpdatedRules, - numberOfUpdatedTimelines, - updateRules, -}) => { +const UpdatePrePackagedRulesCallOutComponent = () => { const { services } = useKibana(); + const { data: prePackagedRulesStatus } = usePrePackagedRulesStatus(); + const rulesNotUpdated = prePackagedRulesStatus?.rules_not_updated ?? 0; + const timelinesNotUpdated = prePackagedRulesStatus?.timelines_not_updated ?? 0; const prepackagedRulesOrTimelines = useMemo(() => { - if (numberOfUpdatedRules > 0 && numberOfUpdatedTimelines === 0) { + if (rulesNotUpdated > 0 && timelinesNotUpdated === 0) { return { - callOutMessage: i18n.UPDATE_PREPACKAGED_RULES_MSG(numberOfUpdatedRules), - buttonTitle: i18n.UPDATE_PREPACKAGED_RULES(numberOfUpdatedRules), + callOutMessage: i18n.UPDATE_PREPACKAGED_RULES_MSG(rulesNotUpdated), + buttonTitle: i18n.UPDATE_PREPACKAGED_RULES(rulesNotUpdated), }; - } else if (numberOfUpdatedRules === 0 && numberOfUpdatedTimelines > 0) { + } else if (rulesNotUpdated === 0 && timelinesNotUpdated > 0) { return { - callOutMessage: i18n.UPDATE_PREPACKAGED_TIMELINES_MSG(numberOfUpdatedTimelines), - buttonTitle: i18n.UPDATE_PREPACKAGED_TIMELINES(numberOfUpdatedTimelines), + callOutMessage: i18n.UPDATE_PREPACKAGED_TIMELINES_MSG(timelinesNotUpdated), + buttonTitle: i18n.UPDATE_PREPACKAGED_TIMELINES(timelinesNotUpdated), }; - } else if (numberOfUpdatedRules > 0 && numberOfUpdatedTimelines > 0) + } else if (rulesNotUpdated > 0 && timelinesNotUpdated > 0) return { callOutMessage: i18n.UPDATE_PREPACKAGED_RULES_AND_TIMELINES_MSG( - numberOfUpdatedRules, - numberOfUpdatedTimelines + rulesNotUpdated, + timelinesNotUpdated ), buttonTitle: i18n.UPDATE_PREPACKAGED_RULES_AND_TIMELINES( - numberOfUpdatedRules, - numberOfUpdatedTimelines + rulesNotUpdated, + timelinesNotUpdated ), }; - }, [numberOfUpdatedRules, numberOfUpdatedTimelines]); + }, [rulesNotUpdated, timelinesNotUpdated]); return ( @@ -60,14 +51,13 @@ const UpdatePrePackagedRulesCallOutComponent: React.FC

- - {prepackagedRulesOrTimelines?.buttonTitle} - + + {(renderProps) => ( + + {prepackagedRulesOrTimelines?.buttonTitle} + + )} +
); }; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integration_details.ts b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integration_details.ts index b8475f7a0e9af..361e542fa3f0f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integration_details.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integration_details.ts @@ -7,12 +7,15 @@ import { capitalize } from 'lodash'; import semver from 'semver'; + import type { InstalledIntegration, InstalledIntegrationArray, +} from '../../../../../common/detection_engine/fleet_integrations'; +import type { RelatedIntegration, RelatedIntegrationArray, -} from '../../../../../common/detection_engine/schemas/common'; +} from '../../../../../common/detection_engine/rule_schema'; export interface IntegrationDetails { packageName: string; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_description/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_description/index.tsx index 5932faf1de6f0..5640abea69cc3 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_description/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_description/index.tsx @@ -8,7 +8,7 @@ import React from 'react'; import styled from 'styled-components'; -import type { RelatedIntegrationArray } from '../../../../../../common/detection_engine/schemas/common'; +import type { RelatedIntegrationArray } from '../../../../../../common/detection_engine/rule_schema'; import type { ListItems } from '../../description_step/types'; import type { IntegrationDetails } from '../integration_details'; import { useRelatedIntegrations } from '../use_related_integrations'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_popover/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_popover/index.tsx index 6c17b182381ca..36fc206aa92ea 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_popover/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/integrations_popover/index.tsx @@ -16,7 +16,7 @@ import { EuiSpacer, } from '@elastic/eui'; -import type { RelatedIntegrationArray } from '../../../../../../common/detection_engine/schemas/common'; +import type { RelatedIntegrationArray } from '../../../../../../common/detection_engine/rule_schema'; import { IntegrationDescription } from '../integrations_description'; import { useRelatedIntegrations } from '../use_related_integrations'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/mock.ts b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/mock.ts index 786e33ad69293..43a0c8a0602ef 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/mock.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/mock.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RelatedIntegrationArray } from '../../../../../common/detection_engine/schemas/common'; +import type { RelatedIntegrationArray } from '../../../../../common/detection_engine/rule_schema'; export const relatedIntegrations: RelatedIntegrationArray = [ { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx index 705c7f5f3fbd3..d1322fd76a91f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.test.tsx @@ -5,18 +5,18 @@ * 2.0. */ -jest.mock('../../../containers/detection_engine/rules/api'); -jest.mock('../../../../common/lib/kibana'); - import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { renderHook, cleanup } from '@testing-library/react-hooks'; import { useInstalledIntegrations } from './use_installed_integrations'; -import * as api from '../../../containers/detection_engine/rules/api'; +import { fleetIntegrationsApi } from '../../../../detection_engine/fleet_integrations/api'; import { useToasts } from '../../../../common/lib/kibana'; +jest.mock('../../../../detection_engine/fleet_integrations/api'); +jest.mock('../../../../common/lib/kibana'); + describe('useInstalledIntegrations', () => { beforeEach(() => { jest.clearAllMocks(); @@ -53,7 +53,10 @@ describe('useInstalledIntegrations', () => { ); it('calls the API via fetchInstalledIntegrations', async () => { - const fetchInstalledIntegrations = jest.spyOn(api, 'fetchInstalledIntegrations'); + const fetchInstalledIntegrations = jest.spyOn( + fleetIntegrationsApi, + 'fetchInstalledIntegrations' + ); const { waitForNextUpdate } = render(); @@ -101,7 +104,7 @@ describe('useInstalledIntegrations', () => { // Skipping until we re-enable errors it.skip('handles exceptions from the API', async () => { const exception = new Error('Boom!'); - jest.spyOn(api, 'fetchInstalledIntegrations').mockRejectedValue(exception); + jest.spyOn(fleetIntegrationsApi, 'fetchInstalledIntegrations').mockRejectedValue(exception); const { result, waitForNextUpdate } = render(); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx index 734ef6e628214..c94404bb5cdc7 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_installed_integrations.tsx @@ -6,8 +6,9 @@ */ import { useQuery } from '@tanstack/react-query'; -import type { InstalledIntegrationArray } from '../../../../../common/detection_engine/schemas/common'; -import { fetchInstalledIntegrations } from '../../../containers/detection_engine/rules/api'; + +import type { InstalledIntegrationArray } from '../../../../../common/detection_engine/fleet_integrations'; +import { fleetIntegrationsApi } from '../../../../detection_engine/fleet_integrations'; // import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; // import * as i18n from './translations'; @@ -28,7 +29,7 @@ export const useInstalledIntegrations = ({ packages }: UseInstalledIntegrationsA }, ], async ({ signal }) => { - const integrations = await fetchInstalledIntegrations({ + const integrations = await fleetIntegrationsApi.fetchInstalledIntegrations({ packages, signal, }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_related_integrations.ts b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_related_integrations.ts index 3363abf2fe3c7..19e662746638a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_related_integrations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/related_integrations/use_related_integrations.ts @@ -7,7 +7,7 @@ import { useMemo } from 'react'; -import type { RelatedIntegrationArray } from '../../../../../common/detection_engine/schemas/common'; +import type { RelatedIntegrationArray } from '../../../../../common/detection_engine/rule_schema'; import type { IntegrationDetails } from './integration_details'; import { calculateIntegrationDetails } from './integration_details'; import { useInstalledIntegrations } from './use_installed_integrations'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx index ea5aac0bcae26..177fd2e97e6cd 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/risk_score_mapping/index.tsx @@ -5,6 +5,9 @@ * 2.0. */ +import React, { useCallback, useMemo } from 'react'; +import styled from 'styled-components'; +import { noop } from 'lodash/fp'; import { EuiFormRow, EuiCheckbox, @@ -16,15 +19,14 @@ import { EuiSpacer, EuiRange, } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; -import styled from 'styled-components'; -import { noop } from 'lodash/fp'; -import type { RiskScoreMapping } from '@kbn/securitysolution-io-ts-alerting-types'; -import { FieldComponent } from '@kbn/securitysolution-autocomplete'; + import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -import * as i18n from './translations'; +import { FieldComponent } from '@kbn/securitysolution-autocomplete'; +import type { RiskScoreMapping } from '@kbn/securitysolution-io-ts-alerting-types'; + import type { AboutStepRiskScore } from '../../../pages/detection_engine/rules/types'; +import * as i18n from './translations'; const NestedContent = styled.div` margin-left: 24px; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap deleted file mode 100644 index 2cbd090e87733..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,74 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`RuleActionsOverflow snapshots renders correctly against snapshot 1`] = ` - - - - - } - closePopover={[Function]} - data-test-subj="rules-details-popover" - display="inline-block" - hasArrow={true} - id="ruleActionsOverflow" - isOpen={false} - ownFocus={true} - panelPaddingSize="none" - repositionOnScroll={true} - > - - - - Duplicate rule - - - , - - Export rule - , - - Delete rule - , - ] - } - /> - - -`; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx index 8b736bad37b92..ce265ffb8382c 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.test.tsx @@ -5,17 +5,20 @@ * 2.0. */ -import { shallow, mount } from 'enzyme'; +import { render, fireEvent } from '@testing-library/react'; import React from 'react'; -import { - goToRuleEditPage, - executeRulesBulkAction, - bulkExportRules, -} from '../../../pages/detection_engine/rules/all/actions'; +import { useBulkExport } from '../../../../detection_engine/rule_management/logic/bulk_actions/use_bulk_export'; +import { useExecuteBulkAction } from '../../../../detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action'; + import { RuleActionsOverflow } from '.'; -import { mockRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +import { mockRule } from '../../../../detection_engine/rule_management_ui/components/rules_table/__mocks__/mock'; +import { TestProviders } from '../../../../common/mock'; +jest.mock( + '../../../../detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action' +); +jest.mock('../../../../detection_engine/rule_management/logic/bulk_actions/use_bulk_export'); jest.mock('../../../../common/lib/apm/use_start_transaction'); jest.mock('../../../../common/hooks/use_app_toasts'); jest.mock('../../../../common/lib/kibana', () => { @@ -31,12 +34,9 @@ jest.mock('../../../../common/lib/kibana', () => { }), }; }); -jest.mock('../../../pages/detection_engine/rules/all/actions'); - -const executeRulesBulkActionMock = executeRulesBulkAction as jest.Mock; -const bulkExportRulesMock = bulkExportRules as jest.Mock; -const flushPromises = () => new Promise(setImmediate); +const useExecuteBulkActionMock = useExecuteBulkAction as jest.Mock; +const useBulkExportMock = useBulkExport as jest.Mock; describe('RuleActionsOverflow', () => { afterEach(() => { @@ -46,328 +46,189 @@ describe('RuleActionsOverflow', () => { jest.resetAllMocks(); }); - describe('snapshots', () => { - test('renders correctly against snapshot', () => { - const wrapper = shallow( - - ); - expect(wrapper).toMatchSnapshot(); - }); - }); - describe('rules details menu panel', () => { - test('there is at least one item when there is a rule within the rules-details-menu-panel', () => { - const wrapper = mount( + test('menu items rendered when a rule is passed to the component', () => { + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - const items: unknown[] = wrapper - .find('[data-test-subj="rules-details-menu-panel"]') - .first() - .prop('items'); - - expect(items.length).toBeGreaterThan(0); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + expect(getByTestId('rules-details-menu-panel')).toHaveTextContent('Duplicate rule'); + expect(getByTestId('rules-details-menu-panel')).toHaveTextContent('Export rule'); + expect(getByTestId('rules-details-menu-panel')).toHaveTextContent('Delete rule'); }); - test('items are empty when there is a null rule within the rules-details-menu-panel', () => { - const wrapper = mount( - + test('menu is empty when no rule is passed to the component', () => { + const { getByTestId } = render( + , + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-menu-panel"]').first().prop('items') - ).toEqual([]); - }); - - test('items are empty when there is an undefined rule within the rules-details-menu-panel', () => { - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-menu-panel"]').first().prop('items') - ).toEqual([]); - }); - - test('it opens the popover when rules-details-popover-button-icon is clicked', () => { - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(true); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + expect(getByTestId('rules-details-menu-panel')).not.toHaveTextContent(/.+/); }); }); describe('rules details pop over button icon', () => { test('it does not open the popover when rules-details-popover-button-icon is clicked when the user does not have permission', () => { - const wrapper = mount( + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(false); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + + expect(getByTestId('rules-details-popover')).not.toHaveTextContent(/.+/); }); }); describe('rules details duplicate rule', () => { - test('it does not open the popover when rules-details-popover-button-icon is clicked and the user does not have permission', () => { - const rule = mockRule('id'); - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect(wrapper.find('[data-test-subj="rules-details-delete-rule"] button').exists()).toEqual( - false - ); - }); - - test('it opens the popover when rules-details-popover-button-icon is clicked', () => { - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(true); - }); - test('it closes the popover when rules-details-duplicate-rule is clicked', () => { - const wrapper = mount( + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-duplicate-rule"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(false); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-duplicate-rule')); + + expect(getByTestId('rules-details-popover')).not.toHaveTextContent(/.+/); }); test('it calls duplicate action when rules-details-duplicate-rule is clicked', () => { - const wrapper = mount( + const executeBulkAction = jest.fn(); + useExecuteBulkActionMock.mockReturnValue({ executeBulkAction }); + + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-duplicate-rule"] button').simulate('click'); - wrapper.update(); - expect(executeRulesBulkAction).toHaveBeenCalledWith( + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-duplicate-rule')); + + expect(executeBulkAction).toHaveBeenCalledWith( expect.objectContaining({ action: 'duplicate' }) ); }); test('it calls duplicate action with the rule and rule.id when rules-details-duplicate-rule is clicked', () => { - const rule = mockRule('id'); - const wrapper = mount( - + const executeBulkAction = jest.fn(); + useExecuteBulkActionMock.mockReturnValue({ executeBulkAction }); + + const { getByTestId } = render( + , + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-duplicate-rule"] button').simulate('click'); - wrapper.update(); - expect(executeRulesBulkAction).toHaveBeenCalledWith( + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-duplicate-rule')); + + expect(executeBulkAction).toHaveBeenCalledWith( expect.objectContaining({ action: 'duplicate', search: { ids: ['id'] } }) ); }); }); - test('it navigates to edit page after the rule is duplicated', async () => { - const rule = mockRule('id'); - const ruleDuplicate = mockRule('newRule'); - executeRulesBulkActionMock.mockImplementation(() => - Promise.resolve({ attributes: { results: { created: [ruleDuplicate] } } }) - ); - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-duplicate-rule"] button').simulate('click'); - wrapper.update(); - await flushPromises(); - - expect(executeRulesBulkAction).toHaveBeenCalledWith( - expect.objectContaining({ action: 'duplicate' }) - ); - expect(goToRuleEditPage).toHaveBeenCalledWith(ruleDuplicate.id, expect.anything()); - }); - describe('rules details export rule', () => { test('should call export actions and display toast when export option is clicked', async () => { - bulkExportRulesMock.mockImplementation(() => Promise.resolve({})); - const wrapper = mount( + const bulkExport = jest.fn(); + useBulkExportMock.mockReturnValue({ bulkExport }); + + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-export-rule"] button').simulate('click'); - wrapper.update(); - await flushPromises(); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-export-rule')); - expect(bulkExportRulesMock).toHaveBeenCalledWith( - expect.objectContaining({ action: 'export' }) - ); - expect(bulkExportRulesMock).toHaveBeenCalledWith( - expect.not.objectContaining({ onSuccess: expect.any }) - ); - }); - test('it does not open the popover when rules-details-popover-button-icon is clicked and the user does not have permission', () => { - const rule = mockRule('id'); - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect(wrapper.find('[data-test-subj="rules-details-export-rule"] button').exists()).toEqual( - false - ); + expect(bulkExport).toHaveBeenCalled(); }); test('it closes the popover when rules-details-export-rule is clicked', () => { - const wrapper = mount( + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-export-rule"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(false); - }); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-export-rule')); - test('it does not close the pop over on rules-details-export-rule when the rule is an immutable rule and the user does a click', () => { - const rule = mockRule('id'); - rule.immutable = true; - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-export-rule"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(true); + // Popover is not shown + expect(getByTestId('rules-details-popover')).not.toHaveTextContent(/.+/); }); }); describe('rules details delete rule', () => { - test('it does not open the popover when rules-details-popover-button-icon is clicked and the user does not have permission', () => { - const rule = mockRule('id'); - const wrapper = mount( - - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - expect(wrapper.find('[data-test-subj="rules-details-delete-rule"] button').exists()).toEqual( - false - ); - }); - test('it closes the popover when rules-details-delete-rule is clicked', () => { - const wrapper = mount( + const { getByTestId } = render( + />, + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-delete-rule"] button').simulate('click'); - wrapper.update(); - expect( - wrapper.find('[data-test-subj="rules-details-popover"]').first().prop('isOpen') - ).toEqual(false); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-delete-rule')); + + // Popover is not shown + expect(getByTestId('rules-details-popover')).not.toHaveTextContent(/.+/); }); test('it calls deleteRulesAction when rules-details-delete-rule is clicked', () => { - const wrapper = mount( + const executeBulkAction = jest.fn(); + useExecuteBulkActionMock.mockReturnValue({ executeBulkAction }); + + const { getByTestId } = render( - ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-delete-rule"] button').simulate('click'); - wrapper.update(); - expect(executeRulesBulkAction).toHaveBeenCalledWith( - expect.objectContaining({ action: 'delete' }) + />, + { wrapper: TestProviders } ); + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-delete-rule')); + + expect(executeBulkAction).toHaveBeenCalledWith(expect.objectContaining({ action: 'delete' })); }); test('it calls deleteRulesAction with the rule.id when rules-details-delete-rule is clicked', () => { + const executeBulkAction = jest.fn(); + useExecuteBulkActionMock.mockReturnValue({ executeBulkAction }); + const rule = mockRule('id'); - const wrapper = mount( - + const { getByTestId } = render( + , + { wrapper: TestProviders } ); - wrapper.find('[data-test-subj="rules-details-popover-button-icon"] button').simulate('click'); - wrapper.update(); - wrapper.find('[data-test-subj="rules-details-delete-rule"] button').simulate('click'); - wrapper.update(); - expect(executeRulesBulkAction).toHaveBeenCalledWith( + fireEvent.click(getByTestId('rules-details-popover-button-icon')); + fireEvent.click(getByTestId('rules-details-delete-rule')); + + expect(executeBulkAction).toHaveBeenCalledWith( expect.objectContaining({ action: 'delete', search: { ids: ['id'] } }) ); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx index 404319ef75832..c2fc45d53e1d6 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx @@ -16,7 +16,7 @@ import { noop } from 'lodash'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { APP_UI_ID, SecurityPageName } from '../../../../../common/constants'; -import { BulkAction } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { getRulesUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useBoolState } from '../../../../common/hooks/use_bool_state'; @@ -24,12 +24,15 @@ import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; import { useKibana } from '../../../../common/lib/kibana'; import { canEditRuleWithActions } from '../../../../common/utils/privileges'; -import type { Rule } from '../../../containers/detection_engine/rules'; +import type { Rule } from '../../../../detection_engine/rule_management/logic'; +import { + downloadExportedRules, + useBulkExport, +} from '../../../../detection_engine/rule_management/logic/bulk_actions/use_bulk_export'; import { - executeRulesBulkAction, goToRuleEditPage, - bulkExportRules, -} from '../../../pages/detection_engine/rules/all/actions'; + useExecuteBulkAction, +} from '../../../../detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action'; import * as i18nActions from '../../../pages/detection_engine/rules/translations'; import * as i18n from './translations'; @@ -62,6 +65,8 @@ const RuleActionsOverflowComponent = ({ const { navigateToApp } = useKibana().services.application; const toasts = useAppToasts(); const { startTransaction } = useStartTransaction(); + const { executeBulkAction } = useExecuteBulkAction(); + const { bulkExport } = useBulkExport(); const onRuleDeletedCallback = useCallback(() => { navigateToApp(APP_UI_ID, { @@ -82,11 +87,10 @@ const RuleActionsOverflowComponent = ({ onClick={async () => { startTransaction({ name: SINGLE_RULE_ACTIONS.DUPLICATE }); closePopover(); - const result = await executeRulesBulkAction({ + const result = await executeBulkAction({ action: BulkAction.duplicate, onSuccess: noop, search: { ids: [rule.id] }, - toasts, }); const createdRules = result?.attributes.results.created; if (createdRules?.length) { @@ -113,11 +117,13 @@ const RuleActionsOverflowComponent = ({ onClick={async () => { startTransaction({ name: SINGLE_RULE_ACTIONS.EXPORT }); closePopover(); - await bulkExportRules({ - action: BulkAction.export, - search: { ids: [rule.id] }, - toasts, - }); + const response = await bulkExport({ search: { ids: [rule.id] } }); + if (response) { + await downloadExportedRules({ + response, + toasts, + }); + } }} > {i18nActions.EXPORT_RULE} @@ -130,11 +136,10 @@ const RuleActionsOverflowComponent = ({ onClick={async () => { startTransaction({ name: SINGLE_RULE_ACTIONS.DELETE }); closePopover(); - await executeRulesBulkAction({ + await executeBulkAction({ action: BulkAction.delete, onSuccess: onRuleDeletedCallback, search: { ids: [rule.id] }, - toasts, }); }} > @@ -143,8 +148,10 @@ const RuleActionsOverflowComponent = ({ ] : [], [ + bulkExport, canDuplicateRuleWithActions, closePopover, + executeBulkAction, navigateToApp, onRuleDeletedCallback, rule, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_logs.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_logs.tsx index 8249f60f20869..3d72986a100dd 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_logs.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/preview_logs.tsx @@ -7,7 +7,7 @@ import React, { Fragment, useMemo } from 'react'; import { EuiCallOut, EuiText, EuiSpacer, EuiAccordion } from '@elastic/eui'; -import type { RulePreviewLogs } from '../../../../../common/detection_engine/schemas/request'; +import type { RulePreviewLogs } from '../../../../../common/detection_engine/rule_schema'; import * as i18n from './translations'; interface PreviewLogsComponentProps { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_invocation_count.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_invocation_count.ts index fa6cb82980832..ef61f7dd37c13 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_invocation_count.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_invocation_count.ts @@ -8,7 +8,7 @@ import moment from 'moment'; import type { TimeframePreviewOptions } from '../../../pages/detection_engine/rules/types'; -import { getTimeTypeValue } from '../../../pages/detection_engine/rules/create/helpers'; +import { getTimeTypeValue } from '../../../../detection_engine/rule_creation_ui/pages/rule_creation/helpers'; export const usePreviewInvocationCount = ({ timeframeOptions, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx index f6dbe68f07882..a1ccd3472bb75 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_route.tsx @@ -8,8 +8,8 @@ import { useEffect, useState, useCallback } from 'react'; import type { List } from '@kbn/securitysolution-io-ts-list-types'; import { usePreviewRule } from './use_preview_rule'; -import { formatPreviewRule } from '../../../pages/detection_engine/rules/create/helpers'; -import type { RulePreviewLogs } from '../../../../../common/detection_engine/schemas/request'; +import { formatPreviewRule } from '../../../../detection_engine/rule_creation_ui/pages/rule_creation/helpers'; +import type { RulePreviewLogs } from '../../../../../common/detection_engine/rule_schema'; import type { AboutStepRule, DefineStepRule, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_rule.ts b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_rule.ts index 349eaa8c5dd80..17d47008e77bc 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_rule.ts +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_preview/use_preview_rule.ts @@ -10,11 +10,11 @@ import { useEffect, useMemo, useState } from 'react'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import type { PreviewResponse, - CreateRulesSchema, -} from '../../../../../common/detection_engine/schemas/request'; + RuleCreateProps, +} from '../../../../../common/detection_engine/rule_schema'; -import { previewRule } from '../../../containers/detection_engine/rules/api'; -import * as i18n from '../../../containers/detection_engine/rules/translations'; +import { previewRule } from '../../../../detection_engine/rule_management/api/api'; +import * as i18n from '../../../../detection_engine/rule_management/logic/translations'; import { transformOutput } from '../../../containers/detection_engine/rules/transforms'; import type { TimeframePreviewOptions } from '../../../pages/detection_engine/rules/types'; import { usePreviewInvocationCount } from './use_preview_invocation_count'; @@ -30,7 +30,7 @@ export const usePreviewRule = ({ }: { timeframeOptions: TimeframePreviewOptions; }) => { - const [rule, setRule] = useState(null); + const [rule, setRule] = useState(null); const [response, setResponse] = useState(emptyPreviewRule); const [isLoading, setIsLoading] = useState(false); const { addError } = useAppToasts(); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx index 6580d8955ae2f..9989cd76b09c9 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.test.tsx @@ -9,18 +9,20 @@ import { mount } from 'enzyme'; import React from 'react'; import { waitFor } from '@testing-library/react'; -import { performBulkAction } from '../../../containers/detection_engine/rules'; +import { performBulkAction } from '../../../../detection_engine/rule_management/api/api'; import { RuleSwitchComponent } from '.'; -import { getRulesSchemaMock } from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import { useRulesTableContextOptional } from '../../../pages/detection_engine/rules/all/rules_table/rules_table_context'; -import { useRulesTableContextMock } from '../../../pages/detection_engine/rules/all/rules_table/__mocks__/rules_table_context'; +import { getRulesSchemaMock } from '../../../../../common/detection_engine/rule_schema/mocks'; +import { useRulesTableContextOptional } from '../../../../detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context'; +import { useRulesTableContextMock } from '../../../../detection_engine/rule_management_ui/components/rules_table/rules_table/__mocks__/rules_table_context'; import { TestProviders } from '../../../../common/mock'; import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; jest.mock('../../../../common/hooks/use_app_toasts'); -jest.mock('../../../containers/detection_engine/rules'); -jest.mock('../../../pages/detection_engine/rules/all/rules_table/rules_table_context'); +jest.mock('../../../../detection_engine/rule_management/api/api'); +jest.mock( + '../../../../detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context' +); jest.mock('../../../../common/lib/apm/use_start_transaction'); const useAppToastsValueMock = useAppToastsMock.create(); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx index 6c924a68da4a1..bcd0e74d6ef9f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_switch/index.tsx @@ -10,13 +10,11 @@ import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiSwitch } from '@elasti import { noop } from 'lodash'; import React, { useCallback, useMemo, useState } from 'react'; import styled from 'styled-components'; -import { BulkAction } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; +import { BulkAction } from '../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; -import { useUpdateRulesCache } from '../../../containers/detection_engine/rules/use_find_rules_query'; -import { executeRulesBulkAction } from '../../../pages/detection_engine/rules/all/actions'; -import { useRulesTableContextOptional } from '../../../pages/detection_engine/rules/all/rules_table/rules_table_context'; +import { useExecuteBulkAction } from '../../../../detection_engine/rule_management/logic/bulk_actions/use_execute_bulk_action'; +import { useRulesTableContextOptional } from '../../../../detection_engine/rule_management_ui/components/rules_table/rules_table/rules_table_context'; const StaticSwitch = styled(EuiSwitch)` .euiSwitch__thumb, @@ -47,9 +45,8 @@ export const RuleSwitchComponent = ({ }: RuleSwitchProps) => { const [myIsLoading, setMyIsLoading] = useState(false); const rulesTableContext = useRulesTableContextOptional(); - const updateRulesCache = useUpdateRulesCache(); - const toasts = useAppToasts(); const { startTransaction } = useStartTransaction(); + const { executeBulkAction } = useExecuteBulkAction(); const onRuleStateChange = useCallback( async (event: EuiSwitchEvent) => { @@ -57,9 +54,8 @@ export const RuleSwitchComponent = ({ startTransaction({ name: enabled ? SINGLE_RULE_ACTIONS.DISABLE : SINGLE_RULE_ACTIONS.ENABLE, }); - const bulkActionResponse = await executeRulesBulkAction({ + const bulkActionResponse = await executeBulkAction({ setLoadingRules: rulesTableContext?.actions.setLoadingRules, - toasts, onSuccess: rulesTableContext ? undefined : noop, action: event.target.checked ? BulkAction.enable : BulkAction.disable, search: { ids: [id] }, @@ -67,12 +63,11 @@ export const RuleSwitchComponent = ({ }); if (bulkActionResponse?.attributes.results.updated.length) { // The rule was successfully updated - updateRulesCache(bulkActionResponse.attributes.results.updated); onChange?.(bulkActionResponse.attributes.results.updated[0].enabled); } setMyIsLoading(false); }, - [enabled, id, onChange, rulesTableContext, startTransaction, toasts, updateRulesCache] + [enabled, executeBulkAction, id, onChange, rulesTableContext, startTransaction] ); const showLoader = useMemo((): boolean => { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/severity_badge/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/severity_badge/index.tsx index af746d158e2a7..9f3e6c927de83 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/severity_badge/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/severity_badge/index.tsx @@ -5,10 +5,11 @@ * 2.0. */ -import { upperFirst } from 'lodash/fp'; import React from 'react'; +import { upperFirst } from 'lodash/fp'; import { euiLightVars } from '@kbn/ui-theme'; import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; + import { HealthTruncateText } from '../../../../common/components/health_truncate_text'; const { euiColorVis0, euiColorVis5, euiColorVis7, euiColorVis9 } = euiLightVars; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx index 961620d1521c4..aeefb4091307e 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/severity_mapping/index.tsx @@ -19,22 +19,23 @@ import { import { noop } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; + +import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; +import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; +import { + FieldComponent, + AutocompleteFieldMatchComponent, +} from '@kbn/securitysolution-autocomplete'; import type { Severity, SeverityMapping, SeverityMappingItem, } from '@kbn/securitysolution-io-ts-alerting-types'; -import { - FieldComponent, - AutocompleteFieldMatchComponent, -} from '@kbn/securitysolution-autocomplete'; -import type { DataViewBase, DataViewFieldBase } from '@kbn/es-query'; -import type { FieldHook } from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib'; -import * as i18n from './translations'; import type { SeverityOptionItem } from '../step_about_rule/data'; import type { AboutStepSeverity } from '../../../pages/detection_engine/rules/types'; import { useKibana } from '../../../../common/lib/kibana'; +import * as i18n from './translations'; const NestedContent = styled.div` margin-left: 24px; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/data.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/data.tsx index d0d471e3a727b..bab334b1c7f1f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/data.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/data.tsx @@ -5,11 +5,10 @@ * 2.0. */ +import React from 'react'; import styled from 'styled-components'; import { EuiHealth } from '@elastic/eui'; import { euiLightVars } from '@kbn/ui-theme'; -import React from 'react'; - import type { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import * as I18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx index 4c3f635069c0f..5c5554b72ad8a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.test.tsx @@ -13,7 +13,7 @@ import { stubIndexPattern } from '@kbn/data-plugin/common/stubs'; import { StepAboutRule } from '.'; import { useFetchIndex } from '../../../../common/containers/source'; import { useGetInstalledJob } from '../../../../common/components/ml/hooks/use_get_jobs'; -import { mockAboutStepRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +import { mockAboutStepRule } from '../../../../detection_engine/rule_management_ui/components/rules_table/__mocks__/mock'; import { StepRuleDescription } from '../description_step'; import { stepAboutDefaultValue } from './default_value'; import type { diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx index 34303c00e5153..22c9670e3bed8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule/index.tsx @@ -44,7 +44,7 @@ import { AutocompleteField } from '../autocomplete_field'; import { useFetchIndex } from '../../../../common/containers/source'; import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../common/constants'; import { useKibana } from '../../../../common/lib/kibana'; -import { useRuleIndices } from '../../../containers/detection_engine/rules/use_rule_indices'; +import { useRuleIndices } from '../../../../detection_engine/rule_management/logic/use_rule_indices'; const CommonUseField = getUseField({ component: Field }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.test.tsx index cafbc1f173f0b..ae46ccef9e859 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_about_rule_details/index.test.tsx @@ -11,7 +11,7 @@ import { EuiProgress, EuiButtonGroup } from '@elastic/eui'; import { ThemeProvider } from 'styled-components'; import { StepAboutRuleToggleDetails } from '.'; -import { mockAboutStepRule } from '../../../pages/detection_engine/rules/all/__mocks__/mock'; +import { mockAboutStepRule } from '../../../../detection_engine/rule_management_ui/components/rules_table/__mocks__/mock'; import { HeaderSection } from '../../../../common/components/header_section'; import { StepAboutRule } from '../step_about_rule'; import type { AboutStepRule } from '../../../pages/detection_engine/rules/types'; diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index 1dd2a2d1de798..dc926fd4f74e2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -36,7 +36,7 @@ import type { EqlOptionsSelected, FieldsEqlOptions } from '../../../../../common import { filterRuleFieldsForType, getStepDataDataSource, -} from '../../../pages/detection_engine/rules/create/helpers'; +} from '../../../../detection_engine/rule_creation_ui/pages/rule_creation/helpers'; import type { DefineStepRule, RuleStepProps } from '../../../pages/detection_engine/rules/types'; import { RuleStep, DataSourceType } from '../../../pages/detection_engine/rules/types'; import { StepRuleDescription } from '../description_step'; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts index 2b280786e2905..060f36f5bb5c8 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/exceptions/get_es_query_filter.ts @@ -13,14 +13,17 @@ import { buildEsQuery } from '@kbn/es-query'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { KibanaServices } from '../../../../common/lib/kibana'; -import type { Query, Index } from '../../../../../common/detection_engine/schemas/common'; +import type { + IndexPatternArray, + RuleQuery, +} from '../../../../../common/detection_engine/rule_schema'; import type { ESBoolQuery } from '../../../../../common/typed_json'; export const getEsQueryFilter = async ( - query: Query, + query: RuleQuery, language: Language, filters: unknown, - index: Index, + index: IndexPatternArray, lists: ExceptionListItemSchema[], excludeExceptions: boolean = true ): Promise => { diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/transforms.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/transforms.ts index ab4d1eedbd2ae..a78191913562a 100644 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/transforms.ts +++ b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/transforms.ts @@ -8,10 +8,10 @@ import { flow } from 'fp-ts/lib/function'; import { addIdToItem, removeIdFromItem } from '@kbn/securitysolution-utils'; import type { - CreateRulesSchema, - UpdateRulesSchema, -} from '../../../../../common/detection_engine/schemas/request'; -import type { Rule } from './types'; + RuleCreateProps, + RuleUpdateProps, +} from '../../../../../common/detection_engine/rule_schema'; +import type { Rule } from '../../../../detection_engine/rule_management/logic/types'; // These are a collection of transforms that are UI specific and useful for UI concerns // that are inserted between the API and the actual user interface. In some ways these @@ -31,8 +31,8 @@ import type { Rule } from './types'; * @returns The rule transformed from the output */ export const transformOutput = ( - rule: CreateRulesSchema | UpdateRulesSchema -): CreateRulesSchema | UpdateRulesSchema => flow(removeIdFromThreatMatchArray)(rule); + rule: RuleCreateProps | RuleUpdateProps +): RuleCreateProps | RuleUpdateProps => flow(removeIdFromThreatMatchArray)(rule); /** * Transforms the output of rules to compensate for technical debt or UI concerns such as @@ -84,8 +84,8 @@ export const addIdToThreatMatchArray = (rule: Rule): Rule => { * @returns rule The rule but with id removed from the threat array and entries */ export const removeIdFromThreatMatchArray = ( - rule: CreateRulesSchema | UpdateRulesSchema -): CreateRulesSchema | UpdateRulesSchema => { + rule: RuleCreateProps | RuleUpdateProps +): RuleCreateProps | RuleUpdateProps => { if (rule.type === 'threat_match' && rule.threat_mapping != null) { const threatMapWithoutId = rule.threat_mapping.map((mapping) => { const newEntries = mapping.entries.map((entry) => removeIdFromItem(entry)); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts deleted file mode 100644 index c1161db6db26f..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/translations.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const RULE_AND_TIMELINE_FETCH_FAILURE = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.rulesAndTimelines', - { - defaultMessage: 'Failed to fetch Rules and Timelines', - } -); - -export const RULE_ADD_FAILURE = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.addRuleFailDescription', - { - defaultMessage: 'Failed to add Rule', - } -); - -export const RULE_AND_TIMELINE_PREPACKAGED_FAILURE = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineFailDescription', - { - defaultMessage: 'Failed to installed pre-packaged rules and timelines from elastic', - } -); - -export const RULE_AND_TIMELINE_PREPACKAGED_SUCCESS = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleAndTimelineSuccesDescription', - { - defaultMessage: 'Installed pre-packaged rules and timeline templates from elastic', - } -); - -export const RULE_PREPACKAGED_SUCCESS = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.createPrePackagedRuleSuccesDescription', - { - defaultMessage: 'Installed pre-packaged rules from elastic', - } -); - -export const TIMELINE_PREPACKAGED_SUCCESS = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.createPrePackagedTimelineSuccesDescription', - { - defaultMessage: 'Installed pre-packaged timeline templates from elastic', - } -); - -export const TAG_FETCH_FAILURE = i18n.translate( - 'xpack.securitySolution.containers.detectionEngine.tagFetchFailDescription', - { - defaultMessage: 'Failed to fetch Tags', - } -); - -export const LOAD_PREPACKAGED_RULES = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton', - { - defaultMessage: 'Load Elastic prebuilt rules', - } -); - -export const LOAD_PREPACKAGED_TIMELINE_TEMPLATES = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedTimelineTemplatesButton', - { - defaultMessage: 'Load Elastic prebuilt timeline templates', - } -); - -export const LOAD_PREPACKAGED_RULES_AND_TEMPLATES = i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesAndTemplatesButton', - { - defaultMessage: 'Load Elastic prebuilt rules and timeline templates', - } -); - -export const RELOAD_MISSING_PREPACKAGED_RULES = (missingRules: number) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton', - { - values: { missingRules }, - defaultMessage: - 'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} ', - } - ); - -export const RELOAD_MISSING_PREPACKAGED_TIMELINES = (missingTimelines: number) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedTimelinesButton', - { - values: { missingTimelines }, - defaultMessage: - 'Install {missingTimelines} Elastic prebuilt {missingTimelines, plural, =1 {timeline} other {timelines}} ', - } - ); - -export const RELOAD_MISSING_PREPACKAGED_RULES_AND_TIMELINES = ( - missingRules: number, - missingTimelines: number -) => - i18n.translate( - 'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesAndTimelinesButton', - { - values: { missingRules, missingTimelines }, - defaultMessage: - 'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} and {missingTimelines} Elastic prebuilt {missingTimelines, plural, =1 {timeline} other {timelines}} ', - } - ); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_create_rule.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_create_rule.test.tsx deleted file mode 100644 index 71d8aacff4280..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_create_rule.test.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { renderHook, act } from '@testing-library/react-hooks'; - -import type { ReturnCreateRule } from './use_create_rule'; -import { useCreateRule } from './use_create_rule'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getRulesSchemaMock } from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; -import { TestProviders } from '../../../../common/mock'; - -jest.mock('./api'); -jest.mock('../../../../common/hooks/use_app_toasts'); - -describe('useCreateRule', () => { - (useAppToasts as jest.Mock).mockReturnValue(useAppToastsMock.create()); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('init', async () => { - const { result } = renderHook(() => useCreateRule(), { - wrapper: TestProviders, - }); - - expect(result.current).toEqual([{ isLoading: false, ruleId: null }, result.current[1]]); - }); - - test('saving rule with isLoading === true', async () => { - await act(async () => { - const { result, rerender, waitForNextUpdate } = renderHook( - () => useCreateRule(), - { - wrapper: TestProviders, - } - ); - await waitForNextUpdate(); - result.current[1](getCreateRulesSchemaMock()); - rerender(); - expect(result.current).toEqual([{ isLoading: true, ruleId: null }, result.current[1]]); - }); - }); - - test('updates ruleId after the rule has been saved', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => useCreateRule(), - { - wrapper: TestProviders, - } - ); - await waitForNextUpdate(); - result.current[1](getCreateRulesSchemaMock()); - await waitForNextUpdate(); - expect(result.current).toEqual([ - { isLoading: false, ruleId: getRulesSchemaMock().id }, - result.current[1], - ]); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_create_rule.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_create_rule.tsx deleted file mode 100644 index f2b76c306dc5f..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_create_rule.tsx +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Dispatch } from 'react'; -import { useEffect, useState } from 'react'; - -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import type { CreateRulesSchema } from '../../../../../common/detection_engine/schemas/request'; - -import { createRule } from './api'; -import * as i18n from './translations'; -import { transformOutput } from './transforms'; -import { useInvalidateRules } from './use_find_rules_query'; -import { useInvalidatePrePackagedRulesStatus } from './use_pre_packaged_rules_status'; - -interface CreateRuleReturn { - isLoading: boolean; - ruleId: string | null; -} - -export type ReturnCreateRule = [CreateRuleReturn, Dispatch]; - -export const useCreateRule = (): ReturnCreateRule => { - const [rule, setRule] = useState(null); - const [ruleId, setRuleId] = useState(null); - const [isLoading, setIsLoading] = useState(false); - const { addError } = useAppToasts(); - const invalidateRules = useInvalidateRules(); - const invalidatePrePackagedRulesStatus = useInvalidatePrePackagedRulesStatus(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - setRuleId(null); - const saveRule = async () => { - if (rule != null) { - try { - setIsLoading(true); - const createRuleResponse = await createRule({ - rule: transformOutput(rule), - signal: abortCtrl.signal, - }); - invalidateRules(); - invalidatePrePackagedRulesStatus(); - if (isSubscribed) { - setRuleId(createRuleResponse.id); - } - } catch (error) { - if (isSubscribed) { - addError(error, { title: i18n.RULE_ADD_FAILURE }); - } - } - if (isSubscribed) { - setIsLoading(false); - } - } - }; - - saveRule(); - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - }, [rule, addError, invalidateRules, invalidatePrePackagedRulesStatus]); - - return [{ isLoading, ruleId }, setRule]; -}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx deleted file mode 100644 index 5cddbeef63028..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.test.tsx +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { act, renderHook } from '@testing-library/react-hooks'; -import { shallow } from 'enzyme'; -import type { ReactElement } from 'react'; -import { useToasts } from '../../../../common/lib/kibana'; -import { TestProviders } from '../../../../common/mock'; -import * as api from './api'; -import * as i18n from './translations'; -import type { ReturnPrePackagedRulesAndTimelines } from './use_pre_packaged_rules'; -import { usePrePackagedRules } from './use_pre_packaged_rules'; - -jest.mock('../../../../common/lib/kibana', () => ({ - useKibana: jest.fn(), - useToasts: jest.fn().mockReturnValue({ - addError: jest.fn(), - addSuccess: jest.fn(), - addWarning: jest.fn(), - remove: jest.fn(), - }), -})); - -jest.mock('./api', () => ({ - getPrePackagedRulesStatus: jest.fn(), - createPrepackagedRules: jest.fn(), -})); - -describe('usePrePackagedRules', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('initial state', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: null, - hasIndexWrite: null, - isAuthenticated: null, - hasEncryptionKey: null, - isSignalIndexExists: null, - }), - { wrapper: TestProviders } - ); - - await waitForNextUpdate(); - - expect(result.current).toEqual({ - getLoadPrebuiltRulesAndTemplatesButton: expect.any(Function), - getReloadPrebuiltRulesAndTemplatesButton: expect.any(Function), - createPrePackagedRules: expect.any(Function), - loading: true, - loadingCreatePrePackagedRules: false, - }); - }); - }); - - test('fetch getPrePackagedRulesStatus', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 33, - rules_installed: 12, - rules_not_installed: 0, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 0, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: null, - hasIndexWrite: null, - isAuthenticated: null, - hasEncryptionKey: null, - isSignalIndexExists: null, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(result.current).toEqual({ - getLoadPrebuiltRulesAndTemplatesButton: - result.current.getLoadPrebuiltRulesAndTemplatesButton, - getReloadPrebuiltRulesAndTemplatesButton: - result.current.getReloadPrebuiltRulesAndTemplatesButton, - createPrePackagedRules: result.current.createPrePackagedRules, - loading: false, - loadingCreatePrePackagedRules: false, - rulesCustomInstalled: 33, - rulesInstalled: 12, - rulesNotInstalled: 0, - rulesNotUpdated: 0, - timelinesInstalled: 0, - timelinesNotInstalled: 0, - timelinesNotUpdated: 0, - }); - }); - }); - - test('happy path to createPrePackagedRules', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 33, - rules_installed: 12, - rules_not_installed: 0, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 0, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).toHaveBeenCalled(); - await waitForNextUpdate(); - expect(result.current).toEqual({ - getLoadPrebuiltRulesAndTemplatesButton: - result.current.getLoadPrebuiltRulesAndTemplatesButton, - getReloadPrebuiltRulesAndTemplatesButton: - result.current.getReloadPrebuiltRulesAndTemplatesButton, - createPrePackagedRules: result.current.createPrePackagedRules, - loading: false, - loadingCreatePrePackagedRules: false, - rulesCustomInstalled: 33, - rulesInstalled: 12, - rulesNotInstalled: 0, - rulesNotUpdated: 0, - timelinesInstalled: 0, - timelinesNotInstalled: 0, - timelinesNotUpdated: 0, - }); - }); - }); - - test('getLoadPrebuiltRulesAndTemplatesButton - LOAD_PREPACKAGED_RULES', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 0, - rules_installed: 0, - rules_not_installed: 1, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 0, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - const button = result.current.getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: false, - onClick: jest.fn(), - 'data-test-subj': 'button', - }); - const wrapper = shallow(button as ReactElement); - expect(wrapper.find('[data-test-subj="button"]').text()).toEqual(i18n.LOAD_PREPACKAGED_RULES); - }); - }); - - test('getLoadPrebuiltRulesAndTemplatesButton - LOAD_PREPACKAGED_TIMELINE_TEMPLATES', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 0, - rules_installed: 0, - rules_not_installed: 0, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 1, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - const button = result.current.getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: false, - onClick: jest.fn(), - 'data-test-subj': 'button', - }); - const wrapper = shallow(button as ReactElement); - expect(wrapper.find('[data-test-subj="button"]').text()).toEqual( - i18n.LOAD_PREPACKAGED_TIMELINE_TEMPLATES - ); - }); - }); - - test('getLoadPrebuiltRulesAndTemplatesButton - LOAD_PREPACKAGED_RULES_AND_TEMPLATES', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 0, - rules_installed: 0, - rules_not_installed: 1, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 1, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - const button = result.current.getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: false, - onClick: jest.fn(), - 'data-test-subj': 'button', - }); - const wrapper = shallow(button as ReactElement); - expect(wrapper.find('[data-test-subj="button"]').text()).toEqual( - i18n.LOAD_PREPACKAGED_RULES_AND_TEMPLATES - ); - }); - }); - - test('getReloadPrebuiltRulesAndTemplatesButton - missing rules and templates', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 0, - rules_installed: 1, - rules_not_installed: 1, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 1, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - const button = result.current.getReloadPrebuiltRulesAndTemplatesButton({ - isDisabled: false, - onClick: jest.fn(), - }); - const wrapper = shallow(button as ReactElement); - expect(wrapper.find('[data-test-subj="reloadPrebuiltRulesBtn"]').text()).toEqual( - 'Install 1 Elastic prebuilt rule and 1 Elastic prebuilt timeline ' - ); - }); - }); - - test('getReloadPrebuiltRulesAndTemplatesButton - missing rules', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 0, - rules_installed: 1, - rules_not_installed: 1, - rules_not_updated: 0, - timelines_installed: 0, - timelines_not_installed: 0, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - const button = result.current.getReloadPrebuiltRulesAndTemplatesButton({ - isDisabled: false, - onClick: jest.fn(), - }); - const wrapper = shallow(button as ReactElement); - expect(wrapper.find('[data-test-subj="reloadPrebuiltRulesBtn"]').text()).toEqual( - 'Install 1 Elastic prebuilt rule ' - ); - }); - }); - - test('getReloadPrebuiltRulesAndTemplatesButton - missing templates', async () => { - (api.getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({ - rules_custom_installed: 0, - rules_installed: 1, - rules_not_installed: 0, - rules_not_updated: 0, - timelines_installed: 1, - timelines_not_installed: 1, - timelines_not_updated: 0, - }); - (api.createPrepackagedRules as jest.Mock).mockResolvedValue({ - rules_installed: 0, - rules_updated: 0, - timelines_installed: 0, - timelines_updated: 0, - }); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - - const button = result.current.getReloadPrebuiltRulesAndTemplatesButton({ - isDisabled: false, - onClick: jest.fn(), - }); - const wrapper = shallow(button as ReactElement); - expect(wrapper.find('[data-test-subj="reloadPrebuiltRulesBtn"]').text()).toEqual( - 'Install 1 Elastic prebuilt timeline ' - ); - }); - }); - - test('unhappy path to createPrePackagedRules', async () => { - (api.createPrepackagedRules as jest.Mock).mockRejectedValue(new Error('Something went wrong')); - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).toHaveBeenCalled(); - expect(useToasts().addError).toHaveBeenCalled(); - }); - }); - - test('can NOT createPrePackagedRules because canUserCrud === false', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: false, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).not.toHaveBeenCalled(); - }); - }); - - test('can NOT createPrePackagedRules because hasIndexWrite === false', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: false, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).not.toHaveBeenCalled(); - }); - }); - - test('can NOT createPrePackagedRules because isAuthenticated === false', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: false, - hasEncryptionKey: true, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).not.toHaveBeenCalled(); - }); - }); - - test('can NOT createPrePackagedRules because hasEncryptionKey === false', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: false, - isSignalIndexExists: true, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).not.toHaveBeenCalled(); - }); - }); - - test('can NOT createPrePackagedRules because isSignalIndexExists === false', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => - usePrePackagedRules({ - canUserCRUD: true, - hasIndexWrite: true, - isAuthenticated: true, - hasEncryptionKey: true, - isSignalIndexExists: false, - }), - { wrapper: TestProviders } - ); - await waitForNextUpdate(); - result.current.createPrePackagedRules(); - await waitForNextUpdate(); - expect(api.createPrepackagedRules).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx deleted file mode 100644 index 88bfe5c618c01..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules.tsx +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; -import { - getPrePackagedRuleStatus, - getPrePackagedTimelineStatus, -} from '../../../pages/detection_engine/rules/helpers'; -import * as i18n from './translations'; -import { useInstallPrePackagedRules } from './use_install_pre_packaged_rules'; -import type { PrePackagedRulesStatusResponse } from './use_pre_packaged_rules_status'; -import { usePrePackagedRulesStatus } from './use_pre_packaged_rules_status'; - -type GetLoadPrebuiltRulesAndTemplatesButton = (args: { - isDisabled: boolean; - onClick: () => void; - fill?: boolean; - 'data-test-subj'?: string; -}) => React.ReactNode | null; - -type GetReloadPrebuiltRulesAndTemplatesButton = ({ - isDisabled, - onClick, - fill, -}: { - isDisabled: boolean; - onClick: () => void; - fill?: boolean; -}) => React.ReactNode | null; - -interface ReturnPrePackagedRules { - createPrePackagedRules: () => void; - loading: boolean; - loadingCreatePrePackagedRules: boolean; - getLoadPrebuiltRulesAndTemplatesButton: GetLoadPrebuiltRulesAndTemplatesButton; - getReloadPrebuiltRulesAndTemplatesButton: GetReloadPrebuiltRulesAndTemplatesButton; -} - -export type ReturnPrePackagedRulesAndTimelines = ReturnPrePackagedRules & - Partial; - -interface UsePrePackagedRuleProps { - canUserCRUD: boolean | null; - hasIndexWrite: boolean | null; - isAuthenticated: boolean | null; - hasEncryptionKey: boolean | null; - isSignalIndexExists: boolean | null; -} - -/** - * Hook for using to get status about pre-packaged Rules from the Detection Engine API - * - * @param hasIndexWrite boolean - * @param isAuthenticated boolean - * @param hasEncryptionKey boolean - * @param isSignalIndexExists boolean - * - */ -export const usePrePackagedRules = ({ - canUserCRUD, - hasIndexWrite, - isAuthenticated, - hasEncryptionKey, - isSignalIndexExists, -}: UsePrePackagedRuleProps): ReturnPrePackagedRulesAndTimelines => { - const { data: prePackagedRulesStatus, isFetching } = usePrePackagedRulesStatus(); - const { mutate: installPrePackagedRules, isLoading: loadingCreatePrePackagedRules } = - useInstallPrePackagedRules(); - - const createPrePackagedRules = useCallback(() => { - if ( - canUserCRUD && - hasIndexWrite && - isAuthenticated && - hasEncryptionKey && - isSignalIndexExists - ) { - installPrePackagedRules(); - } - }, [ - canUserCRUD, - hasEncryptionKey, - hasIndexWrite, - installPrePackagedRules, - isAuthenticated, - isSignalIndexExists, - ]); - - const prePackagedAssetsStatus = useMemo( - () => - getPrePackagedRuleStatus( - prePackagedRulesStatus?.rulesInstalled, - prePackagedRulesStatus?.rulesNotInstalled, - prePackagedRulesStatus?.rulesNotUpdated - ), - [ - prePackagedRulesStatus?.rulesInstalled, - prePackagedRulesStatus?.rulesNotInstalled, - prePackagedRulesStatus?.rulesNotUpdated, - ] - ); - - const prePackagedTimelineStatus = useMemo( - () => - getPrePackagedTimelineStatus( - prePackagedRulesStatus?.timelinesInstalled, - prePackagedRulesStatus?.timelinesNotInstalled, - prePackagedRulesStatus?.timelinesNotUpdated - ), - [ - prePackagedRulesStatus?.timelinesInstalled, - prePackagedRulesStatus?.timelinesNotInstalled, - prePackagedRulesStatus?.timelinesNotUpdated, - ] - ); - const getLoadPrebuiltRulesAndTemplatesButton = useCallback( - ({ isDisabled, onClick, fill, 'data-test-subj': dataTestSubj = 'loadPrebuiltRulesBtn' }) => { - return (prePackagedAssetsStatus === 'ruleNotInstalled' || - prePackagedTimelineStatus === 'timelinesNotInstalled') && - prePackagedAssetsStatus !== 'someRuleUninstall' ? ( - - {prePackagedAssetsStatus === 'ruleNotInstalled' && - prePackagedTimelineStatus === 'timelinesNotInstalled' && - i18n.LOAD_PREPACKAGED_RULES_AND_TEMPLATES} - - {prePackagedAssetsStatus === 'ruleNotInstalled' && - prePackagedTimelineStatus !== 'timelinesNotInstalled' && - i18n.LOAD_PREPACKAGED_RULES} - - {prePackagedAssetsStatus !== 'ruleNotInstalled' && - prePackagedTimelineStatus === 'timelinesNotInstalled' && - i18n.LOAD_PREPACKAGED_TIMELINE_TEMPLATES} - - ) : null; - }, - [loadingCreatePrePackagedRules, prePackagedAssetsStatus, prePackagedTimelineStatus] - ); - - const getMissingRulesOrTimelinesButtonTitle = useCallback( - (missingRules: number, missingTimelines: number) => { - if (missingRules > 0 && missingTimelines === 0) - return i18n.RELOAD_MISSING_PREPACKAGED_RULES(missingRules); - else if (missingRules === 0 && missingTimelines > 0) - return i18n.RELOAD_MISSING_PREPACKAGED_TIMELINES(missingTimelines); - else if (missingRules > 0 && missingTimelines > 0) - return i18n.RELOAD_MISSING_PREPACKAGED_RULES_AND_TIMELINES(missingRules, missingTimelines); - }, - [] - ); - - const getReloadPrebuiltRulesAndTemplatesButton = useCallback( - ({ isDisabled, onClick, fill = false }) => { - return prePackagedAssetsStatus === 'someRuleUninstall' || - prePackagedTimelineStatus === 'someTimelineUninstall' ? ( - - {getMissingRulesOrTimelinesButtonTitle( - prePackagedRulesStatus?.rulesNotInstalled ?? 0, - prePackagedRulesStatus?.timelinesNotInstalled ?? 0 - )} - - ) : null; - }, - [ - getMissingRulesOrTimelinesButtonTitle, - loadingCreatePrePackagedRules, - prePackagedAssetsStatus, - prePackagedRulesStatus?.rulesNotInstalled, - prePackagedRulesStatus?.timelinesNotInstalled, - prePackagedTimelineStatus, - ] - ); - - return { - loading: isFetching, - loadingCreatePrePackagedRules, - createPrePackagedRules, - getLoadPrebuiltRulesAndTemplatesButton, - getReloadPrebuiltRulesAndTemplatesButton, - ...prePackagedRulesStatus, - }; -}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts deleted file mode 100644 index c01bce4fe8bc2..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_pre_packaged_rules_status.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { useCallback } from 'react'; -import { useQuery, useQueryClient } from '@tanstack/react-query'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { getPrePackagedRulesStatus } from './api'; -import * as i18n from './translations'; - -const ONE_MINUTE = 60000; - -export interface PrePackagedRulesStatusResponse { - rulesCustomInstalled: number; - rulesInstalled: number; - rulesNotInstalled: number; - rulesNotUpdated: number; - timelinesInstalled: number; - timelinesNotInstalled: number; - timelinesNotUpdated: number; -} - -export const PRE_PACKAGED_RULES_STATUS_QUERY_KEY = 'prePackagedRulesStatus'; - -export const usePrePackagedRulesStatus = () => { - const { addError } = useAppToasts(); - - return useQuery( - [PRE_PACKAGED_RULES_STATUS_QUERY_KEY], - async ({ signal }) => { - const response = await getPrePackagedRulesStatus({ signal }); - - return { - rulesCustomInstalled: response.rules_custom_installed, - rulesInstalled: response.rules_installed, - rulesNotInstalled: response.rules_not_installed, - rulesNotUpdated: response.rules_not_updated, - timelinesInstalled: response.timelines_installed, - timelinesNotInstalled: response.timelines_not_installed, - timelinesNotUpdated: response.timelines_not_updated, - }; - }, - { - staleTime: ONE_MINUTE * 5, - onError: (err) => { - addError(err, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }); - }, - } - ); -}; - -/** - * We should use this hook to invalidate the prepackaged rules cache. For - * example, rule mutations that affect rule set size, like creation or deletion, - * should lead to cache invalidation. - * - * @returns A rules cache invalidation callback - */ -export const useInvalidatePrePackagedRulesStatus = () => { - const queryClient = useQueryClient(); - - return useCallback(() => { - queryClient.invalidateQueries([PRE_PACKAGED_RULES_STATUS_QUERY_KEY], { - refetchType: 'active', - }); - }, [queryClient]); -}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule.test.tsx deleted file mode 100644 index 89e32793b9e9a..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule.test.tsx +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { renderHook, act } from '@testing-library/react-hooks'; -import type { ReturnRule } from './use_rule'; -import { useRule } from './use_rule'; -import * as api from './api'; -import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; - -jest.mock('./api'); -jest.mock('../../../../common/hooks/use_app_toasts'); - -describe('useRule', () => { - (useAppToasts as jest.Mock).mockReturnValue(useAppToastsMock.create()); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('init', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => - useRule('myOwnRuleID') - ); - await waitForNextUpdate(); - expect(result.current).toEqual([true, null]); - }); - }); - - test('fetch rule', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => - useRule('myOwnRuleID') - ); - await waitForNextUpdate(); - await waitForNextUpdate(); - expect(result.current).toEqual([ - false, - { - actions: [], - author: [], - created_at: 'mm/dd/yyyyTHH:MM:sssz', - created_by: 'mockUser', - description: 'some desc', - enabled: true, - false_positives: [], - filters: [], - from: 'now-360s', - id: '12345678987654321', - immutable: false, - index: [ - 'apm-*-transaction*', - 'traces-apm*', - 'auditbeat-*', - 'endgame-*', - 'filebeat-*', - 'packetbeat-*', - 'winlogbeat-*', - ], - interval: '5m', - language: 'kuery', - name: 'Test rule', - max_signals: 100, - query: "user.email: 'root@elastic.co'", - references: [], - related_integrations: [], - required_fields: [], - risk_score: 75, - risk_score_mapping: [], - rule_id: 'bbd3106e-b4b5-4d7c-a1a2-47531d6a2baf', - setup: '', - severity: 'high', - severity_mapping: [], - tags: ['APM'], - threat: [], - throttle: null, - to: 'now', - type: 'query', - updated_at: 'mm/dd/yyyyTHH:MM:sssz', - updated_by: 'mockUser', - }, - ]); - }); - }); - - test('fetch a new rule', async () => { - const spyOnfetchRuleById = jest.spyOn(api, 'fetchRuleById'); - await act(async () => { - const { rerender, waitForNextUpdate } = renderHook((id) => useRule(id), { - initialProps: 'myOwnRuleID', - }); - await waitForNextUpdate(); - await waitForNextUpdate(); - rerender('newRuleId'); - await waitForNextUpdate(); - expect(spyOnfetchRuleById).toHaveBeenCalledTimes(2); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule.tsx deleted file mode 100644 index bef089555128d..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useEffect, useState } from 'react'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; - -import { fetchRuleById } from './api'; -import { transformInput } from './transforms'; -import * as i18n from './translations'; -import type { Rule } from './types'; - -export type ReturnRule = [boolean, Rule | null]; - -/** - * Hook for using to get a Rule from the Detection Engine API - * - * @param id desired Rule ID's (not rule_id) - * - */ -export const useRule = (id: string | undefined): ReturnRule => { - const [rule, setRule] = useState(null); - const [loading, setLoading] = useState(true); - const { addError } = useAppToasts(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - - const fetchData = async (idToFetch: string) => { - try { - setLoading(true); - const ruleResponse = transformInput( - await fetchRuleById({ - id: idToFetch, - signal: abortCtrl.signal, - }) - ); - if (isSubscribed) { - setRule(ruleResponse); - } - } catch (error) { - if (isSubscribed) { - setRule(null); - addError(error, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }); - } - } - if (isSubscribed) { - setLoading(false); - } - }; - if (id != null) { - fetchData(id); - } - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - }, [id, addError]); - - return [loading, rule]; -}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_async.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_async.tsx deleted file mode 100644 index ab93a50f12829..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_async.tsx +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useEffect, useCallback } from 'react'; - -import { flow } from 'fp-ts/lib/function'; -import { useAsync, withOptionalSignal } from '@kbn/securitysolution-hook-utils'; -import { useHttp } from '../../../../common/lib/kibana'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { pureFetchRuleById } from './api'; -import type { Rule } from './types'; -import * as i18n from './translations'; -import { transformInput } from './transforms'; - -export interface UseRuleAsync { - error: unknown; - loading: boolean; - refresh: () => void; - rule: Rule | null; -} - -const _fetchRule = flow(withOptionalSignal(pureFetchRuleById), async (rule: Promise) => - transformInput(await rule) -); - -/** This does not use "_useRuleAsyncInternal" as that would deactivate the useHooks linter rule, so instead it has the word "Internal" post-pended */ -const useRuleAsyncInternal = () => useAsync(_fetchRule); - -export const useRuleAsync = (ruleId: string): UseRuleAsync => { - const { start, loading, result, error } = useRuleAsyncInternal(); - const http = useHttp(); - const { addError } = useAppToasts(); - - const fetch = useCallback(() => { - start({ id: ruleId, http }); - }, [http, ruleId, start]); - - // initial fetch - useEffect(() => { - fetch(); - }, [fetch]); - - // toast on error - useEffect(() => { - if (error != null) { - addError(error, { title: i18n.RULE_AND_TIMELINE_FETCH_FAILURE }); - } - }, [addError, error]); - - return { error, loading, refresh: fetch, rule: result ?? null }; -}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx deleted file mode 100644 index c8e2bc3e98279..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_rule_with_fallback.test.tsx +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { renderHook, act } from '@testing-library/react-hooks'; -import type { SecurityAppError } from '@kbn/securitysolution-t-grid'; -import { alertsMock8x, alertMockEmptyResults } from '../alerts/mock'; -import type { AlertSearchResponse } from '../alerts/types'; -import { useRuleWithFallback } from './use_rule_with_fallback'; -import * as api from './api'; -import * as alertsAPI from '../alerts/api'; -import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; - -jest.mock('./api'); -jest.mock('../alerts/api'); -jest.mock('../../../../common/hooks/use_app_toasts'); -jest.mock('../../../../common/lib/kibana'); - -const mockNotFoundErrorForRule = () => { - (api.fetchRuleById as jest.Mock).mockImplementation(async () => { - const err = new Error('Not found') as SecurityAppError; - err.body = { status_code: 404, message: 'Rule Not found' }; - throw err; - }); -}; - -describe('useRuleWithFallback', () => { - (useAppToasts as jest.Mock).mockReturnValue(useAppToastsMock.create()); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should return initial state on mount', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useRuleWithFallback('testRuleId')); - await waitForNextUpdate(); - expect(result.current).toEqual({ - error: undefined, - isExistingRule: true, - loading: false, - refresh: expect.any(Function), - rule: null, - }); - }); - }); - - it('should return the rule if it exists', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useRuleWithFallback('testRuleId')); - await waitForNextUpdate(); - await waitForNextUpdate(); - expect(result.current).toMatchInlineSnapshot(` - Object { - "error": undefined, - "isExistingRule": true, - "loading": false, - "refresh": [Function], - "rule": Object { - "actions": Array [], - "author": Array [], - "created_at": "mm/dd/yyyyTHH:MM:sssz", - "created_by": "mockUser", - "description": "some desc", - "enabled": true, - "false_positives": Array [], - "filters": Array [], - "from": "now-360s", - "id": "12345678987654321", - "immutable": false, - "index": Array [ - "apm-*-transaction*", - "traces-apm*", - "auditbeat-*", - "endgame-*", - "filebeat-*", - "packetbeat-*", - "winlogbeat-*", - ], - "interval": "5m", - "language": "kuery", - "max_signals": 100, - "name": "Test rule", - "query": "user.email: 'root@elastic.co'", - "references": Array [], - "related_integrations": Array [], - "required_fields": Array [], - "risk_score": 75, - "risk_score_mapping": Array [], - "rule_id": "bbd3106e-b4b5-4d7c-a1a2-47531d6a2baf", - "setup": "", - "severity": "high", - "severity_mapping": Array [], - "tags": Array [ - "APM", - ], - "threat": Array [], - "throttle": null, - "to": "now", - "type": "query", - "updated_at": "mm/dd/yyyyTHH:MM:sssz", - "updated_by": "mockUser", - }, - } - `); - }); - }); - - it("should fallback to fetching rule data from a 7.x signal if the rule doesn't exist", async () => { - mockNotFoundErrorForRule(); - await act(async () => { - const { result, waitForNextUpdate } = renderHook((id) => useRuleWithFallback(id), { - initialProps: 'testRuleId', - }); - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(result.current).toMatchInlineSnapshot(` - Object { - "error": [Error: Not found], - "isExistingRule": false, - "loading": false, - "refresh": [Function], - "rule": Object { - "created_at": "2020-02-12T19:49:29.417Z", - "created_by": "elastic", - "description": "matches most events", - "enabled": true, - "false_positives": Array [], - "filters": Array [], - "from": "now-360s", - "id": "2df3a613-f5a8-4b55-bf6a-487fc820b842", - "immutable": false, - "index": Array [ - "apm-*-transaction*", - "traces-apm*", - "auditbeat-*", - "endgame-*", - "filebeat-*", - "packetbeat-*", - "winlogbeat-*", - ], - "interval": "5m", - "language": "kuery", - "max_signals": 100, - "meta": Object { - "from": "1m", - }, - "name": "matches host.name exists", - "output_index": ".siem-signals-default", - "query": "host.name : *", - "references": Array [ - "https://google.com", - ], - "risk_score": 79, - "rule_id": "82b2b065-a2ee-49fc-9d6d-781a75c3d280", - "severity": "high", - "tags": Array [ - "host.name exists", - "for testing", - ], - "threat": Array [ - Object { - "framework": "MITRE ATT&CK", - "tactic": Object { - "id": "TA0006", - "name": "Credential Access", - "reference": "https://attack.mitre.org/tactics/TA0006", - }, - "technique": Array [ - Object { - "id": "T1110", - "name": "Brute Force", - "reference": "https://attack.mitre.org/techniques/T1110", - }, - Object { - "id": "T1098", - "name": "Account Manipulation", - "reference": "https://attack.mitre.org/techniques/T1098", - }, - Object { - "id": "T1081", - "name": "Credentials in Files", - "reference": "https://attack.mitre.org/techniques/T1081", - }, - ], - }, - Object { - "framework": "MITRE ATT&CK", - "tactic": Object { - "id": "TA0009", - "name": "Collection", - "reference": "https://attack.mitre.org/tactics/TA0009", - }, - "technique": Array [ - Object { - "id": "T1530", - "name": "Data from Cloud Storage Object", - "reference": "https://attack.mitre.org/techniques/T1530", - }, - ], - }, - ], - "to": "now", - "type": "query", - "updated_at": "2020-02-14T23:15:06.186Z", - "updated_by": "elastic", - "version": 1, - }, - } - `); - }); - }); - - it("should fallback to fetching rule data from an 8.0 alert if the rule doesn't exist", async () => { - // Override default mock coming from ../alerts/__mocks__/api.ts - const spy = jest.spyOn(alertsAPI, 'fetchQueryAlerts').mockImplementation(async () => { - return alertsMock8x as AlertSearchResponse; - }); - - mockNotFoundErrorForRule(); - - await act(async () => { - const { result, waitForNextUpdate } = renderHook((id) => useRuleWithFallback(id), { - initialProps: 'testRuleId', - }); - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(result.current).toMatchInlineSnapshot(` - Object { - "error": [Error: Not found], - "isExistingRule": false, - "loading": false, - "refresh": [Function], - "rule": Object { - "actions": Array [], - "author": Array [ - "author", - ], - "category": "Custom Query Rule", - "consumer": "siem", - "created_at": "2022-01-11T23:22:47.678Z", - "created_by": "elastic", - "description": "8.1: To Be Deleted", - "enabled": true, - "exceptions_list": Array [], - "false_positives": Array [ - "fp", - ], - "filters": Array [], - "from": "now-360s", - "immutable": false, - "index": Array [ - "apm-*-transaction*", - "traces-apm*", - "auditbeat-*", - "endgame-*", - "filebeat-*", - "logs-*", - "packetbeat-*", - "winlogbeat-*", - ], - "interval": "5m", - "language": "kuery", - "license": "license", - "max_signals": 100, - "meta": Object { - "from": "1m", - "kibana_siem_app_url": "http://localhost:5601/kbn/app/security", - }, - "name": "944edf04-ea2d-44f9-b89a-574e9a9301da", - "note": "Investigation guuuide", - "producer": "siem", - "query": "host.name:*", - "references": Array [ - "http://www.example.com/1", - ], - "risk_score": 37, - "risk_score_mapping": Array [ - Object { - "field": "Responses.process.pid", - "operator": "equals", - "value": "", - }, - ], - "rule_id": "a2490dbb-33f6-4b03-88d8-b7d009ef58db", - "rule_name_override": "host.id", - "rule_type_id": "siem.queryRule", - "severity": "low", - "severity_mapping": Array [ - Object { - "field": "host.name", - "operator": "equals", - "severity": "low", - "value": "", - }, - ], - "tags": Array [ - "8.0-tag", - ], - "threat": Array [ - Object { - "framework": "MITRE ATT&CK", - "tactic": Object { - "id": "TA0007", - "name": "Discovery", - "reference": "https://attack.mitre.org/tactics/TA0007", - }, - "technique": Array [ - Object { - "id": "T1217", - "name": "Browser Bookmark Discovery", - "reference": "https://attack.mitre.org/techniques/T1217", - "subtechnique": Array [], - }, - Object { - "id": "T1580", - "name": "Cloud Infrastructure Discovery", - "reference": "https://attack.mitre.org/techniques/T1580", - "subtechnique": Array [], - }, - Object { - "id": "T1033", - "name": "System Owner/User Discovery", - "reference": "https://attack.mitre.org/techniques/T1033", - "subtechnique": Array [], - }, - ], - }, - Object { - "framework": "MITRE ATT&CK", - "tactic": Object { - "id": "TA0007", - "name": "Discovery", - "reference": "https://attack.mitre.org/tactics/TA0007", - }, - "technique": Array [], - }, - ], - "to": "now", - "type": "query", - "updated_at": "2022-01-11T23:22:47.678Z", - "updated_by": "elastic", - "uuid": "63136880-7335-11ec-9f1b-9db9315083e9", - "version": 1, - }, - } - `); - }); - // Reset back to default mock coming from ../alerts/__mocks__/api.ts - spy.mockRestore(); - }); - - it('should return rule as null if fallback fetching from 8.0 alert returns empty results', async () => { - // Override default mock coming from ../alerts/__mocks__/api.ts - const spy = jest.spyOn(alertsAPI, 'fetchQueryAlerts').mockImplementation(async () => { - return alertMockEmptyResults; - }); - - mockNotFoundErrorForRule(); - - await act(async () => { - const { result, waitForNextUpdate } = renderHook((id) => useRuleWithFallback(id), { - initialProps: 'testRuleId', - }); - await waitForNextUpdate(); - - expect(result.current.rule).toBeNull(); - }); - // Reset back to default mock coming from ../alerts/__mocks__/api.ts - spy.mockRestore(); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_tags.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_tags.test.tsx deleted file mode 100644 index 52b37d6c3d4bf..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_tags.test.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { renderHook, act } from '@testing-library/react-hooks'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; -import type { ReturnTags } from './use_tags'; -import { useTags } from './use_tags'; - -jest.mock('./api'); -jest.mock('../../../../common/hooks/use_app_toasts'); - -describe('useTags', () => { - (useAppToasts as jest.Mock).mockReturnValue(useAppToastsMock.create()); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('init', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useTags()); - await waitForNextUpdate(); - expect(result.current).toEqual([true, [], result.current[2]]); - }); - }); - - test('fetch tags', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => useTags()); - await waitForNextUpdate(); - await waitForNextUpdate(); - expect(result.current).toEqual([ - false, - ['elastic', 'love', 'quality', 'code'], - result.current[2], - ]); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_tags.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_tags.tsx deleted file mode 100644 index 5f16cb593a516..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_tags.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { noop } from 'lodash/fp'; -import { useEffect, useState, useRef } from 'react'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { fetchTags } from './api'; -import * as i18n from './translations'; - -export type ReturnTags = [boolean, string[], () => void]; - -/** - * Hook for using the list of Tags from the Detection Engine API - * - */ -export const useTags = (): ReturnTags => { - const [tags, setTags] = useState([]); - const [loading, setLoading] = useState(true); - const reFetchTags = useRef<() => void>(noop); - const { addError } = useAppToasts(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - - const fetchData = async () => { - setLoading(true); - try { - const fetchTagsResult = await fetchTags({ - signal: abortCtrl.signal, - }); - - if (isSubscribed) { - setTags(fetchTagsResult); - } - } catch (error) { - if (isSubscribed) { - addError(error, { title: i18n.TAG_FETCH_FAILURE }); - } - } - if (isSubscribed) { - setLoading(false); - } - }; - - fetchData(); - reFetchTags.current = fetchData; - - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - }, [addError]); - - return [loading, tags, reFetchTags.current]; -}; diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_update_rule.test.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_update_rule.test.tsx deleted file mode 100644 index c25242e03126e..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_update_rule.test.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { renderHook, act } from '@testing-library/react-hooks'; - -import type { ReturnUpdateRule } from './use_update_rule'; -import { useUpdateRule } from './use_update_rule'; -import { getUpdateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock'; -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { TestProviders } from '../../../../common/mock'; - -jest.mock('./api'); -jest.mock('../../../../common/hooks/use_app_toasts'); - -describe('useUpdateRule', () => { - (useAppToasts as jest.Mock).mockReturnValue(useAppToastsMock.create()); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('init', async () => { - const { result } = renderHook(() => useUpdateRule(), { - wrapper: TestProviders, - }); - - expect(result.current).toEqual([{ isLoading: false, isSaved: false }, result.current[1]]); - }); - - test('saving rule with isLoading === true', async () => { - await act(async () => { - const { result, rerender, waitForNextUpdate } = renderHook( - () => useUpdateRule(), - { - wrapper: TestProviders, - } - ); - await waitForNextUpdate(); - result.current[1](getUpdateRulesSchemaMock()); - rerender(); - expect(result.current).toEqual([{ isLoading: true, isSaved: false }, result.current[1]]); - }); - }); - - test('saved rule with isSaved === true', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook( - () => useUpdateRule(), - { - wrapper: TestProviders, - } - ); - await waitForNextUpdate(); - result.current[1](getUpdateRulesSchemaMock()); - await waitForNextUpdate(); - expect(result.current).toEqual([{ isLoading: false, isSaved: true }, result.current[1]]); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_update_rule.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_update_rule.tsx deleted file mode 100644 index e0144ff8e88eb..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/rules/use_update_rule.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Dispatch } from 'react'; -import { useEffect, useState } from 'react'; - -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import type { UpdateRulesSchema } from '../../../../../common/detection_engine/schemas/request'; - -import { transformOutput } from './transforms'; - -import { updateRule } from './api'; -import * as i18n from './translations'; -import { useInvalidateRules } from './use_find_rules_query'; - -interface UpdateRuleReturn { - isLoading: boolean; - isSaved: boolean; -} - -export type ReturnUpdateRule = [UpdateRuleReturn, Dispatch]; - -export const useUpdateRule = (): ReturnUpdateRule => { - const [rule, setRule] = useState(null); - const [isSaved, setIsSaved] = useState(false); - const [isLoading, setIsLoading] = useState(false); - const { addError } = useAppToasts(); - const invalidateRules = useInvalidateRules(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - setIsSaved(false); - const saveRule = async () => { - if (rule != null) { - try { - setIsLoading(true); - await updateRule({ rule: transformOutput(rule), signal: abortCtrl.signal }); - invalidateRules(); - if (isSubscribed) { - setIsSaved(true); - } - } catch (error) { - if (isSubscribed) { - addError(error, { title: i18n.RULE_ADD_FAILURE }); - } - } - if (isSubscribed) { - setIsLoading(false); - } - } - }; - - saveRule(); - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - }, [rule, addError, invalidateRules]); - - return [{ isLoading, isSaved }, setRule]; -}; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.ts deleted file mode 100644 index d80835209010f..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.ts +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { NavigateToAppOptions } from '@kbn/core/public'; -import { APP_UI_ID } from '../../../../../../common/constants'; -import type { BulkActionEditPayload } from '../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkAction } from '../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { HTTPError } from '../../../../../../common/detection_engine/types'; -import { SecurityPageName } from '../../../../../app/types'; -import { getEditRuleUrl } from '../../../../../common/components/link_to/redirect_to_detection_engine'; -import type { UseAppToasts } from '../../../../../common/hooks/use_app_toasts'; -import { METRIC_TYPE, TELEMETRY_EVENT, track } from '../../../../../common/lib/telemetry'; -import { downloadBlob } from '../../../../../common/utils/download_blob'; -import type { - BulkActionSummary, - BulkActionResponse, -} from '../../../../containers/detection_engine/rules'; -import { performBulkAction } from '../../../../containers/detection_engine/rules'; -import * as i18n from '../translations'; -import { getExportedRulesCounts } from './helpers'; -import type { RulesTableActions } from './rules_table/rules_table_context'; - -export const goToRuleEditPage = ( - ruleId: string, - navigateToApp: (appId: string, options?: NavigateToAppOptions | undefined) => Promise -) => { - navigateToApp(APP_UI_ID, { - deepLinkId: SecurityPageName.rules, - path: getEditRuleUrl(ruleId ?? ''), - }); -}; - -type OnActionSuccessCallback = ( - toasts: UseAppToasts, - action: BulkAction, - summary: BulkActionSummary -) => void; - -type OnActionErrorCallback = (toasts: UseAppToasts, action: BulkAction, error: HTTPError) => void; - -interface BaseRulesBulkActionArgs { - visibleRuleIds?: string[]; - toasts: UseAppToasts; - search: { query: string } | { ids: string[] }; - payload?: { edit?: BulkActionEditPayload[] }; - onError?: OnActionErrorCallback; - onFinish?: () => void; - onSuccess?: OnActionSuccessCallback; - setLoadingRules?: RulesTableActions['setLoadingRules']; -} - -interface RulesBulkActionArgs extends BaseRulesBulkActionArgs { - action: Exclude; -} -interface ExportRulesBulkActionArgs extends BaseRulesBulkActionArgs { - action: BulkAction.export; -} - -// export bulk actions API returns blob, the rest of actions returns BulkActionResponse object -// hence method overloading to make type safe calls -export async function executeRulesBulkAction(args: ExportRulesBulkActionArgs): Promise; -export async function executeRulesBulkAction( - args: RulesBulkActionArgs -): Promise; -export async function executeRulesBulkAction({ - visibleRuleIds = [], - action, - setLoadingRules, - toasts, - search, - payload, - onSuccess = defaultSuccessHandler, - onError = defaultErrorHandler, - onFinish, -}: RulesBulkActionArgs | ExportRulesBulkActionArgs) { - let response: Blob | BulkActionResponse | null = null; - try { - setLoadingRules?.({ ids: visibleRuleIds, action }); - - if (action === BulkAction.export) { - // on successToast for export handles separately outside of action execution method - response = await performBulkAction({ ...search, action }); - } else { - response = await performBulkAction({ ...search, action, edit: payload?.edit }); - sendTelemetry(action, response); - onSuccess(toasts, action, response.attributes.summary); - } - } catch (error) { - onError(toasts, action, error); - } finally { - setLoadingRules?.({ ids: [], action: null }); - onFinish?.(); - } - return response; -} - -/** - * downloads exported rules, received from export action - * @param params.response - Blob results with exported rules - * @param params.toasts - {@link UseAppToasts} toasts service - * @param params.onSuccess - {@link OnActionSuccessCallback} optional toast to display when action successful - * @param params.onError - {@link OnActionErrorCallback} optional toast to display when action failed - */ -export async function downloadExportedRules({ - response, - toasts, - onSuccess = defaultSuccessHandler, - onError = defaultErrorHandler, -}: { - response: Blob; - toasts: UseAppToasts; - onSuccess?: OnActionSuccessCallback; - onError?: OnActionErrorCallback; -}) { - try { - downloadBlob(response, `${i18n.EXPORT_FILENAME}.ndjson`); - onSuccess(toasts, BulkAction.export, await getExportedRulesCounts(response)); - } catch (error) { - onError(toasts, BulkAction.export, error); - } -} - -/** - * executes bulk export action and downloads exported rules - * @param params - {@link ExportRulesBulkActionArgs} - */ -export async function bulkExportRules(params: ExportRulesBulkActionArgs) { - const response = await executeRulesBulkAction(params); - - // if response null, likely network error happened and export rules haven't been received - if (response) { - await downloadExportedRules({ response, toasts: params.toasts, onSuccess: params.onSuccess }); - } -} - -function defaultErrorHandler(toasts: UseAppToasts, action: BulkAction, error: HTTPError) { - // if response doesn't have number of failed rules, it means the whole bulk action failed - // and general error toast will be shown. Otherwise - error toast for partial failure - const summary = (error?.body as BulkActionResponse)?.attributes?.summary; - error.stack = JSON.stringify(error.body, null, 2); - - let title: string; - let toastMessage: string | undefined; - - switch (action) { - case BulkAction.export: - title = i18n.RULES_BULK_EXPORT_FAILURE; - if (summary) { - toastMessage = i18n.RULES_BULK_EXPORT_FAILURE_DESCRIPTION(summary.failed); - } - break; - case BulkAction.duplicate: - title = i18n.RULES_BULK_DUPLICATE_FAILURE; - if (summary) { - toastMessage = i18n.RULES_BULK_DUPLICATE_FAILURE_DESCRIPTION(summary.failed); - } - break; - case BulkAction.delete: - title = i18n.RULES_BULK_DELETE_FAILURE; - if (summary) { - toastMessage = i18n.RULES_BULK_DELETE_FAILURE_DESCRIPTION(summary.failed); - } - break; - case BulkAction.enable: - title = i18n.RULES_BULK_ENABLE_FAILURE; - if (summary) { - toastMessage = i18n.RULES_BULK_ENABLE_FAILURE_DESCRIPTION(summary.failed); - } - break; - case BulkAction.disable: - title = i18n.RULES_BULK_DISABLE_FAILURE; - if (summary) { - toastMessage = i18n.RULES_BULK_DISABLE_FAILURE_DESCRIPTION(summary.failed); - } - break; - case BulkAction.edit: - title = i18n.RULES_BULK_EDIT_FAILURE; - if (summary) { - toastMessage = i18n.RULES_BULK_EDIT_FAILURE_DESCRIPTION(summary.failed); - } - break; - } - - toasts.addError(error, { title, toastMessage }); -} - -const getExportSuccessToastMessage = (succeeded: number, total: number) => { - const message = [i18n.RULES_BULK_EXPORT_SUCCESS_DESCRIPTION(succeeded, total)]; - - // if not all rules are successfully exported it means there included prebuilt rules - // display message to users that prebuilt rules were excluded - if (total > succeeded) { - message.push(i18n.RULES_BULK_EXPORT_PREBUILT_RULES_EXCLUDED_DESCRIPTION); - } - - return message.join(' '); -}; - -async function defaultSuccessHandler( - toasts: UseAppToasts, - action: BulkAction, - summary: BulkActionSummary -) { - let title: string; - let text: string | undefined; - - switch (action) { - case BulkAction.export: - title = i18n.RULES_BULK_EXPORT_SUCCESS; - text = getExportSuccessToastMessage(summary.succeeded, summary.total); - break; - case BulkAction.duplicate: - title = i18n.RULES_BULK_DUPLICATE_SUCCESS; - text = i18n.RULES_BULK_DUPLICATE_SUCCESS_DESCRIPTION(summary.succeeded); - break; - case BulkAction.delete: - title = i18n.RULES_BULK_DELETE_SUCCESS; - text = i18n.RULES_BULK_DELETE_SUCCESS_DESCRIPTION(summary.succeeded); - break; - case BulkAction.enable: - title = i18n.RULES_BULK_ENABLE_SUCCESS; - text = i18n.RULES_BULK_ENABLE_SUCCESS_DESCRIPTION(summary.succeeded); - break; - case BulkAction.disable: - title = i18n.RULES_BULK_DISABLE_SUCCESS; - text = i18n.RULES_BULK_DISABLE_SUCCESS_DESCRIPTION(summary.succeeded); - break; - case BulkAction.edit: - title = i18n.RULES_BULK_EDIT_SUCCESS; - text = i18n.RULES_BULK_EDIT_SUCCESS_DESCRIPTION(summary.succeeded); - break; - } - - toasts.addSuccess({ title, text }); -} - -function sendTelemetry(action: BulkAction, response: BulkActionResponse) { - if (action === BulkAction.disable || action === BulkAction.enable) { - if (response.attributes.results.updated.some((rule) => rule.immutable)) { - track( - METRIC_TYPE.COUNT, - action === BulkAction.enable - ? TELEMETRY_EVENT.SIEM_RULE_ENABLED - : TELEMETRY_EVENT.SIEM_RULE_DISABLED - ); - } - if (response.attributes.results.updated.some((rule) => !rule.immutable)) { - track( - METRIC_TYPE.COUNT, - action === BulkAction.disable - ? TELEMETRY_EVENT.CUSTOM_RULE_ENABLED - : TELEMETRY_EVENT.CUSTOM_RULE_DISABLED - ); - } - } -} diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx deleted file mode 100644 index 826cdca510a62..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.test.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { waitFor } from '@testing-library/react'; -import { mount, shallow } from 'enzyme'; -import React from 'react'; -import { useKibana } from '../../../../../common/lib/kibana'; -import { TestProviders } from '../../../../../common/mock'; -import '../../../../../common/mock/formatted_relative'; -import '../../../../../common/mock/match_media'; -import { AllRules } from '.'; - -jest.mock('../../../../../common/components/link_to'); -jest.mock('../../../../../common/lib/kibana'); -jest.mock('../../../../containers/detection_engine/rules'); -jest.mock('./rules_table/rules_table_context'); - -const useKibanaMock = useKibana as jest.Mocked; - -describe('AllRules', () => { - beforeEach(() => { - useKibanaMock().services.application.capabilities = { - navLinks: {}, - management: {}, - catalogue: {}, - actions: { show: true }, - }; - }); - - afterEach(() => { - jest.clearAllTimers(); - jest.clearAllMocks(); - }); - - it('renders correctly', () => { - const wrapper = shallow( - - ); - - expect(wrapper.find('RulesTables')).toHaveLength(1); - }); - - describe('tabs', () => { - it('renders all rules tab by default', async () => { - const wrapper = mount( - - - - ); - - await waitFor(() => { - expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeFalsy(); - expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeTruthy(); - }); - }); - }); - - it('renders monitoring tab when monitoring tab clicked', async () => { - const wrapper = mount( - - - - ); - - await waitFor(() => { - const monitoringTab = wrapper.find('[data-test-subj="allRulesTableTab-monitoring"] button'); - monitoringTab.simulate('click'); - - wrapper.update(); - expect(wrapper.exists('[data-test-subj="monitoring-table"]')).toBeTruthy(); - expect(wrapper.exists('[data-test-subj="rules-table"]')).toBeFalsy(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx deleted file mode 100644 index bcdcc4dac263e..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiSpacer } from '@elastic/eui'; -import React, { useState } from 'react'; -import { RulesTables } from './rules_tables'; -import { AllRulesTabs, RulesTableToolbar } from './rules_table_toolbar'; - -interface AllRulesProps { - createPrePackagedRules: () => void; - hasPermissions: boolean; - loadingCreatePrePackagedRules: boolean; - rulesCustomInstalled?: number; - rulesInstalled?: number; - rulesNotInstalled?: number; - rulesNotUpdated?: number; -} - -/** - * Table Component for displaying all Rules for a given cluster. Provides the ability to filter - * by name, sort by enabled, and perform the following actions: - * * Enable/Disable - * * Duplicate - * * Delete - * * Import/Export - */ -export const AllRules = React.memo( - ({ - createPrePackagedRules, - hasPermissions, - loadingCreatePrePackagedRules, - rulesCustomInstalled, - rulesInstalled, - rulesNotInstalled, - rulesNotUpdated, - }) => { - const [activeTab, setActiveTab] = useState(AllRulesTabs.rules); - - return ( - <> - - - - - ); - } -); - -AllRules.displayName = 'AllRules'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_actions.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_actions.test.tsx deleted file mode 100644 index 30c8ba7008367..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_actions.test.tsx +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import uuid from 'uuid'; -import { useAppToastsMock } from '../../../../../common/hooks/use_app_toasts.mock'; -import '../../../../../common/mock/match_media'; -import { goToRuleEditPage, executeRulesBulkAction } from './actions'; -import { getRulesTableActions } from './rules_table_actions'; -import { mockRule } from './__mocks__/mock'; - -jest.mock('./actions'); - -const executeRulesBulkActionMock = executeRulesBulkAction as jest.Mock; -const goToRuleEditPageMock = goToRuleEditPage as jest.Mock; - -describe('getRulesTableActions', () => { - const rule = mockRule(uuid.v4()); - const toasts = useAppToastsMock.create(); - const invalidateRules = jest.fn(); - const invalidatePrePackagedRulesStatus = jest.fn(); - const setLoadingRules = jest.fn(); - const startTransaction = jest.fn(); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - test('duplicate rule onClick should call rule edit after the rule is duplicated', async () => { - const ruleDuplicate = mockRule('newRule'); - const navigateToApp = jest.fn(); - executeRulesBulkActionMock.mockImplementation(() => - Promise.resolve({ attributes: { results: { created: [ruleDuplicate] } } }) - ); - - const duplicateRulesActionObject = getRulesTableActions({ - toasts, - navigateToApp, - invalidateRules, - invalidatePrePackagedRulesStatus, - actionsPrivileges: true, - setLoadingRules, - startTransaction, - })[1]; - const duplicateRulesActionHandler = duplicateRulesActionObject.onClick; - expect(duplicateRulesActionHandler).toBeDefined(); - - await duplicateRulesActionHandler!(rule); - expect(executeRulesBulkAction).toHaveBeenCalledWith( - expect.objectContaining({ action: 'duplicate' }) - ); - expect(goToRuleEditPageMock).toHaveBeenCalledWith(ruleDuplicate.id, navigateToApp); - }); - - test('delete rule onClick should call refetch after the rule is deleted', async () => { - const navigateToApp = jest.fn(); - - const deleteRulesActionObject = getRulesTableActions({ - toasts, - navigateToApp, - invalidateRules, - invalidatePrePackagedRulesStatus, - actionsPrivileges: true, - setLoadingRules, - startTransaction, - })[3]; - const deleteRuleActionHandler = deleteRulesActionObject.onClick; - expect(deleteRuleActionHandler).toBeDefined(); - - await deleteRuleActionHandler!(rule); - expect(executeRulesBulkAction).toHaveBeenCalledTimes(1); - expect(executeRulesBulkAction).toHaveBeenCalledWith( - expect.objectContaining({ action: 'delete' }) - ); - expect(invalidateRules).toHaveBeenCalledTimes(1); - expect(executeRulesBulkActionMock.mock.invocationCallOrder[0]).toBeLessThan( - invalidateRules.mock.invocationCallOrder[0] - ); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_actions.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_actions.tsx deleted file mode 100644 index 0a10026194869..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_actions.tsx +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { DefaultItemAction } from '@elastic/eui'; -import { EuiToolTip } from '@elastic/eui'; -import React from 'react'; -import type { NavigateToAppOptions } from '@kbn/core/public'; -import { BulkAction } from '../../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { UseAppToasts } from '../../../../../common/hooks/use_app_toasts'; -import { canEditRuleWithActions } from '../../../../../common/utils/privileges'; -import type { Rule } from '../../../../containers/detection_engine/rules'; -import * as i18n from '../translations'; -import { executeRulesBulkAction, goToRuleEditPage, bulkExportRules } from './actions'; -import type { RulesTableActions } from './rules_table/rules_table_context'; -import type { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; -import { SINGLE_RULE_ACTIONS } from '../../../../../common/lib/apm/user_actions'; - -type NavigateToApp = (appId: string, options?: NavigateToAppOptions | undefined) => Promise; - -export const getRulesTableActions = ({ - toasts, - navigateToApp, - invalidateRules, - invalidatePrePackagedRulesStatus, - actionsPrivileges, - setLoadingRules, - startTransaction, -}: { - toasts: UseAppToasts; - navigateToApp: NavigateToApp; - invalidateRules: () => void; - invalidatePrePackagedRulesStatus: () => void; - actionsPrivileges: boolean; - setLoadingRules: RulesTableActions['setLoadingRules']; - startTransaction: ReturnType['startTransaction']; -}): Array> => [ - { - type: 'icon', - 'data-test-subj': 'editRuleAction', - description: i18n.EDIT_RULE_SETTINGS, - name: !actionsPrivileges ? ( - - <>{i18n.EDIT_RULE_SETTINGS} - - ) : ( - i18n.EDIT_RULE_SETTINGS - ), - icon: 'controlsHorizontal', - onClick: (rule: Rule) => goToRuleEditPage(rule.id, navigateToApp), - enabled: (rule: Rule) => canEditRuleWithActions(rule, actionsPrivileges), - }, - { - type: 'icon', - 'data-test-subj': 'duplicateRuleAction', - description: i18n.DUPLICATE_RULE, - icon: 'copy', - name: !actionsPrivileges ? ( - - <>{i18n.DUPLICATE_RULE} - - ) : ( - i18n.DUPLICATE_RULE - ), - enabled: (rule: Rule) => canEditRuleWithActions(rule, actionsPrivileges), - onClick: async (rule: Rule) => { - startTransaction({ name: SINGLE_RULE_ACTIONS.DUPLICATE }); - const result = await executeRulesBulkAction({ - action: BulkAction.duplicate, - setLoadingRules, - visibleRuleIds: [rule.id], - toasts, - search: { ids: [rule.id] }, - }); - invalidateRules(); - invalidatePrePackagedRulesStatus(); - const createdRules = result?.attributes.results.created; - if (createdRules?.length) { - goToRuleEditPage(createdRules[0].id, navigateToApp); - } - }, - }, - { - type: 'icon', - 'data-test-subj': 'exportRuleAction', - description: i18n.EXPORT_RULE, - icon: 'exportAction', - name: i18n.EXPORT_RULE, - onClick: async (rule: Rule) => { - startTransaction({ name: SINGLE_RULE_ACTIONS.EXPORT }); - await bulkExportRules({ - action: BulkAction.export, - setLoadingRules, - visibleRuleIds: [rule.id], - toasts, - search: { ids: [rule.id] }, - }); - }, - enabled: (rule: Rule) => !rule.immutable, - }, - { - type: 'icon', - 'data-test-subj': 'deleteRuleAction', - description: i18n.DELETE_RULE, - icon: 'trash', - name: i18n.DELETE_RULE, - onClick: async (rule: Rule) => { - startTransaction({ name: SINGLE_RULE_ACTIONS.DELETE }); - await executeRulesBulkAction({ - action: BulkAction.delete, - setLoadingRules, - visibleRuleIds: [rule.id], - toasts, - search: { ids: [rule.id] }, - }); - invalidateRules(); - invalidatePrePackagedRulesStatus(); - }, - }, -]; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx deleted file mode 100644 index 2ad9de45346c4..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_table_filters/rules_table_filters.test.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { mount } from 'enzyme'; - -import { RulesTableFilters } from './rules_table_filters'; -import { TestProviders } from '../../../../../../common/mock'; - -jest.mock('../rules_table/rules_table_context'); - -describe('RulesTableFilters', () => { - it('renders no numbers next to rule type button filter if none exist', async () => { - const wrapper = mount(, { wrappingComponent: TestProviders }); - - expect(wrapper.find('[data-test-subj="showElasticRulesFilterButton"]').at(0).text()).toEqual( - 'Elastic rules' - ); - expect(wrapper.find('[data-test-subj="showCustomRulesFilterButton"]').at(0).text()).toEqual( - 'Custom rules' - ); - }); - - it('renders number of custom and prepackaged rules', async () => { - const wrapper = mount( - , - { wrappingComponent: TestProviders } - ); - - expect(wrapper.find('[data-test-subj="showElasticRulesFilterButton"]').at(0).text()).toEqual( - 'Elastic rules (9)' - ); - expect(wrapper.find('[data-test-subj="showCustomRulesFilterButton"]').at(0).text()).toEqual( - 'Custom rules (10)' - ); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx deleted file mode 100644 index f577a71a6b6e5..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/rules_tables.tsx +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - EuiBasicTable, - EuiConfirmModal, - EuiEmptyPrompt, - EuiLoadingContent, - EuiProgress, -} from '@elastic/eui'; -import React, { useCallback, useEffect, useMemo, useRef } from 'react'; -import { AllRulesTabs } from './rules_table_toolbar'; -import { RULES_TABLE_PAGE_SIZE_OPTIONS } from '../../../../../../common/constants'; -import { Loader } from '../../../../../common/components/loader'; -import { useBoolState } from '../../../../../common/hooks/use_bool_state'; -import { useValueChanged } from '../../../../../common/hooks/use_value_changed'; -import { RULES_TABLE_ACTIONS } from '../../../../../common/lib/apm/user_actions'; -import { useStartTransaction } from '../../../../../common/lib/apm/use_start_transaction'; -import { PrePackagedRulesPrompt } from '../../../../components/rules/pre_packaged_rules/load_empty_prompt'; -import type { Rule, RulesSortingFields } from '../../../../containers/detection_engine/rules'; -import { useTags } from '../../../../containers/detection_engine/rules/use_tags'; -import { getPrePackagedRuleStatus } from '../helpers'; -import * as i18n from '../translations'; -import type { EuiBasicTableOnChange } from '../types'; -import { useMonitoringColumns, useRulesColumns } from './use_columns'; -import { showRulesTable } from './helpers'; -import { useRulesTableContext } from './rules_table/rules_table_context'; -import { useAsyncConfirmation } from './rules_table/use_async_confirmation'; -import { RulesTableFilters } from './rules_table_filters/rules_table_filters'; -import { RulesTableUtilityBar } from './rules_table_utility_bar'; -import { useBulkActionsDryRun } from './bulk_actions/use_bulk_actions_dry_run'; -import { useBulkActionsConfirmation } from './bulk_actions/use_bulk_actions_confirmation'; -import { useBulkEditFormFlyout } from './bulk_actions/use_bulk_edit_form_flyout'; -import { BulkActionDryRunConfirmation } from './bulk_actions/bulk_action_dry_run_confirmation'; -import { BulkEditFlyout } from './bulk_actions/bulk_edit_flyout'; -import { useBulkActions } from './bulk_actions/use_bulk_actions'; - -const INITIAL_SORT_FIELD = 'enabled'; - -interface RulesTableProps { - createPrePackagedRules: () => void; - hasPermissions: boolean; - loadingCreatePrePackagedRules: boolean; - rulesCustomInstalled?: number; - rulesInstalled?: number; - rulesNotInstalled?: number; - rulesNotUpdated?: number; - selectedTab: AllRulesTabs; -} - -const NO_ITEMS_MESSAGE = ( - {i18n.NO_RULES}} titleSize="xs" body={i18n.NO_RULES_BODY} /> -); - -/** - * Table Component for displaying all Rules for a given cluster. Provides the ability to filter - * by name, sort by enabled, and perform the following actions: - * * Enable/Disable - * * Duplicate - * * Delete - * * Import/Export - */ -export const RulesTables = React.memo( - ({ - createPrePackagedRules, - hasPermissions, - loadingCreatePrePackagedRules, - rulesCustomInstalled, - rulesInstalled, - rulesNotInstalled, - rulesNotUpdated, - selectedTab, - }) => { - const { startTransaction } = useStartTransaction(); - const tableRef = useRef(null); - const rulesTableContext = useRulesTableContext(); - - const { - state: { - rules, - filterOptions, - isActionInProgress, - isAllSelected, - isFetched, - isLoading, - isRefetching, - isRefreshOn, - loadingRuleIds, - loadingRulesAction, - pagination, - selectedRuleIds, - sortingOptions, - }, - actions: { - reFetchRules, - setIsAllSelected, - setIsRefreshOn, - setPage, - setPerPage, - setSelectedRuleIds, - setSortingOptions, - }, - } = rulesTableContext; - - const prePackagedRuleStatus = getPrePackagedRuleStatus( - rulesInstalled, - rulesNotInstalled, - rulesNotUpdated - ); - - const [, allTags, reFetchTags] = useTags(); - - useEffect(() => { - reFetchTags(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [rulesCustomInstalled, rulesInstalled]); - - const [isDeleteConfirmationVisible, showDeleteConfirmation, hideDeleteConfirmation] = - useBoolState(); - - const [confirmDeletion, handleDeletionConfirm, handleDeletionCancel] = useAsyncConfirmation({ - onInit: showDeleteConfirmation, - onFinish: hideDeleteConfirmation, - }); - - const { - bulkActionsDryRunResult, - bulkAction, - isBulkActionConfirmationVisible, - showBulkActionConfirmation, - cancelBulkActionConfirmation, - approveBulkActionConfirmation, - } = useBulkActionsConfirmation(); - - const { - bulkEditActionType, - isBulkEditFlyoutVisible, - handleBulkEditFormConfirm, - handleBulkEditFormCancel, - completeBulkEditForm, - } = useBulkEditFormFlyout(); - - const selectedItemsCount = isAllSelected ? pagination.total : selectedRuleIds.length; - - const { isBulkActionsDryRunLoading, executeBulkActionsDryRun } = useBulkActionsDryRun(); - - const getBulkItemsPopoverContent = useBulkActions({ - filterOptions, - confirmDeletion, - showBulkActionConfirmation, - completeBulkEditForm, - reFetchTags, - executeBulkActionsDryRun, - }); - - const paginationMemo = useMemo( - () => ({ - pageIndex: pagination.page - 1, - pageSize: pagination.perPage, - totalItemCount: pagination.total, - pageSizeOptions: RULES_TABLE_PAGE_SIZE_OPTIONS, - }), - [pagination] - ); - - const tableOnChangeCallback = useCallback( - ({ page, sort }: EuiBasicTableOnChange) => { - setSortingOptions({ - field: (sort?.field as RulesSortingFields) ?? INITIAL_SORT_FIELD, // Narrowing EuiBasicTable sorting types - order: sort?.direction ?? 'desc', - }); - setPage(page.index + 1); - setPerPage(page.size); - }, - [setPage, setPerPage, setSortingOptions] - ); - - const rulesColumns = useRulesColumns({ hasCRUDPermissions: hasPermissions }); - const monitoringColumns = useMonitoringColumns({ hasCRUDPermissions: hasPermissions }); - - const handleCreatePrePackagedRules = useCallback(async () => { - if (createPrePackagedRules != null) { - startTransaction({ name: RULES_TABLE_ACTIONS.LOAD_PREBUILT }); - await createPrePackagedRules(); - await reFetchRules(); - } - }, [createPrePackagedRules, reFetchRules, startTransaction]); - - const handleRefreshRules = useCallback(() => { - startTransaction({ name: RULES_TABLE_ACTIONS.REFRESH }); - reFetchRules(); - }, [reFetchRules, startTransaction]); - - const isSelectAllCalled = useRef(false); - - // Synchronize selectedRuleIds with EuiBasicTable's selected rows - useValueChanged((ruleIds) => { - if (tableRef.current != null) { - tableRef.current.setSelection(rules.filter((rule) => ruleIds.includes(rule.id))); - } - }, selectedRuleIds); - - const euiBasicTableSelectionProps = useMemo( - () => ({ - selectable: (item: Rule) => !loadingRuleIds.includes(item.id), - onSelectionChange: (selected: Rule[]) => { - /** - * EuiBasicTable doesn't provide declarative API to control selected rows. - * This limitation requires us to synchronize selection state manually using setSelection(). - * But it creates a chain reaction when the user clicks Select All: - * selectAll() -> setSelection() -> onSelectionChange() -> setSelection(). - * To break the chain we should check whether the onSelectionChange was triggered - * by the Select All action or not. - * - */ - if (isSelectAllCalled.current) { - isSelectAllCalled.current = false; - // Handle special case of unselecting all rules via checkbox - // after all rules were selected via Bulk select. - if (selected.length === 0) { - setIsAllSelected(false); - setSelectedRuleIds([]); - } - } else { - setSelectedRuleIds(selected.map(({ id }) => id)); - setIsAllSelected(false); - } - }, - }), - [loadingRuleIds, setIsAllSelected, setSelectedRuleIds] - ); - - const toggleSelectAll = useCallback(() => { - isSelectAllCalled.current = true; - setIsAllSelected(!isAllSelected); - setSelectedRuleIds(!isAllSelected ? rules.map(({ id }) => id) : []); - }, [rules, isAllSelected, setIsAllSelected, setSelectedRuleIds]); - - const handleAutoRefreshSwitch = useCallback( - (refreshOn: boolean) => { - if (refreshOn) { - reFetchRules(); - } - setIsRefreshOn(refreshOn); - }, - [setIsRefreshOn, reFetchRules] - ); - - const shouldShowRulesTable = useMemo( - (): boolean => showRulesTable({ rulesCustomInstalled, rulesInstalled }) && !isLoading, - [isLoading, rulesCustomInstalled, rulesInstalled] - ); - - const shouldShowPrepackagedRulesPrompt = useMemo( - (): boolean => - rulesCustomInstalled != null && - rulesCustomInstalled === 0 && - prePackagedRuleStatus === 'ruleNotInstalled' && - !isLoading, - [isLoading, prePackagedRuleStatus, rulesCustomInstalled] - ); - - const tableProps = - selectedTab === AllRulesTabs.rules - ? { - 'data-test-subj': 'rules-table', - columns: rulesColumns, - } - : { 'data-test-subj': 'monitoring-table', columns: monitoringColumns }; - - const shouldShowLinearProgress = isFetched && isRefetching; - const shouldShowLoadingOverlay = (!isFetched && isRefetching) || isActionInProgress; - - return ( - <> - {shouldShowLinearProgress && ( - - )} - {shouldShowLoadingOverlay && ( - - )} - {shouldShowRulesTable && ( - - )} - {shouldShowPrepackagedRulesPrompt && ( - - )} - {isLoading && ( - - )} - {isDeleteConfirmationVisible && ( - -

{i18n.DELETE_CONFIRMATION_BODY}

-
- )} - {isBulkActionConfirmationVisible && bulkAction && ( - - )} - {isBulkEditFlyoutVisible && bulkEditActionType !== undefined && ( - - )} - {shouldShowRulesTable && ( - <> - - - - )} - - ); - } -); - -RulesTables.displayName = 'RulesTables'; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.test.tsx deleted file mode 100644 index d283879045165..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.test.tsx +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { shallow } from 'enzyme'; - -import '../../../../../common/mock/match_media'; -import { TestProviders } from '../../../../../common/mock'; -import { EditRulePage } from '.'; -import { useUserData } from '../../../../components/user_info'; -import { useParams } from 'react-router-dom'; -import { useAppToastsMock } from '../../../../../common/hooks/use_app_toasts.mock'; -import { useAppToasts } from '../../../../../common/hooks/use_app_toasts'; - -jest.mock('../../../../../common/lib/kibana'); -jest.mock('../../../../containers/detection_engine/lists/use_lists_config'); -jest.mock('../../../../containers/detection_engine/rules/use_find_rules_query'); -jest.mock('../../../../../common/components/link_to'); -jest.mock('../../../../components/user_info'); -jest.mock('react-router-dom', () => { - const originalModule = jest.requireActual('react-router-dom'); - - return { - ...originalModule, - useHistory: jest.fn(), - useParams: jest.fn(), - }; -}); -jest.mock('../../../../../common/hooks/use_app_toasts'); -jest.mock('../use_get_saved_query', () => ({ - __esModule: true, - useGetSavedQuery: jest.fn().mockReturnValue({}), -})); - -describe('EditRulePage', () => { - let appToastsMock: jest.Mocked>; - - beforeEach(() => { - appToastsMock = useAppToastsMock.create(); - (useAppToasts as jest.Mock).mockReturnValue(appToastsMock); - }); - - it('renders correctly', () => { - (useUserData as jest.Mock).mockReturnValue([{}]); - (useParams as jest.Mock).mockReturnValue({}); - const wrapper = shallow(, { wrappingComponent: TestProviders }); - - expect(wrapper.find('[title="Edit rule settings"]')).toHaveLength(1); - }); -}); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx index f7251806f8f0b..82934d0cccac2 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.test.tsx @@ -15,15 +15,18 @@ import { getActionsStepsData, getHumanizedDuration, getModifiedAboutDetailsData, - getPrePackagedRuleStatus, - getPrePackagedTimelineStatus, + getPrePackagedRuleInstallationStatus, + getPrePackagedTimelineInstallationStatus, determineDetailsValue, fillEmptySeverityMappings, } from './helpers'; -import { mockRuleWithEverything, mockRule } from './all/__mocks__/mock'; +import { + mockRuleWithEverything, + mockRule, +} from '../../../../detection_engine/rule_management_ui/components/rules_table/__mocks__/mock'; import { FilterStateStore } from '@kbn/es-query'; -import type { Rule } from '../../../containers/detection_engine/rules'; +import type { Rule } from '../../../../detection_engine/rule_management/logic'; import type { AboutStepRule, AboutStepRuleDetails, @@ -452,7 +455,7 @@ describe('rule helpers', () => { const rulesInstalled = 0; const rulesNotInstalled = 1; const rulesNotUpdated = 0; - const result: string = getPrePackagedRuleStatus( + const result: string = getPrePackagedRuleInstallationStatus( rulesInstalled, rulesNotInstalled, rulesNotUpdated @@ -465,7 +468,7 @@ describe('rule helpers', () => { const rulesInstalled = 1; const rulesNotInstalled = 0; const rulesNotUpdated = 0; - const result: string = getPrePackagedRuleStatus( + const result: string = getPrePackagedRuleInstallationStatus( rulesInstalled, rulesNotInstalled, rulesNotUpdated @@ -478,7 +481,7 @@ describe('rule helpers', () => { const rulesInstalled = 1; const rulesNotInstalled = 1; const rulesNotUpdated = 0; - const result: string = getPrePackagedRuleStatus( + const result: string = getPrePackagedRuleInstallationStatus( rulesInstalled, rulesNotInstalled, rulesNotUpdated @@ -491,7 +494,7 @@ describe('rule helpers', () => { const rulesInstalled = 1; const rulesNotInstalled = 0; const rulesNotUpdated = 1; - const result: string = getPrePackagedRuleStatus( + const result: string = getPrePackagedRuleInstallationStatus( rulesInstalled, rulesNotInstalled, rulesNotUpdated @@ -504,7 +507,7 @@ describe('rule helpers', () => { const rulesInstalled = undefined; const rulesNotInstalled = undefined; const rulesNotUpdated = undefined; - const result: string = getPrePackagedRuleStatus( + const result: string = getPrePackagedRuleInstallationStatus( rulesInstalled, rulesNotInstalled, rulesNotUpdated @@ -519,7 +522,7 @@ describe('rule helpers', () => { const timelinesInstalled = 0; const timelinesNotInstalled = 1; const timelinesNotUpdated = 0; - const result: string = getPrePackagedTimelineStatus( + const result: string = getPrePackagedTimelineInstallationStatus( timelinesInstalled, timelinesNotInstalled, timelinesNotUpdated @@ -532,7 +535,7 @@ describe('rule helpers', () => { const timelinesInstalled = 1; const timelinesNotInstalled = 0; const timelinesNotUpdated = 0; - const result: string = getPrePackagedTimelineStatus( + const result: string = getPrePackagedTimelineInstallationStatus( timelinesInstalled, timelinesNotInstalled, timelinesNotUpdated @@ -545,7 +548,7 @@ describe('rule helpers', () => { const timelinesInstalled = 1; const timelinesNotInstalled = 1; const timelinesNotUpdated = 0; - const result: string = getPrePackagedTimelineStatus( + const result: string = getPrePackagedTimelineInstallationStatus( timelinesInstalled, timelinesNotInstalled, timelinesNotUpdated @@ -558,7 +561,7 @@ describe('rule helpers', () => { const timelinesInstalled = 1; const timelinesNotInstalled = 0; const timelinesNotUpdated = 1; - const result: string = getPrePackagedTimelineStatus( + const result: string = getPrePackagedTimelineInstallationStatus( timelinesInstalled, timelinesNotInstalled, timelinesNotUpdated @@ -571,7 +574,7 @@ describe('rule helpers', () => { const timelinesInstalled = undefined; const timelinesNotInstalled = undefined; const timelinesNotUpdated = undefined; - const result: string = getPrePackagedTimelineStatus( + const result: string = getPrePackagedTimelineInstallationStatus( timelinesInstalled, timelinesNotInstalled, timelinesNotUpdated diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx index 6995abd54e7fb..216e202052ee7 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx @@ -13,10 +13,10 @@ import { useLocation } from 'react-router-dom'; import styled from 'styled-components'; import { EuiFlexItem } from '@elastic/eui'; import type { + Severity, + SeverityMapping, Threats, Type, - SeverityMapping, - Severity, } from '@kbn/securitysolution-io-ts-alerting-types'; import { ENDPOINT_LIST_ID } from '@kbn/securitysolution-list-constants'; import type { Filter } from '@kbn/es-query'; @@ -29,7 +29,7 @@ import { transformRuleToAlertAction, transformRuleToAlertResponseAction, } from '../../../../../common/detection_engine/transform_actions'; -import type { Rule } from '../../../containers/detection_engine/rules'; +import type { Rule } from '../../../../detection_engine/rule_management/logic'; import type { AboutStepRule, AboutStepRuleDetails, @@ -266,25 +266,25 @@ export const getModifiedAboutDetailsData = (rule: Rule): AboutStepRuleDetails => export const useQuery = () => new URLSearchParams(useLocation().search); -export type PrePackagedRuleStatus = +export type PrePackagedRuleInstallationStatus = | 'ruleInstalled' | 'ruleNotInstalled' | 'ruleNeedUpdate' | 'someRuleUninstall' | 'unknown'; -export type PrePackagedTimelineStatus = +export type PrePackagedTimelineInstallationStatus = | 'timelinesNotInstalled' | 'timelinesInstalled' | 'someTimelineUninstall' | 'timelineNeedUpdate' | 'unknown'; -export const getPrePackagedRuleStatus = ( +export const getPrePackagedRuleInstallationStatus = ( rulesInstalled?: number, rulesNotInstalled?: number, rulesNotUpdated?: number -): PrePackagedRuleStatus => { +): PrePackagedRuleInstallationStatus => { if ( rulesNotInstalled != null && rulesInstalled === 0 && @@ -319,11 +319,11 @@ export const getPrePackagedRuleStatus = ( } return 'unknown'; }; -export const getPrePackagedTimelineStatus = ( +export const getPrePackagedTimelineInstallationStatus = ( timelinesInstalled?: number, timelinesNotInstalled?: number, timelinesNotUpdated?: number -): PrePackagedTimelineStatus => { +): PrePackagedTimelineInstallationStatus => { if ( timelinesNotInstalled != null && timelinesInstalled === 0 && diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx deleted file mode 100644 index 57c0dee2834f7..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; -import React, { useCallback, useMemo, useState } from 'react'; -import { hasUserCRUDPermission } from '../../../../common/utils/privileges'; -import { MlJobUpgradeModal } from '../../../components/modals/ml_job_upgrade_modal'; -import { affectedJobIds } from '../../../components/callouts/ml_job_compatibility_callout/affected_job_ids'; -import { useInstalledSecurityJobs } from '../../../../common/components/ml/hooks/use_installed_security_jobs'; - -import { usePrePackagedRules, importRules } from '../../../containers/detection_engine/rules'; -import { useListsConfig } from '../../../containers/detection_engine/lists/use_lists_config'; -import { getDetectionEngineUrl } from '../../../../common/components/link_to/redirect_to_detection_engine'; -import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; -import { SpyRoute } from '../../../../common/utils/route/spy_routes'; - -import { useUserData } from '../../../components/user_info'; -import { AllRules } from './all'; -import { ImportDataModal } from '../../../../common/components/import_data_modal'; -import { ValueListsFlyout } from '../../../components/value_lists_management_flyout'; -import { UpdatePrePackagedRulesCallOut } from '../../../components/rules/pre_packaged_rules/update_callout'; -import { - getPrePackagedRuleStatus, - getPrePackagedTimelineStatus, - redirectToDetections, -} from './helpers'; -import * as i18n from './translations'; -import { SecurityPageName } from '../../../../app/types'; -import { SecuritySolutionLinkButton } from '../../../../common/components/links'; -import { NeedAdminForUpdateRulesCallOut } from '../../../components/callouts/need_admin_for_update_callout'; -import { MlJobCompatibilityCallout } from '../../../components/callouts/ml_job_compatibility_callout'; -import { MissingPrivilegesCallOut } from '../../../components/callouts/missing_privileges_callout'; -import { APP_UI_ID } from '../../../../../common/constants'; -import { useKibana } from '../../../../common/lib/kibana'; -import { HeaderPage } from '../../../../common/components/header_page'; -import { RulesTableContextProvider } from './all/rules_table/rules_table_context'; -import { useInvalidateRules } from '../../../containers/detection_engine/rules/use_find_rules_query'; -import { useBoolState } from '../../../../common/hooks/use_bool_state'; -import { RULES_TABLE_ACTIONS } from '../../../../common/lib/apm/user_actions'; -import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; - -const RulesPageComponent: React.FC = () => { - const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState(); - const [isValueListFlyoutVisible, showValueListFlyout, hideValueListFlyout] = useBoolState(); - const { navigateToApp } = useKibana().services.application; - const { startTransaction } = useStartTransaction(); - const invalidateRules = useInvalidateRules(); - - const { loading: loadingJobs, jobs } = useInstalledSecurityJobs(); - const legacyJobsInstalled = jobs.filter((job) => affectedJobIds.includes(job.id)); - const [isUpgradeModalVisible, setIsUpgradeModalVisible] = useState(false); - - const [ - { - loading: userInfoLoading, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - canUserCRUD, - hasIndexWrite, - }, - ] = useUserData(); - const { - loading: listsConfigLoading, - canWriteIndex: canWriteListsIndex, - needsConfiguration: needsListsConfiguration, - } = useListsConfig(); - const loading = userInfoLoading || listsConfigLoading; - const { - createPrePackagedRules, - loadingCreatePrePackagedRules, - rulesCustomInstalled, - rulesInstalled, - rulesNotInstalled, - rulesNotUpdated, - timelinesInstalled, - timelinesNotInstalled, - timelinesNotUpdated, - getLoadPrebuiltRulesAndTemplatesButton, - getReloadPrebuiltRulesAndTemplatesButton, - } = usePrePackagedRules({ - canUserCRUD, - hasIndexWrite, - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - }); - const prePackagedRuleStatus = getPrePackagedRuleStatus( - rulesInstalled, - rulesNotInstalled, - rulesNotUpdated - ); - - const prePackagedTimelineStatus = getPrePackagedTimelineStatus( - timelinesInstalled, - timelinesNotInstalled, - timelinesNotUpdated - ); - - const handleCreatePrePackagedRules = useCallback(async () => { - if (createPrePackagedRules != null) { - startTransaction({ name: RULES_TABLE_ACTIONS.LOAD_PREBUILT }); - await createPrePackagedRules(); - } - }, [createPrePackagedRules, startTransaction]); - - // Wrapper to add confirmation modal for users who may be running older ML Jobs that would - // be overridden by updating their rules. For details, see: https://github.com/elastic/kibana/issues/128121 - const mlJobUpgradeModalConfirm = useCallback(async () => { - setIsUpgradeModalVisible(false); - await handleCreatePrePackagedRules(); - }, [handleCreatePrePackagedRules, setIsUpgradeModalVisible]); - - const showMlJobUpgradeModal = useCallback(async () => { - if (legacyJobsInstalled.length > 0) { - setIsUpgradeModalVisible(true); - } else { - await handleCreatePrePackagedRules(); - } - }, [handleCreatePrePackagedRules, legacyJobsInstalled.length]); - - const loadPrebuiltRulesAndTemplatesButton = useMemo( - () => - getLoadPrebuiltRulesAndTemplatesButton({ - isDisabled: !hasUserCRUDPermission(canUserCRUD) || loading || loadingJobs, - onClick: showMlJobUpgradeModal, - }), - [ - canUserCRUD, - getLoadPrebuiltRulesAndTemplatesButton, - showMlJobUpgradeModal, - loading, - loadingJobs, - ] - ); - - const reloadPrebuiltRulesAndTemplatesButton = useMemo( - () => - getReloadPrebuiltRulesAndTemplatesButton({ - isDisabled: !hasUserCRUDPermission(canUserCRUD) || loading || loadingJobs, - onClick: showMlJobUpgradeModal, - }), - [ - canUserCRUD, - getReloadPrebuiltRulesAndTemplatesButton, - showMlJobUpgradeModal, - loading, - loadingJobs, - ] - ); - - if ( - redirectToDetections( - isSignalIndexExists, - isAuthenticated, - hasEncryptionKey, - needsListsConfiguration - ) - ) { - navigateToApp(APP_UI_ID, { - deepLinkId: SecurityPageName.alerts, - path: getDetectionEngineUrl(), - }); - return null; - } - - return ( - <> - - - - {isUpgradeModalVisible && ( - setIsUpgradeModalVisible(false)} - onConfirm={mlJobUpgradeModalConfirm} - /> - )} - - - - - - - - {loadPrebuiltRulesAndTemplatesButton && ( - {loadPrebuiltRulesAndTemplatesButton} - )} - {reloadPrebuiltRulesAndTemplatesButton && ( - {reloadPrebuiltRulesAndTemplatesButton} - )} - - - - {i18n.IMPORT_VALUE_LISTS} - - - - - - {i18n.IMPORT_RULE} - - - - - {i18n.ADD_NEW_RULE} - - - - - {(prePackagedRuleStatus === 'ruleNeedUpdate' || - prePackagedTimelineStatus === 'timelineNeedUpdate') && ( - - )} - - - - - - - ); -}; - -export const RulesPage = React.memo(RulesPageComponent); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts index 950191acad3d9..81ebc4b24cf9c 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/types.ts @@ -9,12 +9,12 @@ import type { List } from '@kbn/securitysolution-io-ts-list-types'; import type { RiskScoreMapping, + Severity, + SeverityMapping, ThreatIndex, ThreatMapping, Threats, Type, - SeverityMapping, - Severity, } from '@kbn/securitysolution-io-ts-alerting-types'; import type { DataViewBase, Filter } from '@kbn/es-query'; import type { RuleAction } from '@kbn/alerting-plugin/common'; @@ -25,16 +25,16 @@ import type { FieldValueQueryBar } from '../../../components/rules/query_bar'; import type { FieldValueTimeline } from '../../../components/rules/pick_timeline'; import type { FieldValueThreshold } from '../../../components/rules/threshold_input'; import type { - Author, BuildingBlockType, - License, RelatedIntegrationArray, RequiredFieldArray, + RuleAuthorArray, + RuleLicense, RuleNameOverride, - SortOrder, SetupGuide, TimestampOverride, -} from '../../../../../common/detection_engine/schemas/common'; +} from '../../../../../common/detection_engine/rule_schema'; +import type { SortOrder } from '../../../../../common/detection_engine/schemas/common'; import type { EqlOptionsSelected } from '../../../../../common/search_strategy'; import type { RuleResponseAction, @@ -215,12 +215,12 @@ export interface DefineStepRuleJson { } export interface AboutStepRuleJson { - author: Author; + author: RuleAuthorArray; building_block_type?: BuildingBlockType; exceptions_list?: List[]; name: string; description: string; - license: License; + license: RuleLicense; severity: string; severity_mapping: SeverityMapping; risk_score: number; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/use_get_saved_query.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/use_get_saved_query.ts index 5cd530754d8ce..fe113defb4eac 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/use_get_saved_query.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/use_get_saved_query.ts @@ -36,7 +36,10 @@ export const useGetSavedQuery = ( const query = useQuery( ['detectionEngine', 'rule', 'savedQuery', savedQueryId], async () => { - if (!savedQueryId) { + // load saved query only if rule type === 'saved_query', as other rule types still can have saved_id property that is not used + // Rule schema allows to save any rule with saved_id property, but it only used for saved_query rule type + // In future we might look in possibility to restrict rule schema (breaking change!) and remove saved_id from the rest of rules through migration + if (!savedQueryId || ruleType !== 'saved_query') { return null; } @@ -44,10 +47,6 @@ export const useGetSavedQuery = ( }, { onError: onError ?? defaultErrorHandler, - // load saved query only if rule type === 'saved_query', as other rule types still can have saved_id property that is not used - // Rule schema allows to save any rule with saved_id property, but it only used for saved_query rule type - // In future we might look in possibility to restrict rule schema (breaking change!) and remove saved_id from the rest of rules through migration - enabled: Boolean(savedQueryId) && ruleType === 'saved_query', retry: false, } ); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts index 26f23bba9591d..5c04e749e481d 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts @@ -20,7 +20,10 @@ import { DEFAULT_THREAT_MATCH_QUERY, RULES_PATH } from '../../../../../common/co import type { AboutStepRule, DefineStepRule, RuleStepsOrder, ScheduleStepRule } from './types'; import { DataSourceType, RuleStep } from './types'; import type { GetSecuritySolutionUrl } from '../../../../common/components/link_to'; -import { RuleDetailTabs, RULE_DETAILS_TAB_NAME } from './details'; +import { + RuleDetailTabs, + RULE_DETAILS_TAB_NAME, +} from '../../../../detection_engine/rule_details_ui/pages/rule_details'; import { fillEmptySeverityMappings } from './helpers'; export const ruleStepsOrder: RuleStepsOrder = [ diff --git a/x-pack/plugins/security_solution/public/exceptions/routes.tsx b/x-pack/plugins/security_solution/public/exceptions/routes.tsx index 512baa600e298..b977a98722444 100644 --- a/x-pack/plugins/security_solution/public/exceptions/routes.tsx +++ b/x-pack/plugins/security_solution/public/exceptions/routes.tsx @@ -11,7 +11,7 @@ import { Route } from '@kbn/kibana-react-plugin/public'; import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; import * as i18n from './translations'; import { EXCEPTIONS_PATH, SecurityPageName } from '../../common/constants'; -import { ExceptionListsTable } from '../detections/pages/detection_engine/rules/all/exceptions/exceptions_table'; +import { ExceptionListsTable } from '../detection_engine/rule_exceptions_ui/pages/exceptions/exceptions_table'; import { SpyRoute } from '../common/utils/route/spy_routes'; import { NotFoundPage } from '../app/404'; import { useReadonlyHeader } from '../use_readonly_header'; diff --git a/x-pack/plugins/security_solution/public/rules/routes.tsx b/x-pack/plugins/security_solution/public/rules/routes.tsx index 633b4005110af..5cfaae23907d2 100644 --- a/x-pack/plugins/security_solution/public/rules/routes.tsx +++ b/x-pack/plugins/security_solution/public/rules/routes.tsx @@ -12,13 +12,13 @@ import { TrackApplicationView } from '@kbn/usage-collection-plugin/public'; import * as i18n from './translations'; import { RULES_PATH, SecurityPageName } from '../../common/constants'; import { NotFoundPage } from '../app/404'; -import { RulesPage } from '../detections/pages/detection_engine/rules'; -import { CreateRulePage } from '../detections/pages/detection_engine/rules/create'; +import { RulesPage } from '../detection_engine/rule_management_ui/pages/rule_management'; +import { CreateRulePage } from '../detection_engine/rule_creation_ui/pages/rule_creation'; import { RuleDetailsPage, RuleDetailTabs, -} from '../detections/pages/detection_engine/rules/details'; -import { EditRulePage } from '../detections/pages/detection_engine/rules/edit'; +} from '../detection_engine/rule_details_ui/pages/rule_details'; +import { EditRulePage } from '../detection_engine/rule_creation_ui/pages/rule_editing'; import { useReadonlyHeader } from '../use_readonly_header'; import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper'; import { SpyRoute } from '../common/utils/route/spy_routes'; diff --git a/x-pack/plugins/security_solution/public/timelines/containers/api.test.ts b/x-pack/plugins/security_solution/public/timelines/containers/api.test.ts index 0d74241ed88bc..3f71bb099ed63 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/api.test.ts +++ b/x-pack/plugins/security_solution/public/timelines/containers/api.test.ts @@ -9,7 +9,7 @@ import * as api from './api'; import { KibanaServices } from '../../common/lib/kibana'; import { TimelineType, TimelineStatus } from '../../../common/types/timeline'; import { TIMELINE_DRAFT_URL, TIMELINE_URL } from '../../../common/constants'; -import type { ImportDataProps } from '../../detections/containers/detection_engine/rules/types'; +import type { ImportDataProps } from '../../detection_engine/rule_management/logic/types'; jest.mock('../../common/lib/kibana', () => { return { diff --git a/x-pack/plugins/security_solution/public/timelines/containers/api.ts b/x-pack/plugins/security_solution/public/timelines/containers/api.ts index cdabd37b443fe..f81910ff8013e 100644 --- a/x-pack/plugins/security_solution/public/timelines/containers/api.ts +++ b/x-pack/plugins/security_solution/public/timelines/containers/api.ts @@ -49,7 +49,7 @@ import type { ExportDocumentsProps, ImportDataProps, ImportDataResponse, -} from '../../detections/containers/detection_engine/rules'; +} from '../../detection_engine/rule_management/logic'; import type { TimelineInput } from '../../../common/search_strategy'; interface RequestPostTimeline { diff --git a/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts index da52432571f97..d4a60be85d3ea 100644 --- a/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts +++ b/x-pack/plugins/security_solution/server/fleet_integration/handlers/install_prepackaged_rules.ts @@ -9,7 +9,7 @@ import type { KibanaRequest, Logger } from '@kbn/core/server'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; import type { PluginStartContract as AlertsStartContract } from '@kbn/alerting-plugin/server'; import { createDetectionIndex } from '../../lib/detection_engine/routes/index/create_index_route'; -import { createPrepackagedRules } from '../../lib/detection_engine/routes/rules/add_prepackaged_rules_route'; +import { createPrepackagedRules } from '../../lib/detection_engine/prebuilt_rules'; import type { SecuritySolutionApiRequestHandlerContext } from '../../types'; export interface InstallPrepackagedRulesProps { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet/get_installed_integrations/installed_integration_set.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/installed_integration_set.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet/get_installed_integrations/installed_integration_set.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/installed_integration_set.ts index e124e0322192c..156d1c99fde5d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet/get_installed_integrations/installed_integration_set.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/installed_integration_set.ts @@ -14,7 +14,7 @@ import type { InstalledPackage, InstalledPackageArray, InstalledPackageBasicInfo, -} from '../../../../../../common/detection_engine/schemas/common'; +} from '../../../../../../common/detection_engine/fleet_integrations'; export interface IInstalledIntegrationSet { addPackagePolicy(policy: PackagePolicy): void; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet/get_installed_integrations/get_installed_integrations_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet/get_installed_integrations/get_installed_integrations_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts index 9e9091e1b578c..7b904c282e1e4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/fleet/get_installed_integrations/get_installed_integrations_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/get_installed_integrations/route.ts @@ -8,11 +8,11 @@ import type { Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { initPromisePool } from '../../../../../utils/promise_pool'; -import { buildSiemResponse } from '../../utils'; +import { buildSiemResponse } from '../../../routes/utils'; import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import { DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL } from '../../../../../../common/constants'; -import type { GetInstalledIntegrationsResponse } from '../../../../../../common/detection_engine/schemas/response/get_installed_integrations_response_schema'; +import type { GetInstalledIntegrationsResponse } from '../../../../../../common/detection_engine/fleet_integrations'; +import { GET_INSTALLED_INTEGRATIONS_URL } from '../../../../../../common/detection_engine/fleet_integrations'; import { createInstalledIntegrationSet } from './installed_integration_set'; const MAX_CONCURRENT_REQUESTS_TO_PACKAGE_REGISTRY = 5; @@ -26,7 +26,7 @@ export const getInstalledIntegrationsRoute = ( ) => { router.get( { - path: DETECTION_ENGINE_INSTALLED_INTEGRATIONS_URL, + path: GET_INSTALLED_INTEGRATIONS_URL, validate: {}, options: { tags: ['access:securitySolution'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/register_routes.ts new file mode 100644 index 0000000000000..2c6c2c2ae21f8 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/api/register_routes.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { SecuritySolutionPluginRouter } from '../../../../types'; + +import { getInstalledIntegrationsRoute } from './get_installed_integrations/route'; + +export const registerFleetIntegrationsRoutes = ( + router: SecuritySolutionPluginRouter, + logger: Logger +) => { + getInstalledIntegrationsRoute(router, logger); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/index.ts new file mode 100644 index 0000000000000..c0123e587d9bf --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/fleet_integrations/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/register_routes'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts similarity index 89% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts index 5853aecf13021..fd7351c677a2a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.test.ts @@ -5,24 +5,24 @@ * 2.0. */ -import { getPrepackagedRulesStatusRoute } from './get_prepackaged_rules_status_route'; +import { getPrebuiltRulesAndTimelinesStatusRoute } from './route'; import { getEmptyFindResult, getFindResultWithSingleHit, getPrepackagedRulesStatusRequest, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, createMockConfig } from '../__mocks__'; +} from '../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, createMockConfig } from '../../../routes/__mocks__'; import type { SecurityPluginSetup } from '@kbn/security-plugin/server'; -import { checkTimelinesStatus } from '../../../timeline/utils/check_timelines_status'; +import { checkTimelinesStatus } from '../../../../timeline/utils/check_timelines_status'; import { mockCheckTimelinesStatusBeforeInstallResult, mockCheckTimelinesStatusAfterInstallResult, -} from '../../../timeline/__mocks__/import_timelines'; +} from '../../../../timeline/__mocks__/import_timelines'; -jest.mock('../../rules/get_prepackaged_rules', () => { +jest.mock('../../logic/get_latest_prebuilt_rules', () => { return { - getLatestPrepackagedRules: async () => { + getLatestPrebuiltRules: async () => { return [ { rule_id: 'rule-1', @@ -43,8 +43,8 @@ jest.mock('../../rules/get_prepackaged_rules', () => { }; }); -jest.mock('../../../timeline/utils/check_timelines_status', () => { - const actual = jest.requireActual('../../../timeline/utils/check_timelines_status'); +jest.mock('../../../../timeline/utils/check_timelines_status', () => { + const actual = jest.requireActual('../../../../timeline/utils/check_timelines_status'); return { ...actual, checkTimelinesStatus: jest.fn(), @@ -82,7 +82,7 @@ describe('get_prepackaged_rule_status_route', () => { prepackagedTimelines: [], }); - getPrepackagedRulesStatusRoute(server.router, createMockConfig(), securitySetup); + getPrebuiltRulesAndTimelinesStatusRoute(server.router, createMockConfig(), securitySetup); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts new file mode 100644 index 0000000000000..e8f947b0540c1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_and_timelines_status/route.ts @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { transformError } from '@kbn/securitysolution-es-utils'; +import { validate } from '@kbn/securitysolution-io-ts-utils'; +import { buildSiemResponse } from '../../../routes/utils'; +import type { ConfigType } from '../../../../../config'; +import type { SetupPlugins } from '../../../../../plugin'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; + +import { + PREBUILT_RULES_STATUS_URL, + GetPrebuiltRulesAndTimelinesStatusResponse, +} from '../../../../../../common/detection_engine/prebuilt_rules'; + +import { getExistingPrepackagedRules } from '../../../rule_management/logic/search/get_existing_prepackaged_rules'; +import { findRules } from '../../../rule_management/logic/search/find_rules'; +import { getLatestPrebuiltRules } from '../../logic/get_latest_prebuilt_rules'; +import { getRulesToInstall } from '../../logic/get_rules_to_install'; +import { getRulesToUpdate } from '../../logic/get_rules_to_update'; +import { ruleAssetSavedObjectsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; +import { rulesToMap } from '../../logic/utils'; + +import { buildFrameworkRequest } from '../../../../timeline/utils/common'; +import { + checkTimelinesStatus, + checkTimelineStatusRt, +} from '../../../../timeline/utils/check_timelines_status'; + +export const getPrebuiltRulesAndTimelinesStatusRoute = ( + router: SecuritySolutionPluginRouter, + config: ConfigType, + security: SetupPlugins['security'] +) => { + router.get( + { + path: PREBUILT_RULES_STATUS_URL, + validate: false, + options: { + tags: ['access:securitySolution'], + }, + }, + async (context, request, response) => { + const siemResponse = buildSiemResponse(response); + const ctx = await context.resolve(['core', 'alerting']); + const savedObjectsClient = ctx.core.savedObjects.client; + const rulesClient = ctx.alerting.getRulesClient(); + const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); + + try { + const latestPrebuiltRules = await getLatestPrebuiltRules( + ruleAssetsClient, + config.prebuiltRulesFromFileSystem, + config.prebuiltRulesFromSavedObjects + ); + + const customRules = await findRules({ + rulesClient, + perPage: 1, + page: 1, + sortField: 'enabled', + sortOrder: 'desc', + filter: 'alert.attributes.params.immutable: false', + fields: undefined, + }); + + const installedPrebuiltRules = rulesToMap( + await getExistingPrepackagedRules({ rulesClient }) + ); + + const rulesToInstall = getRulesToInstall(latestPrebuiltRules, installedPrebuiltRules); + const rulesToUpdate = getRulesToUpdate(latestPrebuiltRules, installedPrebuiltRules); + + const frameworkRequest = await buildFrameworkRequest(context, security, request); + const prebuiltTimelineStatus = await checkTimelinesStatus(frameworkRequest); + const [validatedPrebuiltTimelineStatus] = validate( + prebuiltTimelineStatus, + checkTimelineStatusRt + ); + + const responseBody: GetPrebuiltRulesAndTimelinesStatusResponse = { + rules_custom_installed: customRules.total, + rules_installed: installedPrebuiltRules.size, + rules_not_installed: rulesToInstall.length, + rules_not_updated: rulesToUpdate.length, + timelines_installed: validatedPrebuiltTimelineStatus?.prepackagedTimelines.length ?? 0, + timelines_not_installed: validatedPrebuiltTimelineStatus?.timelinesToInstall.length ?? 0, + timelines_not_updated: validatedPrebuiltTimelineStatus?.timelinesToUpdate.length ?? 0, + }; + + const [validatedBody, validationError] = validate( + responseBody, + GetPrebuiltRulesAndTimelinesStatusResponse + ); + + if (validationError != null) { + return siemResponse.error({ statusCode: 500, body: validationError }); + } else { + return response.ok({ body: validatedBody ?? {} }); + } + } catch (err) { + const error = transformError(err); + return siemResponse.error({ + body: error.message, + statusCode: error.statusCode, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.test.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.test.ts index 6c6cfde2cbaa8..f529369438742 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.test.ts @@ -11,28 +11,30 @@ import { getFindResultWithSingleHit, getRuleMock, getBasicEmptySearchResponse, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock } from '../__mocks__'; -import type { AddPrepackagedRulesSchema } from '../../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import { addPrepackedRulesRoute, createPrepackagedRules } from './add_prepackaged_rules_route'; +} from '../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock } from '../../../routes/__mocks__'; +import type { PrebuiltRuleToInstall } from '../../../../../../common/detection_engine/prebuilt_rules'; +import { installPrebuiltRulesAndTimelinesRoute, createPrepackagedRules } from './route'; import { listMock } from '@kbn/lists-plugin/server/mocks'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; -import { installPrepackagedTimelines } from '../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; +import { installPrepackagedTimelines } from '../../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { legacyMigrate } from '../../rules/utils'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; +import { legacyMigrate } from '../../../rule_management'; -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +jest.mock('../../../rule_management/logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual( + '../../../rule_management/logic/rule_actions/legacy_action_migration' + ); return { ...actual, legacyMigrate: jest.fn(), }; }); -jest.mock('../../rules/get_prepackaged_rules', () => { +jest.mock('../../logic/get_latest_prebuilt_rules', () => { return { - getLatestPrepackagedRules: async (): Promise => { + getLatestPrebuiltRules: async (): Promise => { return [ { author: ['Elastic'], @@ -66,7 +68,7 @@ jest.mock('../../rules/get_prepackaged_rules', () => { }; }); -jest.mock('../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines', () => { +jest.mock('../../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines', () => { return { installPrepackagedTimelines: jest.fn().mockResolvedValue({ success: true, @@ -105,7 +107,7 @@ describe('add_prepackaged_rules_route', () => { context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse()) ); - addPrepackedRulesRoute(server.router); + installPrebuiltRulesAndTimelinesRoute(server.router); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts similarity index 71% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts index 9960101f399c7..4399627692e22 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/add_prepackaged_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/install_prebuilt_rules_and_timelines/route.ts @@ -13,30 +13,30 @@ import type { ExceptionListClient } from '@kbn/lists-plugin/server'; import type { SecuritySolutionApiRequestHandlerContext, SecuritySolutionPluginRouter, -} from '../../../../types'; - -import type { PrePackagedRulesAndTimelinesSchema } from '../../../../../common/detection_engine/schemas/response/prepackaged_rules_schema'; -import { prePackagedRulesAndTimelinesSchema } from '../../../../../common/detection_engine/schemas/response/prepackaged_rules_schema'; -import { importTimelineResultSchema } from '../../../../../common/types/timeline'; -import { DETECTION_ENGINE_PREPACKAGED_URL } from '../../../../../common/constants'; - -import { getLatestPrepackagedRules } from '../../rules/get_prepackaged_rules'; -import { installPrepackagedRules } from '../../rules/install_prepacked_rules'; -import { updatePrepackagedRules } from '../../rules/update_prepacked_rules'; -import { getRulesToInstall } from '../../rules/get_rules_to_install'; -import { getRulesToUpdate } from '../../rules/get_rules_to_update'; -import { getExistingPrepackagedRules } from '../../rules/get_existing_prepackaged_rules'; -import { ruleAssetSavedObjectsClientFactory } from '../../rules/rule_asset/rule_asset_saved_objects_client'; - -import { buildSiemResponse } from '../utils'; - -import { installPrepackagedTimelines } from '../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; -import { rulesToMap } from '../../rules/utils'; - -export const addPrepackedRulesRoute = (router: SecuritySolutionPluginRouter) => { +} from '../../../../../types'; + +import { + PREBUILT_RULES_URL, + InstallPrebuiltRulesAndTimelinesResponse, +} from '../../../../../../common/detection_engine/prebuilt_rules'; +import { importTimelineResultSchema } from '../../../../../../common/types/timeline'; + +import { getExistingPrepackagedRules } from '../../../rule_management/logic/search/get_existing_prepackaged_rules'; +import { getLatestPrebuiltRules } from '../../logic/get_latest_prebuilt_rules'; +import { createPrebuiltRules } from '../../logic/create_prebuilt_rules'; +import { updatePrebuiltRules } from '../../logic/update_prebuilt_rules'; +import { getRulesToInstall } from '../../logic/get_rules_to_install'; +import { getRulesToUpdate } from '../../logic/get_rules_to_update'; +import { ruleAssetSavedObjectsClientFactory } from '../../logic/rule_asset/rule_asset_saved_objects_client'; +import { rulesToMap } from '../../logic/utils'; + +import { installPrepackagedTimelines } from '../../../../timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; +import { buildSiemResponse } from '../../../routes/utils'; + +export const installPrebuiltRulesAndTimelinesRoute = (router: SecuritySolutionPluginRouter) => { router.put( { - path: DETECTION_ENGINE_PREPACKAGED_URL, + path: PREBUILT_RULES_URL, validate: false, options: { tags: ['access:securitySolution'], @@ -84,7 +84,7 @@ export const createPrepackagedRules = async ( context: SecuritySolutionApiRequestHandlerContext, rulesClient: RulesClient, exceptionsClient?: ExceptionListClient -): Promise => { +): Promise => { const config = context.getConfig(); const frameworkRequest = context.getFrameworkRequest(); const savedObjectsClient = context.core.savedObjects.client; @@ -107,7 +107,7 @@ export const createPrepackagedRules = async ( await exceptionsListClient.createEndpointList(); } - const latestPrepackagedRulesMap = await getLatestPrepackagedRules( + const latestPrepackagedRulesMap = await getLatestPrebuiltRules( ruleAssetsClient, prebuiltRulesFromFileSystem, prebuiltRulesFromSavedObjects @@ -116,7 +116,8 @@ export const createPrepackagedRules = async ( const rulesToInstall = getRulesToInstall(latestPrepackagedRulesMap, installedPrePackagedRules); const rulesToUpdate = getRulesToUpdate(latestPrepackagedRulesMap, installedPrePackagedRules); - await installPrepackagedRules(rulesClient, rulesToInstall); + await createPrebuiltRules(rulesClient, rulesToInstall); + const timeline = await installPrepackagedTimelines( maxTimelineImportExportSize, frameworkRequest, @@ -126,28 +127,32 @@ export const createPrepackagedRules = async ( timeline, importTimelineResultSchema ); - await updatePrepackagedRules( + + await updatePrebuiltRules( rulesClient, savedObjectsClient, rulesToUpdate, context.getRuleExecutionLog() ); - const prepackagedRulesOutput: PrePackagedRulesAndTimelinesSchema = { + const prepackagedRulesOutput: InstallPrebuiltRulesAndTimelinesResponse = { rules_installed: rulesToInstall.length, rules_updated: rulesToUpdate.length, timelines_installed: prepackagedTimelinesResult?.timelines_installed ?? 0, timelines_updated: prepackagedTimelinesResult?.timelines_updated ?? 0, }; + const [validated, genericErrors] = validate( prepackagedRulesOutput, - prePackagedRulesAndTimelinesSchema + InstallPrebuiltRulesAndTimelinesResponse ); + if (genericErrors != null && timelinesErrors != null) { throw new PrepackagedRulesError( [genericErrors, timelinesErrors].filter((msg) => msg != null).join(', '), 500 ); } + return validated; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts new file mode 100644 index 0000000000000..39e822af3e147 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/register_routes.ts @@ -0,0 +1,22 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ConfigType } from '../../../../config'; +import type { SetupPlugins } from '../../../../plugin_contract'; +import type { SecuritySolutionPluginRouter } from '../../../../types'; + +import { getPrebuiltRulesAndTimelinesStatusRoute } from './get_prebuilt_rules_and_timelines_status/route'; +import { installPrebuiltRulesAndTimelinesRoute } from './install_prebuilt_rules_and_timelines/route'; + +export const registerPrebuiltRulesRoutes = ( + router: SecuritySolutionPluginRouter, + config: ConfigType, + security: SetupPlugins['security'] +) => { + getPrebuiltRulesAndTimelinesStatusRoute(router, config, security); + installPrebuiltRulesAndTimelinesRoute(router); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/apm_403_response_to_a_post.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/apm_403_response_to_a_post.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/apm_403_response_to_a_post.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/apm_403_response_to_a_post.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/apm_405_response_method_not_allowed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/apm_405_response_method_not_allowed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/apm_405_response_method_not_allowed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/apm_405_response_method_not_allowed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/apm_sqlmap_user_agent.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/apm_sqlmap_user_agent.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/apm_sqlmap_user_agent.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/apm_sqlmap_user_agent.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_cloudtrail_logging_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_cloudtrail_logging_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_cloudtrail_logging_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_cloudtrail_logging_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_email_powershell_exchange_mailbox.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_email_powershell_exchange_mailbox.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_email_powershell_exchange_mailbox.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_gcp_pub_sub_subscription_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_gcp_pub_sub_topic_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_google_drive_ownership_transferred_via_google_workspace.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_google_drive_ownership_transferred_via_google_workspace.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_google_drive_ownership_transferred_via_google_workspace.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_google_drive_ownership_transferred_via_google_workspace.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_google_workspace_custom_gmail_route_created_or_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_google_workspace_custom_gmail_route_created_or_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_google_workspace_custom_gmail_route_created_or_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_google_workspace_custom_gmail_route_created_or_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_microsoft_365_new_inbox_rule.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_audio_capture.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_posh_audio_capture.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_audio_capture.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_posh_audio_capture.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_keylogger.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_posh_keylogger.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_keylogger.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_posh_keylogger.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_screen_grabber.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_posh_screen_grabber.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_posh_screen_grabber.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_posh_screen_grabber.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_update_event_hub_auth_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_update_event_hub_auth_rule.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_update_event_hub_auth_rule.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_update_event_hub_auth_rule.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_winrar_encryption.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/collection_winrar_encryption.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/collection_winrar_encryption.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_certutil_network_connection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_certutil_network_connection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_certutil_network_connection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_cobalt_strike_beacon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_beacon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_cobalt_strike_beacon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_default_teamserver_cert.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_cobalt_strike_default_teamserver_cert.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_cobalt_strike_default_teamserver_cert.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_cobalt_strike_default_teamserver_cert.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_common_webservices.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_common_webservices.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_common_webservices.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_connection_attempt_by_non_ssh_root_session.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_connection_attempt_by_non_ssh_root_session.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_connection_attempt_by_non_ssh_root_session.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_connection_attempt_by_non_ssh_root_session.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_dns_tunneling_nslookup.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_download_rar_powershell_from_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_encrypted_channel_freesslcert.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_encrypted_channel_freesslcert.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_encrypted_channel_freesslcert.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_encrypted_channel_freesslcert.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_fin7_c2_behavior.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_fin7_c2_behavior.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_fin7_c2_behavior.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_fin7_c2_behavior.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_halfbaked_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_halfbaked_beacon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_halfbaked_beacon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_halfbaked_beacon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_iexplore_via_com.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_iexplore_via_com.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_iexplore_via_com.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_linux_iodine_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_linux_iodine_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_linux_iodine_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_linux_iodine_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_dns_tunneling.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_dns_tunneling.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_dns_tunneling.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_dns_tunneling.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_rare_dns_question.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_rare_dns_question.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_rare_dns_question.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_rare_dns_question.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_rare_urls.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_rare_urls.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_rare_urls.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_rare_urls.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_rare_user_agent.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_rare_user_agent.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_ml_packetbeat_rare_user_agent.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_ml_packetbeat_rare_user_agent.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_nat_traversal_port_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_nat_traversal_port_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_nat_traversal_port_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_nat_traversal_port_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_26_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_port_26_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_26_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_port_26_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_port_forwarding_added_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_port_forwarding_added_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_port_forwarding_added_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_rdp_remote_desktop_protocol_from_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_rdp_tunnel_plink.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_rdp_tunnel_plink.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_rdp_tunnel_plink.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_desktopimgdownldr.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_mpcmdrun.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_powershell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_powershell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_scripts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_remote_file_copy_scripts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_remote_file_copy_scripts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_sunburst_c2_activity_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_teamviewer_remote_file_copy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_telnet_port_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_telnet_port_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_telnet_port_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_telnet_port_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tunneling_via_earthworm.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_tunneling_via_earthworm.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_tunneling_via_earthworm.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_tunneling_via_earthworm.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_vnc_virtual_network_computing_from_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_vnc_virtual_network_computing_from_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_vnc_virtual_network_computing_from_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_vnc_virtual_network_computing_from_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_vnc_virtual_network_computing_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_vnc_virtual_network_computing_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/command_and_control_vnc_virtual_network_computing_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/command_and_control_vnc_virtual_network_computing_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_access_to_browser_credentials_procargs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_access_to_browser_credentials_procargs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_access_to_browser_credentials_procargs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_access_to_browser_credentials_procargs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_attempted_bypass_of_okta_mfa.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_attempted_bypass_of_okta_mfa.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_attempted_bypass_of_okta_mfa.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_attempted_bypass_of_okta_mfa.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_attempts_to_brute_force_okta_user_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_attempts_to_brute_force_okta_user_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_attempts_to_brute_force_okta_user_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_attempts_to_brute_force_okta_user_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_aws_iam_assume_role_brute_force.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_azure_full_network_packet_capture_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_azure_full_network_packet_capture_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_azure_full_network_packet_capture_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_azure_full_network_packet_capture_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_admin_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_admin_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_admin_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_admin_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_followed_by_success.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_followed_by_success.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_followed_by_success.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_followed_by_success.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_same_srcip.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_same_srcip.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_same_srcip.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_multiple_logon_failure_same_srcip.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_bruteforce_passowrd_guessing.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_cmdline_dump_tool.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cmdline_dump_tool.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_cmdline_dump_tool.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_collection_sensitive_files.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_collection_sensitive_files.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_collection_sensitive_files.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_collection_sensitive_files.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cookies_chromium_browsers_debugging.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_cookies_chromium_browsers_debugging.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_cookies_chromium_browsers_debugging.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_cookies_chromium_browsers_debugging.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_copy_ntds_sam_volshadowcp_cmdline.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_credential_dumping_msbuild.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credential_dumping_msbuild.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_credential_dumping_msbuild.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credentials_keychains.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_credentials_keychains.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_credentials_keychains.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_credentials_keychains.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dcsync_replication_rights.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dcsync_replication_rights.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dcsync_replication_rights.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dcsync_replication_rights.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_disable_kerberos_preauth.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_disable_kerberos_preauth.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_disable_kerberos_preauth.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_disable_kerberos_preauth.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_domain_backup_dpapi_private_keys.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dump_registry_hives.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dump_registry_hives.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dump_registry_hives.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dumping_hashes_bi_cmds.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dumping_hashes_bi_cmds.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dumping_hashes_bi_cmds.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dumping_hashes_bi_cmds.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dumping_keychain_security.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dumping_keychain_security.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_dumping_keychain_security.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_dumping_keychain_security.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_endgame_cred_dumping_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_endgame_cred_dumping_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_endgame_cred_dumping_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_endgame_cred_dumping_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_endgame_cred_dumping_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_endgame_cred_dumping_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_endgame_cred_dumping_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_endgame_cred_dumping_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_generic_localdumps.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_generic_localdumps.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_generic_localdumps.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_generic_localdumps.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_iam_user_addition_to_group.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iam_user_addition_to_group.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_iam_user_addition_to_group.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iis_apppoolsa_pwd_appcmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_iis_apppoolsa_pwd_appcmd.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iis_apppoolsa_pwd_appcmd.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_iis_apppoolsa_pwd_appcmd.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iis_connectionstrings_dumping.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_iis_connectionstrings_dumping.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_iis_connectionstrings_dumping.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_iis_connectionstrings_dumping.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_kerberoasting_unusual_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberoasting_unusual_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_kerberoasting_unusual_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberosdump_kcc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_kerberosdump_kcc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_kerberosdump_kcc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_kerberosdump_kcc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_key_vault_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_key_vault_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_key_vault_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_key_vault_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_keychain_pwd_retrieval_security_cmd.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_handle_via_malseclogon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_lsass_handle_via_malseclogon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_handle_via_malseclogon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_lsass_handle_via_malseclogon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_lsass_memdump_file_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_file_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_lsass_memdump_file_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_handle_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_lsass_memdump_handle_access.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_lsass_memdump_handle_access.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_lsass_memdump_handle_access.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mfa_push_brute_force.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mfa_push_brute_force.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mfa_push_brute_force.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mfa_push_brute_force.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_microsoft_365_brute_force_user_account_attempt.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_microsoft_365_potential_password_spraying_attack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mimikatz_memssp_default_logs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_powershell_module.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mimikatz_powershell_module.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mimikatz_powershell_module.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mimikatz_powershell_module.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mitm_localhost_webproxy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mitm_localhost_webproxy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mitm_localhost_webproxy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mitm_localhost_webproxy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_auth_spike_in_failed_logon_events.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_auth_spike_in_failed_logon_events.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_auth_spike_in_failed_logon_events.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_auth_spike_in_failed_logon_events.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events_from_a_source_ip.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events_from_a_source_ip.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events_from_a_source_ip.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_auth_spike_in_logon_events_from_a_source_ip.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_linux_anomalous_metadata_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_suspicious_login_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_suspicious_login_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_suspicious_login_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_suspicious_login_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ml_windows_anomalous_metadata_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mod_wdigest_security_provider.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mod_wdigest_security_provider.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_mod_wdigest_security_provider.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_mod_wdigest_security_provider.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_moving_registry_hive_via_smb.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_okta_brute_force_or_password_spraying.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_okta_brute_force_or_password_spraying.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_okta_brute_force_or_password_spraying.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_okta_brute_force_or_password_spraying.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_persistence_network_logon_provider_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_minidump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_posh_minidump.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_minidump.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_posh_minidump.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_request_ticket.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_posh_request_ticket.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_posh_request_ticket.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_posh_request_ticket.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_linux_ssh_bruteforce_root.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_lsa_memdump_via_mirrordump.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_potential_macos_ssh_bruteforce.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_promt_for_pwd_via_osascript.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_promt_for_pwd_via_osascript.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_promt_for_pwd_via_osascript.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_promt_for_pwd_via_osascript.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_relay_ntlm_auth_via_http_spoolss.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_relay_ntlm_auth_via_http_spoolss.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_relay_ntlm_auth_via_http_spoolss.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_relay_ntlm_auth_via_http_spoolss.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_remote_sam_secretsdump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_remote_sam_secretsdump.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_remote_sam_secretsdump.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_remote_sam_secretsdump.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_root_console_failure_brute_force.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_root_console_failure_brute_force.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_root_console_failure_brute_force.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_root_console_failure_brute_force.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vault_winlog.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_saved_creds_vault_winlog.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vault_winlog.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_saved_creds_vault_winlog.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vaultcmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_saved_creds_vaultcmd.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_saved_creds_vaultcmd.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_saved_creds_vaultcmd.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_secretsmanager_getsecretvalue.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_seenabledelegationprivilege_assigned_to_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_shadow_credentials.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_shadow_credentials.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_shadow_credentials.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_shadow_credentials.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_spn_attribute_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_spn_attribute_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_spn_attribute_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_spn_attribute_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ssh_backdoor_log.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ssh_backdoor_log.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_ssh_backdoor_log.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_ssh_backdoor_log.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_storage_account_key_regenerated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_storage_account_key_regenerated.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_storage_account_key_regenerated.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_storage_account_key_regenerated.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_comsvcs_imageload.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_comsvcs_imageload.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_comsvcs_imageload.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_comsvcs_imageload.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_lsass_access_memdump.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_lsass_access_memdump.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_lsass_access_memdump.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_lsass_access_memdump.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_lsass_access_via_snapshot.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_lsass_access_via_snapshot.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_lsass_access_via_snapshot.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_lsass_access_via_snapshot.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_suspicious_winreg_access_via_sebackup_priv.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_symbolic_link_to_shadow_copy_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_systemkey_dumping.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_systemkey_dumping.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_systemkey_dumping.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_systemkey_dumping.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_user_excessive_sso_logon_errors.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_user_excessive_sso_logon_errors.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_user_excessive_sso_logon_errors.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_user_excessive_sso_logon_errors.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_user_impersonation_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_user_impersonation_access.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_user_impersonation_access.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_user_impersonation_access.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_via_snapshot_lsass_clone_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_via_snapshot_lsass_clone_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/credential_access_via_snapshot_lsass_clone_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/credential_access_via_snapshot_lsass_clone_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_agent_spoofing_mismatched_id.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_agent_spoofing_mismatched_id.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_agent_spoofing_mismatched_id.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_agent_spoofing_mismatched_id.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_agent_spoofing_multiple_hosts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_agent_spoofing_multiple_hosts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_agent_spoofing_multiple_hosts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_agent_spoofing_multiple_hosts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_amsienable_key_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_amsienable_key_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_amsienable_key_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_amsienable_key_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_apple_softupdates_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_apple_softupdates_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_apple_softupdates_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_apple_softupdates_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_application_removed_from_blocklist_in_google_workspace.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_application_removed_from_blocklist_in_google_workspace.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_application_removed_from_blocklist_in_google_workspace.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_application_removed_from_blocklist_in_google_workspace.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_del_quarantine_attrib.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_deactivate_okta_network_zone.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_deactivate_okta_network_zone.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_deactivate_okta_network_zone.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_deactivate_okta_network_zone.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_delete_okta_network_zone.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_delete_okta_network_zone.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_delete_okta_network_zone.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_delete_okta_network_zone.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_gatekeeper.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_disable_gatekeeper.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_gatekeeper.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_disable_gatekeeper.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_attempt_to_disable_syslog_service.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_application_credential_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_application_credential_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_application_credential_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_application_credential_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_automation_runbook_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_automation_runbook_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_automation_runbook_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_automation_runbook_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_blob_permissions_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_blob_permissions_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_blob_permissions_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_blob_permissions_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_diagnostic_settings_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_service_principal_addition.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_azure_service_principal_addition.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_azure_service_principal_addition.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_base16_or_base32_encoding_or_decoding_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_chattr_immutable_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_chattr_immutable_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_chattr_immutable_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_chattr_immutable_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_console_history.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_clearing_windows_console_history.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_console_history.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_clearing_windows_console_history.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_clearing_windows_event_logs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_clearing_windows_security_logs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cloudtrail_logging_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cloudtrail_logging_suspended.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cloudwatch_alarm_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_config_service_rule_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_config_service_rule_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_config_service_rule_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_configuration_recorder_stopped.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_create_mod_root_certificate.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_create_mod_root_certificate.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_create_mod_root_certificate.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_create_mod_root_certificate.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cve_2020_0601.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cve_2020_0601.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_cve_2020_0601.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_cve_2020_0601.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_defender_disabled_via_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_defender_exclusion_via_powershell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_delete_volume_usn_journal_with_fsutil.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_websvr_access_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_deleting_websvr_access_logs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deleting_websvr_access_logs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_deleting_websvr_access_logs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_deletion_of_bash_command_line_history.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disable_posh_scriptblocklogging.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disable_selinux_attempt.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_selinux_attempt.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disable_selinux_attempt.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disable_windows_firewall_rules_with_netsh.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disabling_windows_defender_powershell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disabling_windows_logs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_disabling_windows_logs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_disabling_windows_logs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dns_over_https_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_dns_over_https_enabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dns_over_https_enabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_dns_over_https_enabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_domain_added_to_google_workspace_trusted_domains.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_domain_added_to_google_workspace_trusted_domains.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_domain_added_to_google_workspace_trusted_domains.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_domain_added_to_google_workspace_trusted_domains.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_dotnet_compiler_parent_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_ec2_flow_log_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_ec2_network_acl_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elastic_agent_service_terminated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_elastic_agent_service_terminated.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elastic_agent_service_terminated.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_elastic_agent_service_terminated.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_elasticache_security_group_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_elasticache_security_group_modified_or_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_enable_inbound_rdp_with_netsh.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_enable_network_discovery_with_netsh.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_event_hub_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_event_hub_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_event_hub_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_event_hub_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_control_panel_suspicious_args.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_lolbas_wuauclt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_lolbas_wuauclt.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_lolbas_wuauclt.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_lolbas_wuauclt.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_by_office_app.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_by_script.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_by_system_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_renamed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_msbuild_started_unusal_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_suspicious_explorer_winword.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_execution_windefend_unusual_path.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_creation_mult_extension.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_file_creation_mult_extension.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_creation_mult_extension.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_file_creation_mult_extension.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_file_deletion_via_shred.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_deletion_via_shred.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_file_deletion_via_shred.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_mod_writable_dir.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_file_mod_writable_dir.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_file_mod_writable_dir.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_file_mod_writable_dir.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_firewall_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_firewall_policy_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_firewall_policy_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_firewall_policy_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_from_unusual_directory.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_from_unusual_directory.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_from_unusual_directory.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_from_unusual_directory.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_frontdoor_firewall_policy_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_firewall_rule_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_firewall_rule_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_firewall_rule_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_logging_bucket_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_logging_sink_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_pub_sub_subscription_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_pub_sub_topic_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_storage_bucket_configuration_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_storage_bucket_permissions_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_network_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_network_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_network_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_network_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_gcp_virtual_private_cloud_route_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_google_workspace_bitlocker_setting_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_google_workspace_bitlocker_setting_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_google_workspace_bitlocker_setting_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_google_workspace_bitlocker_setting_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_google_workspace_restrictions_for_google_marketplace_changed_to_allow_any_app.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_google_workspace_restrictions_for_google_marketplace_changed_to_allow_any_app.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_google_workspace_restrictions_for_google_marketplace_changed_to_allow_any_app.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_google_workspace_restrictions_for_google_marketplace_changed_to_allow_any_app.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_guardduty_detector_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_hidden_file_dir_tmp.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_shared_object.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_hidden_shared_object.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hidden_shared_object.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_hidden_shared_object.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_hide_encoded_executable_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_iis_httplogging_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_injection_msbuild.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_injection_msbuild.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_injection_msbuild.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_injection_msbuild.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_install_root_certificate.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_install_root_certificate.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_install_root_certificate.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_install_root_certificate.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_installutil_beacon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_installutil_beacon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_installutil_beacon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_kernel_module_removal.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kernel_module_removal.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_kernel_module_removal.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kubernetes_events_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_kubernetes_events_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_kubernetes_events_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_kubernetes_events_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_log_files_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_log_files_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_log_files_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_log_files_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_as_elastic_endpoint_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_as_elastic_endpoint_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_as_elastic_endpoint_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_as_elastic_endpoint_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_renamed_autoit.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_suspicious_werfault_childproc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_trusted_directory.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_werfault.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_werfault.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_masquerading_werfault.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_masquerading_werfault.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_dlp_policy_removed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_mailboxauditbypassassociation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_mailboxauditbypassassociation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_365_mailboxauditbypassassociation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_365_mailboxauditbypassassociation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_microsoft_defender_tampering.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_misc_lolbin_connecting_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modify_environment_launchctl.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_modify_environment_launchctl.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_modify_environment_launchctl.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_modify_environment_launchctl.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_ms_office_suspicious_regmod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_msbuild_making_network_connections.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_mshta_beacon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_mshta_beacon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_mshta_beacon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_mshta_beacon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msxsl_network.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_msxsl_network.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_msxsl_network.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_msxsl_network.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_connection_from_windows_binary.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_network_connection_from_windows_binary.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_connection_from_windows_binary.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_network_connection_from_windows_binary.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_watcher_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_network_watcher_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_network_watcher_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_network_watcher_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy_rule.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy_rule.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_deactivate_okta_policy_rule.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy_rule.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy_rule.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_delete_okta_policy_rule.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_network_zone.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_network_zone.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_network_zone.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_network_zone.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy_rule.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy_rule.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_okta_attempt_to_modify_okta_policy_rule.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_parent_process_pid_spoofing.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_parent_process_pid_spoofing.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_parent_process_pid_spoofing.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_parent_process_pid_spoofing.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_persistence_temp_scheduled_task.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_persistence_temp_scheduled_task.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_persistence_temp_scheduled_task.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_persistence_temp_scheduled_task.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_assembly_load.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_posh_assembly_load.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_assembly_load.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_posh_assembly_load.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_compressed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_posh_compressed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_compressed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_posh_compressed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_process_injection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_posh_process_injection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_posh_process_injection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_posh_process_injection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_potential_processherpaderping.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_potential_processherpaderping.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_potential_processherpaderping.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_potential_processherpaderping.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_powershell_windows_firewall_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_privacy_controls_tcc_database_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_privacy_controls_tcc_database_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_privacy_controls_tcc_database_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_privacy_controls_tcc_database_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_privilege_escalation_privacy_pref_sshd_fulldiskaccess.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_privilege_escalation_privacy_pref_sshd_fulldiskaccess.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_privilege_escalation_privacy_pref_sshd_fulldiskaccess.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_privilege_escalation_privacy_pref_sshd_fulldiskaccess.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_process_termination_followed_by_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_proxy_execution_via_msdt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_proxy_execution_via_msdt.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_proxy_execution_via_msdt.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_proxy_execution_via_msdt.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_rundll32_no_arguments.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_rundll32_no_arguments.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_rundll32_no_arguments.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_rundll32_no_arguments.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_s3_bucket_configuration_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_safari_config_change.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_safari_config_change.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_safari_config_change.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_safari_config_change.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sandboxed_office_app_suspicious_zip_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_sandboxed_office_app_suspicious_zip_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sandboxed_office_app_suspicious_zip_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_sandboxed_office_app_suspicious_zip_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_scheduledjobs_at_protocol_enabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_sdelete_like_filename_rename.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sip_provider_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_sip_provider_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_sip_provider_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_sip_provider_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suppression_rule_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suppression_rule_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suppression_rule_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suppression_rule_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_certutil_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_certutil_commands.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_certutil_commands.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_certutil_commands.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_execution_from_mounted_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_execution_from_mounted_device.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_execution_from_mounted_device.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_execution_from_mounted_device.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_managedcode_host_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_process_access_direct_syscall.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_process_creation_calltrace.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_scrobj_load.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_short_program_name.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_short_program_name.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_short_program_name.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_short_program_name.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_wmi_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_wmi_script.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_wmi_script.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_wmi_script.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_zoom_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_zoom_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_suspicious_zoom_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_suspicious_zoom_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_system_critical_proc_abnormal_file_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_tcc_bypass_mounted_apfs_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_tcc_bypass_mounted_apfs_access.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_tcc_bypass_mounted_apfs_access.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_tcc_bypass_mounted_apfs_access.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_timestomp_touch.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_timestomp_touch.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_timestomp_touch.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unload_endpointsecurity_kext.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unload_endpointsecurity_kext.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unload_endpointsecurity_kext.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unload_endpointsecurity_kext.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_ads_file_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_dir_ads.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_dir_ads.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_dir_ads.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_dllhost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_network_connection_via_dllhost.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_dllhost.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_network_connection_via_dllhost.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_network_connection_via_rundll32.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_process_network_connection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_process_network_connection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_process_network_connection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_unusual_system_vp_child_program.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_via_filter_manager.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_via_filter_manager.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_via_filter_manager.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_waf_acl_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_acl_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_waf_acl_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_waf_rule_or_rule_group_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_workfolders_control_execution.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_workfolders_control_execution.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/defense_evasion_workfolders_control_execution.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/defense_evasion_workfolders_control_execution.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_adfind_command_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_adfind_command_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_adfind_command_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_admin_recon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_admin_recon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_admin_recon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_blob_container_access_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_blob_container_access_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_blob_container_access_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_blob_container_access_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_command_system_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_command_system_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_command_system_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_command_system_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_denied_service_account_request.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_denied_service_account_request.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_denied_service_account_request.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_denied_service_account_request.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_enumerating_domain_trusts_via_nltest.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_enumerating_domain_trusts_via_nltest.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_enumerating_domain_trusts_via_nltest.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_enumerating_domain_trusts_via_nltest.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_kernel_module_enumeration.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_kernel_module_enumeration.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_kernel_module_enumeration.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_kernel_module_enumeration.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_linux_hping_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_linux_hping_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_linux_hping_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_linux_hping_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_linux_nping_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_linux_nping_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_linux_nping_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_linux_nping_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_information_discovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_information_discovery.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_information_discovery.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_information_discovery.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_network_configuration_discovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_network_configuration_discovery.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_network_configuration_discovery.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_network_configuration_discovery.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_network_connection_discovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_network_connection_discovery.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_network_connection_discovery.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_network_connection_discovery.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_process_discovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_process_discovery.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_process_discovery.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_process_discovery.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_user_discovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_user_discovery.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_ml_linux_system_user_discovery.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_ml_linux_system_user_discovery.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_view.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_net_view.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_net_view.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_net_view.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_peripheral_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_peripheral_device.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_peripheral_device.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_peripheral_device.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_invoke_sharefinder.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_posh_invoke_sharefinder.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_invoke_sharefinder.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_posh_invoke_sharefinder.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_suspicious_api_functions.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_posh_suspicious_api_functions.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_posh_suspicious_api_functions.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_posh_suspicious_api_functions.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_post_exploitation_external_ip_lookup.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_privileged_localgroup_membership.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_privileged_localgroup_membership.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_privileged_localgroup_membership.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_privileged_localgroup_membership.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_remote_system_discovery_commands_windows.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_security_software_grep.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_grep.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_security_software_grep.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_security_software_wmic.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_security_software_wmic.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_security_software_wmic.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_suspicious_self_subject_review.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_suspicious_self_subject_review.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_suspicious_self_subject_review.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_suspicious_self_subject_review.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_users_domain_built_in_commands.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_users_domain_built_in_commands.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_users_domain_built_in_commands.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_users_domain_built_in_commands.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_virtual_machine_fingerprinting.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_virtual_machine_fingerprinting.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_virtual_machine_fingerprinting_grep.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_whoami_command_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/discovery_whoami_command_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/discovery_whoami_command_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_adversary_behavior_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_adversary_behavior_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_adversary_behavior_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_adversary_behavior_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_malware_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_malware_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_malware_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_malware_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_malware_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_malware_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_malware_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_malware_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_ransomware_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_ransomware_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_ransomware_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_ransomware_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_ransomware_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_ransomware_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/endgame_ransomware_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/endgame_ransomware_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_abnormal_process_id_file_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_abnormal_process_id_file_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_abnormal_process_id_file_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_abnormal_process_id_file_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_apt_solarwinds_backdoor_child_cmd_powershell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_apt_solarwinds_backdoor_unusual_child_processes.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_com_object_xwizard.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_com_object_xwizard.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_com_object_xwizard.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_com_object_xwizard.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_prompt_connecting_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_shell_started_by_svchost.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_svchost.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_shell_started_by_svchost.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_unusual_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_shell_started_by_unusual_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_started_by_unusual_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_shell_started_by_unusual_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_shell_via_rundll32.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_shell_via_rundll32.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_shell_via_rundll32.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_virtual_machine.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_virtual_machine.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_command_virtual_machine.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_command_virtual_machine.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_defense_evasion_electron_app_childproc_node_js.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_defense_evasion_electron_app_childproc_node_js.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_defense_evasion_electron_app_childproc_node_js.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_defense_evasion_electron_app_childproc_node_js.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_endgame_exploit_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_endgame_exploit_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_endgame_exploit_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_endgame_exploit_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_endgame_exploit_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_endgame_exploit_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_endgame_exploit_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_endgame_exploit_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_enumeration_via_wmiprvse.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_enumeration_via_wmiprvse.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_enumeration_via_wmiprvse.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_enumeration_via_wmiprvse.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_from_unusual_path_cmdline.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_from_unusual_path_cmdline.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_from_unusual_path_cmdline.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_html_help_executable_program_connecting_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_initial_access_suspicious_browser_childproc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_initial_access_suspicious_browser_childproc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_initial_access_suspicious_browser_childproc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_initial_access_suspicious_browser_childproc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_installer_package_spawned_network_event.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_installer_package_spawned_network_event.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_installer_package_spawned_network_event.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_installer_package_spawned_network_event.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_linux_netcat_network_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_linux_netcat_network_connection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_linux_netcat_network_connection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_linux_netcat_network_connection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ml_windows_anomalous_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_ml_windows_anomalous_script.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ml_windows_anomalous_script.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_ml_windows_anomalous_script.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_ms_office_written_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_ms_office_written_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_ms_office_written_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_pdf_written_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pdf_written_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_pdf_written_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pentest_eggshell_remote_admin_tool.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_pentest_eggshell_remote_admin_tool.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_pentest_eggshell_remote_admin_tool.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_pentest_eggshell_remote_admin_tool.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_perl_tty_shell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_perl_tty_shell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_perl_tty_shell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_perl_tty_shell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_portable_executable.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_posh_portable_executable.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_portable_executable.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_posh_portable_executable.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_psreflect.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_posh_psreflect.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_posh_psreflect.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_posh_psreflect.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_process_started_from_process_id_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_process_started_from_process_id_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_process_started_from_process_id_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_process_started_from_process_id_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_process_started_in_shared_memory_directory.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_process_started_in_shared_memory_directory.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_process_started_in_shared_memory_directory.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_process_started_in_shared_memory_directory.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_psexec_lateral_movement_command.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_psexec_lateral_movement_command.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_psexec_lateral_movement_command.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_python_tty_shell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_python_tty_shell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_python_tty_shell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_python_tty_shell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_register_server_program_connecting_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_revershell_via_shell_cmd.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_revershell_via_shell_cmd.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_revershell_via_shell_cmd.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_revershell_via_shell_cmd.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_scheduled_task_powershell_source.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scheduled_task_powershell_source.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_scheduled_task_powershell_source.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_via_automator_workflows.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_script_via_automator_workflows.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_script_via_automator_workflows.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_script_via_automator_workflows.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scripting_osascript_exec_followed_by_netcon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_scripting_osascript_exec_followed_by_netcon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_scripting_osascript_exec_followed_by_netcon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_scripting_osascript_exec_followed_by_netcon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_shared_modules_local_sxs_dll.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_shared_modules_local_sxs_dll.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_shared_modules_local_sxs_dll.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_shared_modules_local_sxs_dll.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_shell_evasion_linux_binary.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_shell_evasion_linux_binary.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_shell_evasion_linux_binary.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_shell_evasion_linux_binary.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_shell_execution_via_apple_scripting.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_shell_execution_via_apple_scripting.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_shell_execution_via_apple_scripting.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_shell_execution_via_apple_scripting.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_cmd_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_cmd_wmi.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_cmd_wmi.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_cmd_wmi.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_image_load_wmi_ms_office.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_image_load_wmi_ms_office.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_image_load_wmi_ms_office.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_image_load_wmi_ms_office.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_jar_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_jar_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_jar_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_jar_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_java_netcon_childproc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_java_netcon_childproc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_java_netcon_childproc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_java_netcon_childproc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_pdf_reader.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_pdf_reader.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_pdf_reader.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_powershell_imgload.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_powershell_imgload.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_powershell_imgload.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_psexesvc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_psexesvc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_suspicious_psexesvc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_suspicious_psexesvc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_tc_bpf_filter.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_tc_bpf_filter.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_tc_bpf_filter.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_tc_bpf_filter.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_user_exec_to_pod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_user_exec_to_pod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_user_exec_to_pod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_user_exec_to_pod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_via_compiled_html_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_compiled_html_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_via_compiled_html_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_via_hidden_shell_conhost.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_hidden_shell_conhost.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_via_hidden_shell_conhost.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/execution_via_xp_cmdshell_mssql_stored_procedure.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_full_network_packet_capture_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_ec2_full_network_packet_capture_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_full_network_packet_capture_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_ec2_full_network_packet_capture_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_ec2_snapshot_change_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_vm_export_failure.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_ec2_vm_export_failure.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_ec2_vm_export_failure.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_ec2_vm_export_failure.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_gcp_logging_sink_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_microsoft_365_exchange_transport_rule_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_export.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_rds_snapshot_export.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_export.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_rds_snapshot_export.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_restored.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_rds_snapshot_restored.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/exfiltration_rds_snapshot_restored.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/exfiltration_rds_snapshot_restored.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/external_alerts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/external_alerts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_attempt_to_revoke_okta_api_token.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_attempt_to_revoke_okta_api_token.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_attempt_to_revoke_okta_api_token.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_attempt_to_revoke_okta_api_token.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_aws_eventbridge_rule_disabled_or_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_aws_eventbridge_rule_disabled_or_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_aws_eventbridge_rule_disabled_or_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_aws_eventbridge_rule_disabled_or_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_azure_service_principal_credentials_added.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_azure_service_principal_credentials_added.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_azure_service_principal_credentials_added.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_azure_service_principal_credentials_added.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_backup_file_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_backup_file_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_backup_file_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_cloudtrail_logging_updated.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudtrail_logging_updated.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_cloudtrail_logging_updated.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_cloudwatch_log_group_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_group_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_cloudwatch_log_group_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_cloudwatch_log_stream_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_deleting_backup_catalogs_with_wbadmin.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_ec2_disable_ebs_encryption.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_ec2_disable_ebs_encryption.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_ec2_disable_ebs_encryption.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_efs_filesystem_or_mount_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_efs_filesystem_or_mount_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_efs_filesystem_or_mount_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_efs_filesystem_or_mount_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_iam_role_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_iam_role_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_iam_role_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_iam_role_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_service_account_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_service_account_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_service_account_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_service_account_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_service_account_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_storage_bucket_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_gcp_storage_bucket_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_gcp_storage_bucket_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_admin_role_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_google_workspace_admin_role_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_admin_role_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_google_workspace_admin_role_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_google_workspace_mfa_enforcement_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_hosts_file_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_hosts_file_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_hosts_file_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_iam_deactivate_mfa_device.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_deactivate_mfa_device.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_iam_deactivate_mfa_device.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_iam_group_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_iam_group_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_iam_group_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_kubernetes_pod_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_kubernetes_pod_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_kubernetes_pod_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_kubernetes_pod_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_microsoft_365_potential_ransomware_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_microsoft_365_unusual_volume_of_file_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_modification_of_boot_config.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_modification_of_boot_config.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_modification_of_boot_config.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_okta_attempt_to_deactivate_okta_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_okta_attempt_to_deactivate_okta_application.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_okta_attempt_to_deactivate_okta_application.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_okta_attempt_to_deactivate_okta_application.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_okta_attempt_to_delete_okta_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_okta_attempt_to_delete_okta_application.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_okta_attempt_to_delete_okta_application.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_okta_attempt_to_delete_okta_application.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_okta_attempt_to_modify_okta_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_okta_attempt_to_modify_okta_application.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_okta_attempt_to_modify_okta_application.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_okta_attempt_to_modify_okta_application.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_possible_okta_dos_attack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_possible_okta_dos_attack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_possible_okta_dos_attack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_possible_okta_dos_attack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_process_kill_threshold.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_process_kill_threshold.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_process_kill_threshold.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_process_kill_threshold.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_rds_group_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_group_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_rds_group_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_rds_instance_cluster_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_rds_instance_cluster_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_stoppage.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_rds_instance_cluster_stoppage.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_rds_instance_cluster_stoppage.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_rds_instance_cluster_stoppage.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_resource_group_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_resource_group_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_resource_group_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_resource_group_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_stop_process_service_threshold.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_stop_process_service_threshold.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_stop_process_service_threshold.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_virtual_network_device_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_virtual_network_device_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_virtual_network_device_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_virtual_network_device_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_volume_shadow_copy_deletion_via_powershell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/impact_volume_shadow_copy_deletion_via_wmic.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/index.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/index.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/index.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_anonymous_request_authorized.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_anonymous_request_authorized.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_anonymous_request_authorized.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_anonymous_request_authorized.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_azure_active_directory_powershell_signin.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_consent_grant_attack_via_azure_registered_application.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_console_login_root.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_console_login_root.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_console_login_root.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_evasion_suspicious_htm_file_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_evasion_suspicious_htm_file_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_evasion_suspicious_htm_file_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_evasion_suspicious_htm_file_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_external_guest_user_invite.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_external_guest_user_invite.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_external_guest_user_invite.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_external_guest_user_invite.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_gcp_iam_custom_role_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_exchange_anti_phish_rule_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_exchange_safelinks_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_microsoft_365_user_restricted_from_sending_email.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_auth_rare_hour_for_a_user_to_logon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_auth_rare_hour_for_a_user_to_logon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_auth_rare_hour_for_a_user_to_logon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_auth_rare_hour_for_a_user_to_logon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_auth_rare_source_ip_for_a_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_auth_rare_source_ip_for_a_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_auth_rare_source_ip_for_a_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_auth_rare_source_ip_for_a_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_auth_rare_user_logon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_auth_rare_user_logon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_auth_rare_user_logon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_auth_rare_user_logon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_linux_anomalous_user_name.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_linux_anomalous_user_name.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_linux_anomalous_user_name.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_linux_anomalous_user_name.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_windows_anomalous_user_name.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_windows_anomalous_user_name.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_windows_anomalous_user_name.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_windows_anomalous_user_name.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_windows_rare_user_type10_remote_login.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_windows_rare_user_type10_remote_login.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_ml_windows_rare_user_type10_remote_login.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_ml_windows_rare_user_type10_remote_login.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_o365_user_reported_phish_malware.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_o365_user_reported_phish_malware.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_o365_user_reported_phish_malware.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_o365_user_reported_phish_malware.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_okta_user_attempted_unauthorized_access.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_password_recovery.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_password_recovery.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_password_recovery.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_password_recovery.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rpc_remote_procedure_call_from_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_rpc_remote_procedure_call_from_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rpc_remote_procedure_call_from_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_rpc_remote_procedure_call_from_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rpc_remote_procedure_call_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_rpc_remote_procedure_call_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_rpc_remote_procedure_call_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_rpc_remote_procedure_call_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_script_executing_powershell.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_script_executing_powershell.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_script_executing_powershell.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_scripts_process_started_via_wmi.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_smb_windows_file_sharing_activity_to_the_internet.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_smb_windows_file_sharing_activity_to_the_internet.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_smb_windows_file_sharing_activity_to_the_internet.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_smb_windows_file_sharing_activity_to_the_internet.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_activity_reported_by_okta_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_activity_reported_by_okta_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_activity_reported_by_okta_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_activity_reported_by_okta_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_mac_ms_office_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_exchange_files.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_exchange_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_exchange_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_worker_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_exchange_worker_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_exchange_worker_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_exchange_worker_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_office_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_suspicious_ms_outlook_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unsecure_elasticsearch_node.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_unsecure_elasticsearch_node.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unsecure_elasticsearch_node.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_unsecure_elasticsearch_node.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_unusual_dns_service_children.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_children.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_unusual_dns_service_children.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_unusual_dns_service_file_writes.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_via_explorer_suspicious_child_parent_args.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_via_system_manager.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_via_system_manager.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_via_system_manager.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_zoom_meeting_with_no_passcode.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_zoom_meeting_with_no_passcode.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/initial_access_zoom_meeting_with_no_passcode.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/initial_access_zoom_meeting_with_no_passcode.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_cmd_service.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_cmd_service.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_cmd_service.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_cmd_service.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_credential_access_kerberos_bifrostconsole.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_hta.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dcom_hta.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_hta.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dcom_hta.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_mmc20.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dcom_mmc20.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_mmc20.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dcom_mmc20.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dcom_shellwindow_shellbrowserwindow.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_direct_outbound_smb_connection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dns_server_overflow.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_dns_server_overflow.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_dns_server_overflow.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_evasion_rdp_shadowing.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_executable_tool_transfer_smb.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_from_tsclient_mup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_execution_from_tsclient_mup.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_from_tsclient_mup.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_execution_from_tsclient_mup.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_execution_via_file_shares_sequence.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_incoming_winrm_shell_execution.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_incoming_wmi.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_incoming_wmi.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_incoming_wmi.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_malware_uploaded_onedrive.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_malware_uploaded_onedrive.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_malware_uploaded_onedrive.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_malware_uploaded_onedrive.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_malware_uploaded_sharepoint.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_malware_uploaded_sharepoint.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_malware_uploaded_sharepoint.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_malware_uploaded_sharepoint.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_mount_hidden_or_webdav_share_net.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mounting_smb_share.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_mounting_smb_share.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_mounting_smb_share.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_mounting_smb_share.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_powershell_remoting_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_powershell_remoting_target.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_powershell_remoting_target.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_powershell_remoting_target.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_rdp_enabled_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_enabled_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_rdp_enabled_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_rdp_sharprdp_target.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_file_copy_hidden_share.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_services.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_services.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_services.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_ssh_login_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_ssh_login_enabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_ssh_login_enabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_ssh_login_enabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_task_creation_winlog.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_task_creation_winlog.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_remote_task_creation_winlog.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_remote_task_creation_winlog.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_scheduled_task_target.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_scheduled_task_target.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_scheduled_task_target.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_service_control_spawned_script_int.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_suspicious_rdp_client_imageload.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_suspicious_rdp_client_imageload.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_suspicious_rdp_client_imageload.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_suspicious_rdp_client_imageload.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_external.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_telnet_network_activity_external.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_external.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_telnet_network_activity_external.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_telnet_network_activity_internal.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_via_startup_folder_rdp_smb.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_vpn_connection_attempt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_vpn_connection_attempt.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/lateral_movement_vpn_connection_attempt.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/lateral_movement_vpn_connection_attempt.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_error_message_spike.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_error_message_spike.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_error_message_spike.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_error_code.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_error_code.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_error_code.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_method_by_city.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_method_by_country.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_cloudtrail_rare_method_by_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_denies.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_high_count_network_denies.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_denies.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_high_count_network_denies.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_events.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_high_count_network_events.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_high_count_network_events.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_high_count_network_events.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_network_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_linux_anomalous_network_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_network_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_linux_anomalous_network_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_network_port_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_linux_anomalous_network_port_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_linux_anomalous_network_port_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_linux_anomalous_network_port_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_packetbeat_rare_server_domain.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_packetbeat_rare_server_domain.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_packetbeat_rare_server_domain.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_packetbeat_rare_server_domain.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_destination_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_rare_destination_country.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_rare_destination_country.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_rare_destination_country.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_spike_in_traffic_to_a_country.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_spike_in_traffic_to_a_country.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_spike_in_traffic_to_a_country.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_spike_in_traffic_to_a_country.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_windows_anomalous_network_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_windows_anomalous_network_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/ml_windows_anomalous_network_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/ml_windows_anomalous_network_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/notice.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/notice.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/notice.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/notice.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/okta_threat_detected_by_okta_threatinsight.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/okta_threat_detected_by_okta_threatinsight.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/okta_threat_detected_by_okta_threatinsight.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/okta_threat_detected_by_okta_threatinsight.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_account_creation_hide_at_logon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_account_creation_hide_at_logon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_account_creation_hide_at_logon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_account_creation_hide_at_logon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ad_adminsdholder.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ad_adminsdholder.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ad_adminsdholder.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ad_adminsdholder.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_administrator_privileges_assigned_to_okta_group.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_administrator_privileges_assigned_to_okta_group.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_administrator_privileges_assigned_to_okta_group.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_administrator_privileges_assigned_to_okta_group.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_administrator_role_assigned_to_okta_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_administrator_role_assigned_to_okta_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_administrator_role_assigned_to_okta_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_administrator_role_assigned_to_okta_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_adobe_hijack_persistence.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_adobe_hijack_persistence.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_adobe_hijack_persistence.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_app_compat_shim.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_app_compat_shim.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_app_compat_shim.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_app_compat_shim.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appcertdlls_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_appcertdlls_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appcertdlls_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_appcertdlls_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appinitdlls_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_appinitdlls_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_appinitdlls_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_appinitdlls_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_application_added_to_google_workspace_domain.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_application_added_to_google_workspace_domain.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_application_added_to_google_workspace_domain.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_application_added_to_google_workspace_domain.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_attempt_to_create_okta_api_token.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_attempt_to_create_okta_api_token.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_attempt_to_create_okta_api_token.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_attempt_to_create_okta_api_token.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_attempt_to_deactivate_mfa_for_okta_user_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_attempt_to_deactivate_mfa_for_okta_user_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_attempt_to_deactivate_mfa_for_okta_user_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_attempt_to_deactivate_mfa_for_okta_user_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_account_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_automation_account_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_account_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_automation_account_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_automation_runbook_created_or_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_automation_webhook_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_automation_webhook_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_automation_webhook_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_conditional_access_policy_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_global_administrator_role_assigned.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_global_administrator_role_assigned.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_global_administrator_role_assigned.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_global_administrator_role_assigned.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_pim_user_added_global_admin.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_azure_privileged_identity_management_role_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_chkconfig_service_add.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_chkconfig_service_add.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_chkconfig_service_add.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_chkconfig_service_add.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_change_launch_agents_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_creation_change_launch_agents_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_change_launch_agents_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_creation_change_launch_agents_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_hidden_login_item_osascript.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_creation_hidden_login_item_osascript.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_hidden_login_item_osascript.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_creation_hidden_login_item_osascript.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_modif_launch_deamon_sequence.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_creation_modif_launch_deamon_sequence.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_creation_modif_launch_deamon_sequence.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_creation_modif_launch_deamon_sequence.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_authorization_plugin_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_credential_access_authorization_plugin_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_authorization_plugin_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_credential_access_authorization_plugin_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_credential_access_modify_auth_module_or_config.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_ssh_binaries.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_credential_access_modify_ssh_binaries.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_credential_access_modify_ssh_binaries.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_credential_access_modify_ssh_binaries.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_crontab_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_crontab_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_crontab_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_crontab_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_defense_evasion_hidden_launch_agent_deamon_logonitem_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_defense_evasion_hidden_launch_agent_deamon_logonitem_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_defense_evasion_hidden_launch_agent_deamon_logonitem_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_defense_evasion_hidden_launch_agent_deamon_logonitem_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_directory_services_plugins_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_directory_services_plugins_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_directory_services_plugins_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_directory_services_plugins_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_docker_shortcuts_plist_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_docker_shortcuts_plist_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_docker_shortcuts_plist_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_docker_shortcuts_plist_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dontexpirepasswd_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_dontexpirepasswd_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dontexpirepasswd_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_dontexpirepasswd_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dynamic_linker_backup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_dynamic_linker_backup.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_dynamic_linker_backup.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_dynamic_linker_backup.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ec2_network_acl_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_network_acl_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ec2_network_acl_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ec2_security_group_configuration_change_detection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_emond_rules_file_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_emond_rules_file_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_emond_rules_file_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_emond_rules_file_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_emond_rules_process_execution.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_emond_rules_process_execution.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_emond_rules_process_execution.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_emond_rules_process_execution.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_enable_root_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_enable_root_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_enable_root_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_enable_root_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_etc_file_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_etc_file_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_etc_file_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_etc_file_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_launch_agent_deamon_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_hidden_launch_agent_deamon_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_launch_agent_deamon_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_hidden_launch_agent_deamon_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_hidden_local_account_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_registry_ifeo_injection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_evasion_registry_startup_shell_folder_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_exchange_suspicious_mailbox_right_delegation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exposed_service_created_with_type_nodeport.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_exposed_service_created_with_type_nodeport.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_exposed_service_created_with_type_nodeport.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_exposed_service_created_with_type_nodeport.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_finder_sync_plugin_pluginkit.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_finder_sync_plugin_pluginkit.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_finder_sync_plugin_pluginkit.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_finder_sync_plugin_pluginkit.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_folder_action_scripts_runtime.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_folder_action_scripts_runtime.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_folder_action_scripts_runtime.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_folder_action_scripts_runtime.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gcp_iam_service_account_key_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_key_created_for_service_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gcp_key_created_for_service_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_key_created_for_service_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gcp_key_created_for_service_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_service_account_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gcp_service_account_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gcp_service_account_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gcp_service_account_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_2sv_policy_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_2sv_policy_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_2sv_policy_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_2sv_policy_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_admin_role_assigned_to_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_custom_admin_role_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_policy_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_policy_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_policy_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_policy_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_role_modified.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_role_modified.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_role_modified.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_role_modified.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_user_group_access_modified_to_allow_external_access.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_user_group_access_modified_to_allow_external_access.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_user_group_access_modified_to_allow_external_access.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_user_group_access_modified_to_allow_external_access.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_user_organizational_unit_changed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_user_organizational_unit_changed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_google_workspace_user_organizational_unit_changed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_google_workspace_user_organizational_unit_changed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gpo_schtask_service_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_gpo_schtask_service_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_gpo_schtask_service_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_iam_group_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_iam_group_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_iam_group_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_insmod_kernel_module_load.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_insmod_kernel_module_load.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_insmod_kernel_module_load.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_insmod_kernel_module_load.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kde_autostart_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_kde_autostart_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_kde_autostart_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_kde_autostart_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_local_scheduled_job_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_job_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_local_scheduled_job_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_local_scheduled_task_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_local_scheduled_task_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_scripting.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_local_scheduled_task_scripting.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_local_scheduled_task_scripting.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_local_scheduled_task_scripting.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_login_logout_hooks_defaults.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_login_logout_hooks_defaults.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_login_logout_hooks_defaults.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_login_logout_hooks_defaults.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_loginwindow_plist_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_loginwindow_plist_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_loginwindow_plist_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_loginwindow_plist_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_mfa_disabled_for_azure_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_google_workspace_organization.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_mfa_disabled_for_google_workspace_organization.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_mfa_disabled_for_google_workspace_organization.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_mfa_disabled_for_google_workspace_organization.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_dkim_signing_config_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_exchange_dkim_signing_config_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_dkim_signing_config_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_exchange_dkim_signing_config_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_exchange_management_role_assignment.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_global_administrator_role_assign.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_global_administrator_role_assign.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_global_administrator_role_assign.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_global_administrator_role_assign.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_custom_app_interaction_allowed.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_teams_custom_app_interaction_allowed.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_custom_app_interaction_allowed.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_teams_custom_app_interaction_allowed.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_teams_external_access_enabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_microsoft_365_teams_guest_access_enabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_linux_anomalous_process_all_hosts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_linux_anomalous_process_all_hosts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_linux_anomalous_process_all_hosts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_linux_anomalous_process_all_hosts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_linux.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_rare_process_by_host_linux.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_linux.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_rare_process_by_host_linux.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_rare_process_by_host_windows.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_path_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_path_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_path_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_path_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_process_all_hosts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_process_all_hosts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_process_all_hosts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_process_all_hosts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_process_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_process_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_process_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_process_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_service.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_service.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ml_windows_anomalous_service.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ml_windows_anomalous_service.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_modification_sublime_app_plugin_or_script.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_modification_sublime_app_plugin_or_script.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_modification_sublime_app_plugin_or_script.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_modification_sublime_app_plugin_or_script.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ms_office_addins_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ms_office_addins_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ms_office_addins_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ms_office_addins_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ms_outlook_vba_template.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ms_outlook_vba_template.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ms_outlook_vba_template.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ms_outlook_vba_template.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_msds_alloweddelegateto_krbtgt.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_msds_alloweddelegateto_krbtgt.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_msds_alloweddelegateto_krbtgt.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_msds_alloweddelegateto_krbtgt.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_okta_attempt_to_modify_or_delete_application_sign_on_policy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_okta_attempt_to_modify_or_delete_application_sign_on_policy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_okta_attempt_to_modify_or_delete_application_sign_on_policy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_okta_attempt_to_modify_or_delete_application_sign_on_policy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_periodic_tasks_file_mdofiy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_periodic_tasks_file_mdofiy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_periodic_tasks_file_mdofiy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_periodic_tasks_file_mdofiy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_powershell_exch_mailbox_activesync_add_device.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_priv_escalation_via_accessibility_features.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_rds_cluster_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_cluster_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_rds_cluster_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_group_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_rds_group_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_group_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_rds_group_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_instance_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_rds_instance_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_rds_instance_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_rds_instance_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_redshift_instance_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_redshift_instance_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_redshift_instance_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_redshift_instance_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_registry_uncommon.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_registry_uncommon.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_registry_uncommon.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_remote_password_reset.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_remote_password_reset.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_remote_password_reset.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_remote_password_reset.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_53_domain_transfer_lock_disabled.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_53_domain_transfer_lock_disabled.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_53_domain_transfer_lock_disabled.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_53_domain_transfer_lock_disabled.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_53_domain_transferred_to_another_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_53_domain_transferred_to_another_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_53_domain_transferred_to_another_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_53_domain_transferred_to_another_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_53_hosted_zone_associated_with_a_vpc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_53_hosted_zone_associated_with_a_vpc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_53_hosted_zone_associated_with_a_vpc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_53_hosted_zone_associated_with_a_vpc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_table_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_table_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_modified_or_deleted.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_table_modified_or_deleted.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_route_table_modified_or_deleted.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_route_table_modified_or_deleted.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_run_key_and_startup_broad.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_run_key_and_startup_broad.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_run_key_and_startup_broad.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_runtime_run_key_startup_susp_procs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_scheduled_task_creation_winlog.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_scheduled_task_creation_winlog.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_scheduled_task_creation_winlog.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_scheduled_task_creation_winlog.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_scheduled_task_updated.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_scheduled_task_updated.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_scheduled_task_updated.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_scheduled_task_updated.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_screensaver_engine_unexpected_child_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_plist_file_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_screensaver_plist_file_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_screensaver_plist_file_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_screensaver_plist_file_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_sdprop_exclusion_dsheuristics.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_services_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_services_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_services_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_shell_activity_by_web_server.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_activity_by_web_server.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_shell_activity_by_web_server.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_profile_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_shell_profile_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_shell_profile_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_shell_profile_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ssh_authorized_keys_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ssh_authorized_keys_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_ssh_authorized_keys_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_ssh_authorized_keys_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_startup_folder_file_written_by_suspicious_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_startup_folder_file_written_by_unsigned_process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_startup_folder_scripts.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_startup_folder_scripts.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_startup_folder_scripts.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_calendar_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_calendar_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_calendar_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_calendar_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_com_hijack_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_com_hijack_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_com_hijack_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_image_load_scheduled_task_ms_office.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_image_load_scheduled_task_ms_office.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_image_load_scheduled_task_ms_office.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_image_load_scheduled_task_ms_office.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_scheduled_task_runtime.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_service_created_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_service_created_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_suspicious_service_created_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_suspicious_service_created_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_system_shells_via_services.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_system_shells_via_services.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_system_shells_via_services.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_time_provider_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_time_provider_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_time_provider_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_time_provider_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_account_added_to_privileged_group_ad.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_account_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_account_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_account_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_added_as_owner_for_azure_application.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_user_added_as_owner_for_azure_service_principal.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_application_shimming.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_application_shimming.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_application_shimming.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_atom_init_file_modification.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_atom_init_file_modification.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_atom_init_file_modification.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_atom_init_file_modification.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_bits_job_notify_command.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_bits_job_notify_command.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_bits_job_notify_command.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_bits_job_notify_command.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_hidden_run_key_valuename.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_hidden_run_key_valuename.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_hidden_run_key_valuename.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_hidden_run_key_valuename.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_lsa_security_support_provider_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_telemetrycontroller_scheduledtask_hijack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_update_orchestrator_service_hijack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_windows_management_instrumentation_event_subscription.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_via_wmi_stdregprov_run_services.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_webshell_detection.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/persistence_webshell_detection.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/persistence_webshell_detection.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_applescript_with_admin_privs.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_applescript_with_admin_privs.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_applescript_with_admin_privs.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_applescript_with_admin_privs.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_aws_suspicious_saml_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_aws_suspicious_saml_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_aws_suspicious_saml_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_aws_suspicious_saml_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_azure_kubernetes_rolebinding_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_azure_kubernetes_rolebinding_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_azure_kubernetes_rolebinding_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_azure_kubernetes_rolebinding_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_create_process_as_different_user.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_create_process_as_different_user.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_create_process_as_different_user.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_create_process_as_different_user.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_cyberarkpas_error_audit_event_promotion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_cyberarkpas_error_audit_event_promotion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_cyberarkpas_error_audit_event_promotion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_cyberarkpas_error_audit_event_promotion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_disable_uac_registry.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_disable_uac_registry.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_disable_uac_registry.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_disable_uac_registry.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_echo_nopasswd_sudoers.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_echo_nopasswd_sudoers.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_echo_nopasswd_sudoers.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_echo_nopasswd_sudoers.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_cred_manipulation_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_permission_theft_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_permission_theft_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_permission_theft_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_permission_theft_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_permission_theft_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_permission_theft_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_permission_theft_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_permission_theft_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_process_injection_detected.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_process_injection_detected.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_process_injection_detected.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_process_injection_detected.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_process_injection_prevented.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_process_injection_prevented.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_endgame_process_injection_prevented.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_endgame_process_injection_prevented.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_explicit_creds_via_scripting.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_explicit_creds_via_scripting.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_explicit_creds_via_scripting.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_explicit_creds_via_scripting.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_exploit_adobe_acrobat_updater.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_exploit_adobe_acrobat_updater.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_exploit_adobe_acrobat_updater.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_exploit_adobe_acrobat_updater.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_gcp_kubernetes_rolebindings_created_or_patched.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_gcp_kubernetes_rolebindings_created_or_patched.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_gcp_kubernetes_rolebindings_created_or_patched.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_gcp_kubernetes_rolebindings_created_or_patched.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_iniscript.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_group_policy_iniscript.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_iniscript.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_group_policy_iniscript.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_group_policy_privileged_groups.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_group_policy_scheduled_task.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_installertakeover.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_installertakeover.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_installertakeover.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_installertakeover.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_krbrelayup_service_creation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_krbrelayup_service_creation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_krbrelayup_service_creation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_krbrelayup_service_creation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_ld_preload_shared_object_modif.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_ld_preload_shared_object_modif.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_ld_preload_shared_object_modif.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_ld_preload_shared_object_modif.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_local_user_added_to_admin.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_local_user_added_to_admin.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_local_user_added_to_admin.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_local_user_added_to_admin.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_lsa_auth_package.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_lsa_auth_package.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_lsa_auth_package.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_lsa_auth_package.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_ml_linux_anomalous_sudo_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_ml_linux_anomalous_sudo_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_ml_linux_anomalous_sudo_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_ml_linux_anomalous_sudo_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_ml_windows_rare_user_runas_event.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_ml_windows_rare_user_runas_event.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_ml_windows_rare_user_runas_event.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_ml_windows_rare_user_runas_event.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_named_pipe_impersonation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_named_pipe_impersonation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_named_pipe_impersonation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_named_pipe_impersonation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_new_or_modified_federation_domain.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_persistence_phantom_dll.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pkexec_envar_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pkexec_envar_hijack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pkexec_envar_hijack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pkexec_envar_hijack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_hostipc.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_hostipc.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_hostipc.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_hostipc.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_hostnetwork.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_hostnetwork.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_hostnetwork.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_hostnetwork.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_hostpid.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_hostpid.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_hostpid.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_hostpid.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_sensitive_hospath_volume.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_sensitive_hospath_volume.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_pod_created_with_sensitive_hospath_volume.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_pod_created_with_sensitive_hospath_volume.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_port_monitor_print_pocessor_abuse.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_port_monitor_print_pocessor_abuse.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_port_monitor_print_pocessor_abuse.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_port_monitor_print_pocessor_abuse.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_posh_token_impersonation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_posh_token_impersonation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_posh_token_impersonation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_posh_token_impersonation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_registry_copyfiles.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_registry_copyfiles.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_registry_copyfiles.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_registry_copyfiles.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_service_suspicious_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_file_deletion.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_suspicious_file_deletion.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_file_deletion.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_suspicious_file_deletion.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_printspooler_suspicious_spl_file.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_privileged_pod_created.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_privileged_pod_created.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_privileged_pod_created.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_privileged_pod_created.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_rogue_windir_environment_var.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_crontab_filemod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_root_crontab_filemod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_crontab_filemod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_root_crontab_filemod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_login_without_mfa.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_root_login_without_mfa.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_root_login_without_mfa.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_root_login_without_mfa.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_samaccountname_spoofing_attack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_samaccountname_spoofing_attack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_samaccountname_spoofing_attack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_samaccountname_spoofing_attack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_setuid_setgid_bit_set_via_chmod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_shadow_file_read.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_shadow_file_read.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_shadow_file_read.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_shadow_file_read.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_assumerole_usage.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sts_assumerole_usage.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_assumerole_usage.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sts_assumerole_usage.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sts_getsessiontoken_abuse.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudo_buffer_overflow.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sudo_buffer_overflow.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudo_buffer_overflow.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sudo_buffer_overflow.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sudoers_file_mod.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_sudoers_file_mod.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_sudoers_file_mod.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_suspicious_assignment_of_controller_service_account.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_suspicious_assignment_of_controller_service_account.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_suspicious_assignment_of_controller_service_account.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_suspicious_assignment_of_controller_service_account.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_suspicious_dnshostname_update.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_suspicious_dnshostname_update.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_suspicious_dnshostname_update.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_suspicious_dnshostname_update.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_com_clipup.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_com_ieinstal.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_com_interface_icmluautil.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_diskcleanup_hijack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_dll_sideloading.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_event_viewer.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_mock_windir.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_uac_bypass_winfw_mmc_hijack.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unshare_namesapce_manipulation.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unshare_namesapce_manipulation.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unshare_namesapce_manipulation.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unshare_namesapce_manipulation.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unusual_parentchild_relationship.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_printspooler_childprocess.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unusual_printspooler_childprocess.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_printspooler_childprocess.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unusual_printspooler_childprocess.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_unusual_svchost_childproc_childless.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_updateassumerolepolicy.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_via_rogue_named_pipe.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_via_rogue_named_pipe.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_via_rogue_named_pipe.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_via_rogue_named_pipe.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_windows_service_via_unusual_client.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_windows_service_via_unusual_client.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/privilege_escalation_windows_service_via_unusual_client.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/privilege_escalation_windows_service_via_unusual_client.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/resource_development_ml_linux_anomalous_compiler_activity.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/resource_development_ml_linux_anomalous_compiler_activity.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/resource_development_ml_linux_anomalous_compiler_activity.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/resource_development_ml_linux_anomalous_compiler_activity.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_filebeat8x.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/threat_intel_filebeat8x.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_filebeat8x.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/threat_intel_filebeat8x.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_fleet_integrations.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/threat_intel_fleet_integrations.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/threat_intel_fleet_integrations.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/threat_intel_fleet_integrations.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/README.md similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/README.md rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/README.md index 635839577fb2d..6b9638389e120 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/README.md +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/README.md @@ -6,7 +6,7 @@ 1. [Have the env params set up](https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/server/lib/detection_engine/README.md) -2. Create a new timelines template into `x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines` +2. Create a new timelines template into `x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines` ##### 2.a : Create a new template from UI and export it. @@ -14,7 +14,7 @@ 2. Go to timelines > templates > custom templates (a filter on the right) 3. Click `Create new timeline template` 4. Edit your template - 5. Export only **one** timeline template each time and put that in `x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines`. (For potential update requirement in the future, we put one timeline in each file to keep nice and clear) + 5. Export only **one** timeline template each time and put that in `x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines`. (For potential update requirement in the future, we put one timeline in each file to keep nice and clear) 6. Rename the file extension to `.json` 7. Check the chapter of `Fields to hightlight for on boarding a new prepackaged timeline` in this readme and update your template @@ -25,7 +25,7 @@ Please note that below template is just an example, please replace all your fields with whatever makes sense. Do check `Fields to hightlight for on boarding a new prepackaged timeline` to make sure the template can be created as expected. - cd x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines + cd x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines @@ -54,7 +54,7 @@ 4. ```sh ./timelines/regen_prepackage_timelines_index.sh``` -(this will update `x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson`) +(this will update `x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/index.ndjson`) @@ -83,7 +83,7 @@ sh ./timelines/find_timeline_by_filter.sh immutable template elastic ### How to update an existing prepackage timeline: -1. ```cd x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines``` +1. ```cd x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines``` 2. Open the json file you wish to update, and remember to bump the `templateTimelineVersion` diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/endpoint.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/endpoint.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/endpoint.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/endpoint.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/file_ex.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/file_ex.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/file_ex.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/file_ex.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/index.ndjson similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/index.ndjson rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/index.ndjson diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/network.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/network.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/network.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/network.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/network_ex.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/network_ex.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/network_ex.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/network_ex.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/process.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/process.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/process.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/process.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/process_ex.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/process_ex.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/process_ex.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/process_ex.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/registry_ex.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/registry_ex.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/registry_ex.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/registry_ex.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/threat.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/threat.json similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_timelines/threat.json rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_timelines/threat.json diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/index.ts new file mode 100644 index 0000000000000..30a12c10bdb90 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { createPrepackagedRules } from './api/install_prebuilt_rules_and_timelines/route'; +export * from './api/register_routes'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/create_prebuilt_rules.ts similarity index 56% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/create_prebuilt_rules.ts index b43c2180a07e8..54554e50a7dd7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/install_prepacked_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/create_prebuilt_rules.ts @@ -6,17 +6,14 @@ */ import type { RulesClient } from '@kbn/alerting-plugin/server'; -import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../common/constants'; -import type { AddPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import { initPromisePool } from '../../../utils/promise_pool'; -import { withSecuritySpan } from '../../../utils/with_security_span'; -import { createRules } from './create_rules'; +import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../common/constants'; +import type { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import { initPromisePool } from '../../../../utils/promise_pool'; +import { withSecuritySpan } from '../../../../utils/with_security_span'; +import { createRules } from '../../rule_management/logic/crud/create_rules'; -export const installPrepackagedRules = ( - rulesClient: RulesClient, - rules: AddPrepackagedRulesSchema[] -) => - withSecuritySpan('installPrepackagedRules', async () => { +export const createPrebuiltRules = (rulesClient: RulesClient, rules: PrebuiltRuleToInstall[]) => + withSecuritySpan('createPrebuiltRules', async () => { const result = await initPromisePool({ concurrency: MAX_RULES_TO_UPDATE_IN_PARALLEL, items: rules, @@ -31,6 +28,6 @@ export const installPrepackagedRules = ( }); if (result.errors.length > 0) { - throw new AggregateError(result.errors, 'Error installing prepackaged rules'); + throw new AggregateError(result.errors, 'Error installing new prebuilt rules'); } }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.test.ts new file mode 100644 index 0000000000000..7c3f69990486b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty } from 'lodash/fp'; +import type { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import { getFilesystemRules } from './get_latest_prebuilt_rules'; + +describe('Get latest prebuilt rules', () => { + describe('getFilesystemRules', () => { + test('should not throw any errors with the existing checked in pre-packaged rules', () => { + expect(() => getFilesystemRules()).not.toThrow(); + }); + + test('no rule should have the same rule_id as another rule_id', () => { + const prebuiltRules = getFilesystemRules(); + let existingRuleIds: PrebuiltRuleToInstall[] = []; + prebuiltRules.forEach((rule) => { + const foundDuplicate = existingRuleIds.reduce((accum, existingRule) => { + if (existingRule.rule_id === rule.rule_id) { + return `Found duplicate rule_id of ${rule.rule_id} between these two rule names of "${rule.name}" and "${existingRule.name}"`; + } else { + return accum; + } + }, ''); + if (!isEmpty(foundDuplicate)) { + expect(foundDuplicate).toEqual(''); + } else { + existingRuleIds = [...existingRuleIds, rule]; + } + }); + }); + + test('should throw an exception if a pre-packaged rule is not valid', () => { + // @ts-expect-error intentionally invalid argument + expect(() => getFilesystemRules([{ not_valid_made_up_key: true }])).toThrow(); + }); + + test('should throw an exception with a message having rule_id and name in it', () => { + expect(() => + // @ts-expect-error intentionally invalid argument + getFilesystemRules([{ name: 'rule name', rule_id: 'id-123' }]) + ).toThrow(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts similarity index 60% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts index f01f6820b2687..f1218f031fff8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_latest_prebuilt_rules.ts @@ -5,37 +5,75 @@ * 2.0. */ -import { BadRequestError } from '@kbn/securitysolution-es-utils'; -import { exactCheck, formatErrors } from '@kbn/securitysolution-io-ts-utils'; import { fold } from 'fp-ts/lib/Either'; import { pipe } from 'fp-ts/lib/pipeable'; import type * as t from 'io-ts'; -import type { AddPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import { addPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import type { ConfigType } from '../../../config'; -import { withSecuritySpan } from '../../../utils/with_security_span'; + +import { BadRequestError } from '@kbn/securitysolution-es-utils'; +import { exactCheck, formatErrors } from '@kbn/securitysolution-io-ts-utils'; + +import { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import type { ConfigType } from '../../../../config'; +import { withSecuritySpan } from '../../../../utils/with_security_span'; + // TODO: convert rules files to TS and add explicit type definitions -import { rawRules } from './prepackaged_rules'; -import type { RuleAssetSavedObjectsClient } from './rule_asset/rule_asset_saved_objects_client'; -import type { IRuleAssetSOAttributes } from './types'; +import { rawRules } from '../content/prepackaged_rules'; +import type { + RuleAssetSavedObjectsClient, + IRuleAssetSOAttributes, +} from './rule_asset/rule_asset_saved_objects_client'; + +export const getLatestPrebuiltRules = async ( + client: RuleAssetSavedObjectsClient, + prebuiltRulesFromFileSystem: ConfigType['prebuiltRulesFromFileSystem'], + prebuiltRulesFromSavedObjects: ConfigType['prebuiltRulesFromSavedObjects'] +): Promise> => + withSecuritySpan('getLatestPrebuiltRules', async () => { + // build a map of the most recent version of each rule + const prebuilt = prebuiltRulesFromFileSystem ? getFilesystemRules() : []; + const ruleMap = new Map(prebuilt.map((r) => [r.rule_id, r])); + + // check the rules installed via fleet and create/update if the version is newer + if (prebuiltRulesFromSavedObjects) { + const fleetRules = await getFleetRules(client); + fleetRules.forEach((fleetRule) => { + const fsRule = ruleMap.get(fleetRule.rule_id); + + if (fsRule == null || fsRule.version < fleetRule.version) { + // add the new or updated rules to the map + ruleMap.set(fleetRule.rule_id, fleetRule); + } + }); + } + + return ruleMap; + }); + +/** + * Retrieve and validate prebuilt rules from "file system" (content/prepackaged_rules). + */ +export const getFilesystemRules = ( + // @ts-expect-error mock data is too loosely typed + rules: PrebuiltRuleToInstall[] = rawRules +): PrebuiltRuleToInstall[] => { + return validateFilesystemRules(rules); +}; /** * Validate the rules from the file system and throw any errors indicating to the developer * that they are adding incorrect schema rules. Also this will auto-flush in all the default * aspects such as default interval of 5 minutes, default arrays, etc... */ -export const validateAllPrepackagedRules = ( - rules: AddPrepackagedRulesSchema[] -): AddPrepackagedRulesSchema[] => { +const validateFilesystemRules = (rules: PrebuiltRuleToInstall[]): PrebuiltRuleToInstall[] => { return rules.map((rule) => { - const decoded = addPrepackagedRulesSchema.decode(rule); + const decoded = PrebuiltRuleToInstall.decode(rule); const checked = exactCheck(rule, decoded); - const onLeft = (errors: t.Errors): AddPrepackagedRulesSchema => { + const onLeft = (errors: t.Errors): PrebuiltRuleToInstall => { const ruleName = rule.name ? rule.name : '(rule name unknown)'; const ruleId = rule.rule_id ? rule.rule_id : '(rule rule_id unknown)'; throw new BadRequestError( - `name: "${ruleName}", rule_id: "${ruleId}" within the folder rules/prepackaged_rules ` + + `name: "${ruleName}", rule_id: "${ruleId}" within the folder content/prepackaged_rules ` + `is not a valid detection engine rule. Expect the system ` + `to not work with pre-packaged rules until this rule is fixed ` + `or the file is removed. Error is: ${formatErrors( @@ -44,24 +82,33 @@ export const validateAllPrepackagedRules = ( ); }; - const onRight = (schema: AddPrepackagedRulesSchema): AddPrepackagedRulesSchema => { - return schema as AddPrepackagedRulesSchema; + const onRight = (schema: PrebuiltRuleToInstall): PrebuiltRuleToInstall => { + return schema as PrebuiltRuleToInstall; }; return pipe(checked, fold(onLeft, onRight)); }); }; +/** + * Retrieve and validate prebuilt rules that were installed from Fleet as saved objects. + */ +const getFleetRules = async ( + client: RuleAssetSavedObjectsClient +): Promise => { + const fleetResponse = await client.all(); + const fleetRules = fleetResponse.map((so) => so.attributes); + return validateFleetRules(fleetRules); +}; + /** * Validate the rules from Saved Objects created by Fleet. */ -export const validateAllRuleSavedObjects = ( - rules: IRuleAssetSOAttributes[] -): AddPrepackagedRulesSchema[] => { +const validateFleetRules = (rules: IRuleAssetSOAttributes[]): PrebuiltRuleToInstall[] => { return rules.map((rule) => { - const decoded = addPrepackagedRulesSchema.decode(rule); + const decoded = PrebuiltRuleToInstall.decode(rule); const checked = exactCheck(rule, decoded); - const onLeft = (errors: t.Errors): AddPrepackagedRulesSchema => { + const onLeft = (errors: t.Errors): PrebuiltRuleToInstall => { const ruleName = rule.name ? rule.name : '(rule name unknown)'; const ruleId = rule.rule_id ? rule.rule_id : '(rule rule_id unknown)'; throw new BadRequestError( @@ -74,53 +121,9 @@ export const validateAllRuleSavedObjects = ( ); }; - const onRight = (schema: AddPrepackagedRulesSchema): AddPrepackagedRulesSchema => { - return schema as AddPrepackagedRulesSchema; + const onRight = (schema: PrebuiltRuleToInstall): PrebuiltRuleToInstall => { + return schema as PrebuiltRuleToInstall; }; return pipe(checked, fold(onLeft, onRight)); }); }; - -/** - * Retrieve and validate rules that were installed from Fleet as saved objects. - */ -export const getFleetInstalledRules = async ( - client: RuleAssetSavedObjectsClient -): Promise => { - const fleetResponse = await client.all(); - const fleetRules = fleetResponse.map((so) => so.attributes); - return validateAllRuleSavedObjects(fleetRules); -}; - -export const getPrepackagedRules = ( - // @ts-expect-error mock data is too loosely typed - rules: AddPrepackagedRulesSchema[] = rawRules -): AddPrepackagedRulesSchema[] => { - return validateAllPrepackagedRules(rules); -}; - -export const getLatestPrepackagedRules = async ( - client: RuleAssetSavedObjectsClient, - prebuiltRulesFromFileSystem: ConfigType['prebuiltRulesFromFileSystem'], - prebuiltRulesFromSavedObjects: ConfigType['prebuiltRulesFromSavedObjects'] -): Promise> => - withSecuritySpan('getLatestPrepackagedRules', async () => { - // build a map of the most recent version of each rule - const prepackaged = prebuiltRulesFromFileSystem ? getPrepackagedRules() : []; - const ruleMap = new Map(prepackaged.map((r) => [r.rule_id, r])); - - // check the rules installed via fleet and create/update if the version is newer - if (prebuiltRulesFromSavedObjects) { - const fleetRules = await getFleetInstalledRules(client); - fleetRules.forEach((fleetRule) => { - const fsRule = ruleMap.get(fleetRule.rule_id); - - if (fsRule == null || fsRule.version < fleetRule.version) { - // add the new or updated rules to the map - ruleMap.set(fleetRule.rule_id, fleetRule); - } - }); - } - - return ruleMap; - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_install.test.ts similarity index 65% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_install.test.ts index 513d638afb2a7..b93ef2cc5178f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_install.test.ts @@ -6,73 +6,73 @@ */ import { getRulesToInstall } from './get_rules_to_install'; -import { getRuleMock } from '../routes/__mocks__/request_responses'; -import { getAddPrepackagedRulesSchemaMock } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; -import { prepackagedRulesToMap, rulesToMap } from './utils'; +import { getRuleMock } from '../../routes/__mocks__/request_responses'; +import { getPrebuiltRuleMock } from '../../../../../common/detection_engine/prebuilt_rules/mocks'; +import { getQueryRuleParams } from '../../rule_schema/mocks'; +import { prebuiltRulesToMap, rulesToMap } from './utils'; describe('get_rules_to_install', () => { test('should return empty array if both rule sets are empty', () => { - const update = getRulesToInstall(prepackagedRulesToMap([]), rulesToMap([])); + const update = getRulesToInstall(prebuiltRulesToMap([]), rulesToMap([])); expect(update).toEqual([]); }); test('should return empty array if the two rule ids match', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-1'; const update = getRulesToInstall( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule]) ); expect(update).toEqual([]); }); test('should return the rule to install if the id of the two rules do not match', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-2'; const update = getRulesToInstall( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule]) ); expect(update).toEqual([ruleFromFileSystem]); }); test('should return two rules to install if both the ids of the two rules do not match', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.rule_id = 'rule-1'; - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem2 = getPrebuiltRuleMock(); ruleFromFileSystem2.rule_id = 'rule-2'; const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-3'; const update = getRulesToInstall( - prepackagedRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), + prebuiltRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), rulesToMap([installedRule]) ); expect(update).toEqual([ruleFromFileSystem1, ruleFromFileSystem2]); }); test('should return two rules of three to install if both the ids of the two rules do not match but the third does', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.rule_id = 'rule-1'; - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem2 = getPrebuiltRuleMock(); ruleFromFileSystem2.rule_id = 'rule-2'; - const ruleFromFileSystem3 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem3 = getPrebuiltRuleMock(); ruleFromFileSystem3.rule_id = 'rule-3'; const installedRule = getRuleMock(getQueryRuleParams()); installedRule.params.ruleId = 'rule-3'; const update = getRulesToInstall( - prepackagedRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2, ruleFromFileSystem3]), + prebuiltRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2, ruleFromFileSystem3]), rulesToMap([installedRule]) ); expect(update).toEqual([ruleFromFileSystem1, ruleFromFileSystem2]); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_install.ts similarity index 56% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_install.ts index aa7a257a171e0..69d76cdc98e4a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_install.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_install.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { AddPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import type { RuleAlertType } from './types'; +import type { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import type { RuleAlertType } from '../../rule_schema'; export const getRulesToInstall = ( - latestPrePackagedRules: Map, + latestPrebuiltRules: Map, installedRules: Map ) => { - return Array.from(latestPrePackagedRules.values()).filter( + return Array.from(latestPrebuiltRules.values()).filter( (rule) => !installedRules.has(rule.rule_id) ); }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_update.test.ts similarity index 85% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_update.test.ts index 7f48cca2078e1..bcf85d4095556 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_update.test.ts @@ -6,19 +6,19 @@ */ import { filterInstalledRules, getRulesToUpdate, mergeExceptionLists } from './get_rules_to_update'; -import { getRuleMock } from '../routes/__mocks__/request_responses'; -import { getAddPrepackagedRulesSchemaMock } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; -import { prepackagedRulesToMap, rulesToMap } from './utils'; +import { getRuleMock } from '../../routes/__mocks__/request_responses'; +import { getPrebuiltRuleMock } from '../../../../../common/detection_engine/prebuilt_rules/mocks'; +import { getQueryRuleParams } from '../../rule_schema/mocks'; +import { prebuiltRulesToMap, rulesToMap } from './utils'; describe('get_rules_to_update', () => { test('should return empty array if both rule sets are empty', () => { - const update = getRulesToUpdate(prepackagedRulesToMap([]), rulesToMap([])); + const update = getRulesToUpdate(prebuiltRulesToMap([]), rulesToMap([])); expect(update).toEqual([]); }); test('should return empty array if the rule_id of the two rules do not match', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 2; @@ -26,14 +26,14 @@ describe('get_rules_to_update', () => { installedRule.params.ruleId = 'rule-2'; installedRule.params.version = 1; const update = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule]) ); expect(update).toEqual([]); }); test('should return empty array if the version of file system rule is less than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 1; @@ -41,14 +41,14 @@ describe('get_rules_to_update', () => { installedRule.params.ruleId = 'rule-1'; installedRule.params.version = 2; const update = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule]) ); expect(update).toEqual([]); }); test('should return empty array if the version of file system rule is the same as the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 1; @@ -56,14 +56,14 @@ describe('get_rules_to_update', () => { installedRule.params.ruleId = 'rule-1'; installedRule.params.version = 1; const update = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule]) ); expect(update).toEqual([]); }); test('should return the rule to update if the version of file system rule is greater than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 2; @@ -73,14 +73,14 @@ describe('get_rules_to_update', () => { installedRule.params.exceptionsList = []; const update = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule]) ); expect(update).toEqual([ruleFromFileSystem]); }); test('should return 1 rule out of 2 to update if the version of file system rule is greater than the installed version of just one', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 2; @@ -95,18 +95,18 @@ describe('get_rules_to_update', () => { installedRule2.params.exceptionsList = []; const update = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem]), + prebuiltRulesToMap([ruleFromFileSystem]), rulesToMap([installedRule1, installedRule2]) ); expect(update).toEqual([ruleFromFileSystem]); }); test('should return 2 rules out of 2 to update if the version of file system rule is greater than the installed version of both', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.rule_id = 'rule-1'; ruleFromFileSystem1.version = 2; - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem2 = getPrebuiltRuleMock(); ruleFromFileSystem2.rule_id = 'rule-2'; ruleFromFileSystem2.version = 2; @@ -121,14 +121,14 @@ describe('get_rules_to_update', () => { installedRule2.params.exceptionsList = []; const update = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), + prebuiltRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), rulesToMap([installedRule1, installedRule2]) ); expect(update).toEqual([ruleFromFileSystem1, ruleFromFileSystem2]); }); test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = [ { id: 'endpoint_list', @@ -146,14 +146,14 @@ describe('get_rules_to_update', () => { installedRule1.params.exceptionsList = []; const [update] = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1]), + prebuiltRulesToMap([ruleFromFileSystem1]), rulesToMap([installedRule1]) ); expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); }); test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = [ { id: 'endpoint_list', @@ -178,7 +178,7 @@ describe('get_rules_to_update', () => { ]; const [update] = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1]), + prebuiltRulesToMap([ruleFromFileSystem1]), rulesToMap([installedRule1]) ); expect(update.exceptions_list).toEqual([ @@ -188,7 +188,7 @@ describe('get_rules_to_update', () => { }); test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = [ { id: 'endpoint_list', @@ -213,14 +213,14 @@ describe('get_rules_to_update', () => { ]; const [update] = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1]), + prebuiltRulesToMap([ruleFromFileSystem1]), rulesToMap([installedRule1]) ); expect(update.exceptions_list).toEqual(ruleFromFileSystem1.exceptions_list); }); test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = []; ruleFromFileSystem1.rule_id = 'rule-1'; ruleFromFileSystem1.version = 2; @@ -238,19 +238,19 @@ describe('get_rules_to_update', () => { ]; const [update] = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1]), + prebuiltRulesToMap([ruleFromFileSystem1]), rulesToMap([installedRule1]) ); expect(update.exceptions_list).toEqual(installedRule1.params.exceptionsList); }); test('should not remove an existing exception_list if the rule has an empty exceptions list for multiple rules', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = []; ruleFromFileSystem1.rule_id = 'rule-1'; ruleFromFileSystem1.version = 2; - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem2 = getPrebuiltRuleMock(); ruleFromFileSystem2.exceptions_list = []; ruleFromFileSystem2.rule_id = 'rule-2'; ruleFromFileSystem2.version = 2; @@ -279,7 +279,7 @@ describe('get_rules_to_update', () => { ]; const [update1, update2] = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), + prebuiltRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), rulesToMap([installedRule1, installedRule2]) ); expect(update1.exceptions_list).toEqual(installedRule1.params.exceptionsList); @@ -287,12 +287,12 @@ describe('get_rules_to_update', () => { }); test('should not remove an existing exception_list if the rule has an empty exceptions list for mixed rules', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = []; ruleFromFileSystem1.rule_id = 'rule-1'; ruleFromFileSystem1.version = 2; - const ruleFromFileSystem2 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem2 = getPrebuiltRuleMock(); ruleFromFileSystem2.exceptions_list = []; ruleFromFileSystem2.rule_id = 'rule-2'; ruleFromFileSystem2.version = 2; @@ -330,7 +330,7 @@ describe('get_rules_to_update', () => { ]; const [update1, update2] = getRulesToUpdate( - prepackagedRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), + prebuiltRulesToMap([ruleFromFileSystem1, ruleFromFileSystem2]), rulesToMap([installedRule1, installedRule2]) ); expect(update1.exceptions_list).toEqual(installedRule1.params.exceptionsList); @@ -343,7 +343,7 @@ describe('get_rules_to_update', () => { describe('filterInstalledRules', () => { test('should return "false" if the id of the two rules do not match', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 2; @@ -355,7 +355,7 @@ describe('filterInstalledRules', () => { }); test('should return "false" if the version of file system rule is less than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 1; @@ -367,7 +367,7 @@ describe('filterInstalledRules', () => { }); test('should return "false" if the version of file system rule is the same as the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 1; @@ -379,7 +379,7 @@ describe('filterInstalledRules', () => { }); test('should return "true" to update if the version of file system rule is greater than the installed version', () => { - const ruleFromFileSystem = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem = getPrebuiltRuleMock(); ruleFromFileSystem.rule_id = 'rule-1'; ruleFromFileSystem.version = 2; @@ -395,7 +395,7 @@ describe('filterInstalledRules', () => { describe('mergeExceptionLists', () => { test('should add back an exception_list if it was removed by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = [ { id: 'endpoint_list', @@ -417,7 +417,7 @@ describe('mergeExceptionLists', () => { }); test('should not remove an additional exception_list if an additional one was added by the end user on an immutable rule during an upgrade', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = [ { id: 'endpoint_list', @@ -449,7 +449,7 @@ describe('mergeExceptionLists', () => { }); test('should not remove an existing exception_list if they are the same between the current installed one and the upgraded one', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = [ { id: 'endpoint_list', @@ -478,7 +478,7 @@ describe('mergeExceptionLists', () => { }); test('should not remove an existing exception_list if the rule has an empty exceptions list', () => { - const ruleFromFileSystem1 = getAddPrepackagedRulesSchemaMock(); + const ruleFromFileSystem1 = getPrebuiltRuleMock(); ruleFromFileSystem1.exceptions_list = []; ruleFromFileSystem1.rule_id = 'rule-1'; ruleFromFileSystem1.version = 2; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_update.ts similarity index 60% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_update.ts index 8cfabf1889c7f..7547f16961cc1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_rules_to_update.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/get_rules_to_update.ts @@ -5,21 +5,21 @@ * 2.0. */ -import type { AddPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import type { RuleAlertType } from './types'; +import type { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import type { RuleAlertType } from '../../rule_schema'; /** * Returns the rules to update by doing a compare to the rules from the file system against * the installed rules already. This also merges exception list items between the two since * exception list items can exist on both rules to update and already installed rules. - * @param latestPrePackagedRules The latest rules to check against installed + * @param latestPrebuiltRules The latest rules to check against installed * @param installedRules The installed rules */ export const getRulesToUpdate = ( - latestPrePackagedRules: Map, + latestPrebuiltRules: Map, installedRules: Map ) => { - return Array.from(latestPrePackagedRules.values()) + return Array.from(latestPrebuiltRules.values()) .filter((latestRule) => filterInstalledRules(latestRule, installedRules)) .map((latestRule) => mergeExceptionLists(latestRule, installedRules)); }; @@ -27,45 +27,44 @@ export const getRulesToUpdate = ( /** * Filters latest prepackaged rules that do not match the installed rules so you * only get back rules that are going to be updated - * @param latestPrePackagedRule The latest prepackaged rule version + * @param latestPrebuiltRule The latest prepackaged rule version * @param installedRules The installed rules to compare against for updates */ export const filterInstalledRules = ( - latestPrePackagedRule: AddPrepackagedRulesSchema, + latestPrebuiltRule: PrebuiltRuleToInstall, installedRules: Map ): boolean => { - const installedRule = installedRules.get(latestPrePackagedRule.rule_id); + const installedRule = installedRules.get(latestPrebuiltRule.rule_id); - return !!installedRule && installedRule.params.version < latestPrePackagedRule.version; + return !!installedRule && installedRule.params.version < latestPrebuiltRule.version; }; /** * Given a rule from the file system and the set of installed rules this will merge the exception lists * from the installed rules onto the rules from the file system. - * @param latestPrePackagedRule The latest prepackaged rule version that might have exceptions_lists + * @param latestPrebuiltRule The latest prepackaged rule version that might have exceptions_lists * @param installedRules The installed rules which might have user driven exceptions_lists */ export const mergeExceptionLists = ( - latestPrePackagedRule: AddPrepackagedRulesSchema, + latestPrebuiltRule: PrebuiltRuleToInstall, installedRules: Map -): AddPrepackagedRulesSchema => { - if (latestPrePackagedRule.exceptions_list != null) { - const installedRule = installedRules.get(latestPrePackagedRule.rule_id); +): PrebuiltRuleToInstall => { + if (latestPrebuiltRule.exceptions_list != null) { + const installedRule = installedRules.get(latestPrebuiltRule.rule_id); if (installedRule != null && installedRule.params.exceptionsList != null) { const installedExceptionList = installedRule.params.exceptionsList; - const fileSystemExceptions = latestPrePackagedRule.exceptions_list.filter( - (potentialDuplicate) => - installedExceptionList.every((item) => item.list_id !== potentialDuplicate.list_id) + const fileSystemExceptions = latestPrebuiltRule.exceptions_list.filter((potentialDuplicate) => + installedExceptionList.every((item) => item.list_id !== potentialDuplicate.list_id) ); return { - ...latestPrePackagedRule, + ...latestPrebuiltRule, exceptions_list: [...fileSystemExceptions, ...installedRule.params.exceptionsList], }; } else { - return latestPrePackagedRule; + return latestPrebuiltRule; } } else { - return latestPrePackagedRule; + return latestPrebuiltRule; } }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/rule_asset/rule_asset_saved_object_mappings.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_object_mappings.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/rule_asset/rule_asset_saved_object_mappings.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_object_mappings.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/rule_asset/rule_asset_saved_objects_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts similarity index 80% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/rule_asset/rule_asset_saved_objects_client.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts index de1ea7987e457..be963fb3dae9e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/rule_asset/rule_asset_saved_objects_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_objects_client.ts @@ -11,10 +11,22 @@ import type { SavedObjectsFindResponse, } from '@kbn/core/server'; import { ruleAssetSavedObjectType } from './rule_asset_saved_object_mappings'; -import type { IRuleAssetSavedObject } from '../types'; const DEFAULT_PAGE_SIZE = 100; +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export interface IRuleAssetSOAttributes extends Record { + rule_id: string | null | undefined; + version: string | null | undefined; + name: string | null | undefined; +} + +export interface IRuleAssetSavedObject { + type: string; + id: string; + attributes: IRuleAssetSOAttributes; +} + export interface RuleAssetSavedObjectsClient { find: ( options?: Omit diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/update_prebuilt_rules.test.ts similarity index 73% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/update_prebuilt_rules.test.ts index 88d543cc77007..955d288068e33 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/update_prebuilt_rules.test.ts @@ -7,28 +7,30 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { savedObjectsClientMock } from '@kbn/core/server/mocks'; -import { getRuleMock, getFindResultWithSingleHit } from '../routes/__mocks__/request_responses'; -import { updatePrepackagedRules } from './update_prepacked_rules'; -import { patchRules } from './patch_rules'; +import { getRuleMock, getFindResultWithSingleHit } from '../../routes/__mocks__/request_responses'; +import { updatePrebuiltRules } from './update_prebuilt_rules'; +import { patchRules } from '../../rule_management/logic/crud/patch_rules'; import { - getAddPrepackagedRulesSchemaMock, - getAddPrepackagedThreatMatchRulesSchemaMock, -} from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema.mock'; -import { ruleExecutionLogMock } from '../rule_monitoring/mocks'; -import { legacyMigrate } from './utils'; -import { getQueryRuleParams, getThreatRuleParams } from '../schemas/rule_schemas.mock'; + getPrebuiltRuleMock, + getPrebuiltThreatMatchRuleMock, +} from '../../../../../common/detection_engine/prebuilt_rules/mocks'; +import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; +import { legacyMigrate } from '../../rule_management'; +import { getQueryRuleParams, getThreatRuleParams } from '../../rule_schema/mocks'; -jest.mock('./patch_rules'); +jest.mock('../../rule_management/logic/crud/patch_rules'); -jest.mock('./utils', () => { - const actual = jest.requireActual('./utils'); +jest.mock('../../rule_management/logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual( + '../../rule_management/logic/rule_actions/legacy_action_migration' + ); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('updatePrepackagedRules', () => { +describe('updatePrebuiltRules', () => { let rulesClient: ReturnType; let savedObjectsClient: ReturnType; let ruleExecutionLog: ReturnType; @@ -50,10 +52,10 @@ describe('updatePrepackagedRules', () => { params: {}, }, ]; - const prepackagedRule = getAddPrepackagedRulesSchemaMock(); + const prepackagedRule = getPrebuiltRuleMock(); rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); - await updatePrepackagedRules( + await updatePrebuiltRules( rulesClient, savedObjectsClient, [{ ...prepackagedRule, actions }], @@ -83,14 +85,14 @@ describe('updatePrepackagedRules', () => { threat_indicator_path: 'test.path', threat_query: 'threat:*', }; - const prepackagedRule = getAddPrepackagedThreatMatchRulesSchemaMock(); + const prepackagedRule = getPrebuiltThreatMatchRuleMock(); rulesClient.find.mockResolvedValue({ ...getFindResultWithSingleHit(), data: [getRuleMock(getThreatRuleParams())], }); (legacyMigrate as jest.Mock).mockResolvedValue(getRuleMock(getThreatRuleParams())); - await updatePrepackagedRules( + await updatePrebuiltRules( rulesClient, savedObjectsClient, [{ ...prepackagedRule, ...updatedThreatParams }], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/update_prebuilt_rules.ts similarity index 73% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/update_prebuilt_rules.ts index aaee033dd8e96..341038097f448 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_prepacked_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/update_prebuilt_rules.ts @@ -8,30 +8,34 @@ import { chunk } from 'lodash/fp'; import type { SavedObjectsClientContract } from '@kbn/core/server'; import type { RulesClient, PartialRule } from '@kbn/alerting-plugin/server'; -import type { AddPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; -import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../common/constants'; -import { patchRules } from './patch_rules'; -import { readRules } from './read_rules'; -import type { RuleParams } from '../schemas/rule_schemas'; -import { legacyMigrate } from './utils'; -import { deleteRules } from './delete_rules'; -import { PrepackagedRulesError } from '../routes/rules/add_prepackaged_rules_route'; -import type { IRuleExecutionLogForRoutes } from '../rule_monitoring'; -import { createRules } from './create_rules'; -import { transformAlertToRuleAction } from '../../../../common/detection_engine/transform_actions'; + +import type { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import { transformAlertToRuleAction } from '../../../../../common/detection_engine/transform_actions'; +import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../common/constants'; + +import { legacyMigrate } from '../../rule_management'; +import { createRules } from '../../rule_management/logic/crud/create_rules'; +import { readRules } from '../../rule_management/logic/crud/read_rules'; +import { patchRules } from '../../rule_management/logic/crud/patch_rules'; +import { deleteRules } from '../../rule_management/logic/crud/delete_rules'; + +import type { IRuleExecutionLogForRoutes } from '../../rule_monitoring'; +import type { RuleParams } from '../../rule_schema'; + +import { PrepackagedRulesError } from '../api/install_prebuilt_rules_and_timelines/route'; /** - * Updates the prepackaged rules given a set of rules and output index. + * Updates existing prebuilt rules given a set of rules and output index. * This implements a chunked approach to not saturate network connections and * avoid being a "noisy neighbor". * @param rulesClient Alerting client * @param spaceId Current user spaceId * @param rules The rules to apply the update for */ -export const updatePrepackagedRules = async ( +export const updatePrebuiltRules = async ( rulesClient: RulesClient, savedObjectsClient: SavedObjectsClientContract, - rules: AddPrepackagedRulesSchema[], + rules: PrebuiltRuleToInstall[], ruleExecutionLog: IRuleExecutionLogForRoutes ): Promise => { const ruleChunks = chunk(MAX_RULES_TO_UPDATE_IN_PARALLEL, rules); @@ -53,10 +57,10 @@ export const updatePrepackagedRules = async ( * @param rules The rules to apply the update for * @returns Promise of what was updated. */ -export const createPromises = ( +const createPromises = ( rulesClient: RulesClient, savedObjectsClient: SavedObjectsClientContract, - rules: AddPrepackagedRulesSchema[], + rules: PrebuiltRuleToInstall[], ruleExecutionLog: IRuleExecutionLogForRoutes ): Array | null>> => { return rules.map(async (rule) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/utils.ts new file mode 100644 index 0000000000000..09f231f51d4ac --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/utils.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PrebuiltRuleToInstall } from '../../../../../common/detection_engine/prebuilt_rules'; +import type { RuleAlertType } from '../../rule_schema'; + +/** + * Converts an array of prebuilt rules to a Map with rule IDs as keys + * + * @param rules Array of prebuilt rules + * @returns Map + */ +export const prebuiltRulesToMap = (rules: PrebuiltRuleToInstall[]) => + new Map(rules.map((rule) => [rule.rule_id, rule])); + +/** + * Converts an array of rules to a Map with rule IDs as keys + * + * @param rules Array of rules + * @returns Map + */ +export const rulesToMap = (rules: RuleAlertType[]) => + new Map(rules.map((rule) => [rule.params.ruleId, rule])); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 9f2f576313531..7b6c85d486638 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -6,17 +6,16 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { SavedObjectsFindResponse, SavedObjectsFindResult } from '@kbn/core/server'; import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils'; import { ruleTypeMappings } from '@kbn/securitysolution-rules'; - -import type { SavedObjectsFindResponse, SavedObjectsFindResult } from '@kbn/core/server'; +import type { SanitizedRule, ResolvedSanitizedRule } from '@kbn/alerting-plugin/common'; import { DETECTION_ENGINE_RULES_URL, DETECTION_ENGINE_SIGNALS_STATUS_URL, DETECTION_ENGINE_PRIVILEGES_URL, DETECTION_ENGINE_QUERY_SIGNALS_URL, - DETECTION_ENGINE_PREPACKAGED_URL, DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL, DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL, DETECTION_ENGINE_RULES_BULK_ACTION, @@ -25,24 +24,31 @@ import { DETECTION_ENGINE_RULES_BULK_CREATE, DETECTION_ENGINE_RULES_URL_FIND, } from '../../../../../common/constants'; -import type { RuleAlertType, HapiReadableStream } from '../../rules/types'; -import { requestMock } from './request'; + +import { + PREBUILT_RULES_STATUS_URL, + PREBUILT_RULES_URL, +} from '../../../../../common/detection_engine/prebuilt_rules'; +import { + getPerformBulkActionSchemaMock, + getPerformBulkActionEditSchemaMock, +} from '../../../../../common/detection_engine/rule_management/mocks'; +import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/rule_schema/mocks'; import type { QuerySignalsSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/query_signals_index_schema'; import type { SetSignalsStatusSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/set_signal_status_schema'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; import { getFinalizeSignalsMigrationSchemaMock } from '../../../../../common/detection_engine/schemas/request/finalize_signals_migration_schema.mock'; import { getSignalsMigrationStatusSchemaMock } from '../../../../../common/detection_engine/schemas/request/get_signals_migration_status_schema.mock'; -import type { RuleParams } from '../../schemas/rule_schemas'; -import type { SanitizedRule, ResolvedSanitizedRule } from '@kbn/alerting-plugin/common'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { - getPerformBulkActionSchemaMock, - getPerformBulkActionEditSchemaMock, -} from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock'; -// eslint-disable-next-line no-restricted-imports -import type { LegacyRuleNotificationAlertType } from '../../notifications/legacy_types'; + // eslint-disable-next-line no-restricted-imports -import type { LegacyIRuleActionsAttributes } from '../../rule_actions/legacy_types'; +import type { + LegacyRuleNotificationAlertType, + LegacyIRuleActionsAttributes, +} from '../../rule_actions_legacy'; +import type { HapiReadableStream } from '../../rule_management/logic/import/hapi_readable_stream'; +import type { RuleAlertType, RuleParams } from '../../rule_schema'; +import { getQueryRuleParams } from '../../rule_schema/mocks'; + +import { requestMock } from './request'; export const typicalSetStatusSignalByIdsPayload = (): SetSignalsStatusSchemaDecoded => ({ signal_ids: ['somefakeid1', 'somefakeid2'], @@ -174,13 +180,13 @@ export const getPrivilegeRequest = (options: { auth?: { isAuthenticated: boolean export const addPrepackagedRulesRequest = () => requestMock.create({ method: 'put', - path: DETECTION_ENGINE_PREPACKAGED_URL, + path: PREBUILT_RULES_URL, }); export const getPrepackagedRulesStatusRequest = () => requestMock.create({ method: 'get', - path: `${DETECTION_ENGINE_PREPACKAGED_URL}/_status`, + path: PREBUILT_RULES_STATUS_URL, }); export interface FindHit { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/utils.ts index 3ed486d9d9a1b..67462232a22ba 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/utils.ts @@ -7,10 +7,10 @@ import { Readable } from 'stream'; -import type { HapiReadableStream } from '../../rules/types'; import { getListArrayMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; import { getThreatMock } from '../../../../../common/detection_engine/schemas/types/threat.mock'; -import type { FullResponseSchema } from '../../../../../common/detection_engine/schemas/request'; +import type { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; +import type { HapiReadableStream } from '../../rule_management/logic/import/hapi_readable_stream'; /** * Given a string, builds a hapi stream as our @@ -34,7 +34,7 @@ export const buildHapiStream = (string: string, filename = 'file.ndjson'): HapiR return stream; }; -export const getOutputRuleAlertForRest = (): FullResponseSchema => ({ +export const getOutputRuleAlertForRest = (): RuleResponse => ({ author: ['Elastic'], actions: [], building_block_type: 'default', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts deleted file mode 100644 index 92a854b2540fe..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/get_prepackaged_rules_status_route.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; -import { validate } from '@kbn/securitysolution-io-ts-utils'; -import type { PrePackagedRulesAndTimelinesStatusSchema } from '../../../../../common/detection_engine/schemas/response/prepackaged_rules_status_schema'; -import { prePackagedRulesAndTimelinesStatusSchema } from '../../../../../common/detection_engine/schemas/response/prepackaged_rules_status_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_PREPACKAGED_URL } from '../../../../../common/constants'; -import { buildSiemResponse } from '../utils'; - -import { getRulesToInstall } from '../../rules/get_rules_to_install'; -import { getRulesToUpdate } from '../../rules/get_rules_to_update'; -import { findRules } from '../../rules/find_rules'; -import { getLatestPrepackagedRules } from '../../rules/get_prepackaged_rules'; -import { getExistingPrepackagedRules } from '../../rules/get_existing_prepackaged_rules'; -import { ruleAssetSavedObjectsClientFactory } from '../../rules/rule_asset/rule_asset_saved_objects_client'; -import { buildFrameworkRequest } from '../../../timeline/utils/common'; -import type { ConfigType } from '../../../../config'; -import type { SetupPlugins } from '../../../../plugin'; -import { - checkTimelinesStatus, - checkTimelineStatusRt, -} from '../../../timeline/utils/check_timelines_status'; -import { rulesToMap } from '../../rules/utils'; - -export const getPrepackagedRulesStatusRoute = ( - router: SecuritySolutionPluginRouter, - config: ConfigType, - security: SetupPlugins['security'] -) => { - router.get( - { - path: `${DETECTION_ENGINE_PREPACKAGED_URL}/_status`, - validate: false, - options: { - tags: ['access:securitySolution'], - }, - }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const ctx = await context.resolve(['core', 'alerting']); - const savedObjectsClient = ctx.core.savedObjects.client; - const rulesClient = ctx.alerting.getRulesClient(); - const ruleAssetsClient = ruleAssetSavedObjectsClientFactory(savedObjectsClient); - - try { - const latestPrepackagedRules = await getLatestPrepackagedRules( - ruleAssetsClient, - config.prebuiltRulesFromFileSystem, - config.prebuiltRulesFromSavedObjects - ); - const customRules = await findRules({ - rulesClient, - perPage: 1, - page: 1, - sortField: 'enabled', - sortOrder: 'desc', - filter: 'alert.attributes.params.immutable: false', - fields: undefined, - }); - const frameworkRequest = await buildFrameworkRequest(context, security, request); - const installedPrePackagedRules = rulesToMap( - await getExistingPrepackagedRules({ rulesClient }) - ); - - const rulesToInstall = getRulesToInstall(latestPrepackagedRules, installedPrePackagedRules); - const rulesToUpdate = getRulesToUpdate(latestPrepackagedRules, installedPrePackagedRules); - const prepackagedTimelineStatus = await checkTimelinesStatus(frameworkRequest); - const [validatedPrepackagedTimelineStatus] = validate( - prepackagedTimelineStatus, - checkTimelineStatusRt - ); - - const prepackagedRulesStatus: PrePackagedRulesAndTimelinesStatusSchema = { - rules_custom_installed: customRules.total, - rules_installed: installedPrePackagedRules.size, - rules_not_installed: rulesToInstall.length, - rules_not_updated: rulesToUpdate.length, - timelines_installed: validatedPrepackagedTimelineStatus?.prepackagedTimelines.length ?? 0, - timelines_not_installed: - validatedPrepackagedTimelineStatus?.timelinesToInstall.length ?? 0, - timelines_not_updated: validatedPrepackagedTimelineStatus?.timelinesToUpdate.length ?? 0, - }; - const [validated, errors] = validate( - prepackagedRulesStatus, - prePackagedRulesAndTimelinesStatusSchema - ); - if (errors != null) { - return siemResponse.error({ statusCode: 500, body: errors }); - } else { - return response.ok({ body: validated ?? {} }); - } - } catch (err) { - const error = transformError(err); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts similarity index 90% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts index e6d98ed4f8195..5b20d410db8ce 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/legacy_create_legacy_notification.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/create_legacy_notification/route.ts @@ -8,15 +8,15 @@ import { schema } from '@kbn/config-schema'; import type { Logger } from '@kbn/core/server'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; // eslint-disable-next-line no-restricted-imports -import { legacyUpdateOrCreateRuleActionsSavedObject } from '../../rule_actions/legacy_update_or_create_rule_actions_saved_object'; +import { legacyUpdateOrCreateRuleActionsSavedObject } from '../../logic/rule_actions/legacy_update_or_create_rule_actions_saved_object'; // eslint-disable-next-line no-restricted-imports -import { legacyReadNotifications } from '../../notifications/legacy_read_notifications'; +import { legacyReadNotifications } from '../../logic/notifications/legacy_read_notifications'; // eslint-disable-next-line no-restricted-imports -import type { LegacyRuleNotificationAlertTypeParams } from '../../notifications/legacy_types'; +import type { LegacyRuleNotificationAlertTypeParams } from '../../logic/notifications/legacy_types'; // eslint-disable-next-line no-restricted-imports -import { legacyCreateNotifications } from '../../notifications/legacy_create_notifications'; +import { legacyCreateNotifications } from '../../logic/notifications/legacy_create_notifications'; /** * Given an "alert_id" and a valid "action_id" this will create a legacy notification. This is for testing diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/register_routes.ts new file mode 100644 index 0000000000000..aa4010691a71b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/api/register_routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { SecuritySolutionPluginRouter } from '../../../../types'; + +// eslint-disable-next-line no-restricted-imports +import { legacyCreateLegacyNotificationRoute } from './create_legacy_notification/route'; + +export const registerLegacyRuleActionsRoutes = ( + router: SecuritySolutionPluginRouter, + logger: Logger +) => { + // Once we no longer have the legacy notifications system/"side car actions" this should be removed. + legacyCreateLegacyNotificationRoute(router, logger); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts new file mode 100644 index 0000000000000..22d3c347eef85 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/index.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/register_routes'; + +// eslint-disable-next-line no-restricted-imports +export { legacyRulesNotificationAlertType } from './logic/notifications/legacy_rules_notification_alert_type'; +// eslint-disable-next-line no-restricted-imports +export { legacyIsNotificationAlertExecutor } from './logic/notifications/legacy_types'; +// eslint-disable-next-line no-restricted-imports +export type { + LegacyRuleNotificationAlertType, + LegacyRuleNotificationAlertTypeParams, +} from './logic/notifications/legacy_types'; +export type { NotificationRuleTypeParams } from './logic/notifications/schedule_notification_actions'; +export { scheduleNotificationActions } from './logic/notifications/schedule_notification_actions'; +export { scheduleThrottledNotificationActions } from './logic/notifications/schedule_throttle_notification_actions'; +export { getNotificationResultsLink } from './logic/notifications/utils'; + +// eslint-disable-next-line no-restricted-imports +export { legacyGetBulkRuleActionsSavedObject } from './logic/rule_actions/legacy_get_bulk_rule_actions_saved_object'; +// eslint-disable-next-line no-restricted-imports +export type { LegacyRulesActionsSavedObject } from './logic/rule_actions/legacy_get_rule_actions_saved_object'; +// eslint-disable-next-line no-restricted-imports +export { legacyGetRuleActionsSavedObject } from './logic/rule_actions/legacy_get_rule_actions_saved_object'; +// eslint-disable-next-line no-restricted-imports +export { + legacyType, + legacyRuleActionsSavedObjectType, +} from './logic/rule_actions/legacy_saved_object_mappings'; +// eslint-disable-next-line no-restricted-imports +export type { + LegacyRuleActions, + LegacyRuleAlertAction, + LegacyIRuleActionsAttributes, + LegacyRuleAlertSavedObjectAction, + LegacyIRuleActionsAttributesSavedObjectAttributes, +} from './logic/rule_actions/legacy_types'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/build_signals_query.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/build_signals_query.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/build_signals_query.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/build_signals_query.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/build_signals_query.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/build_signals_query.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/build_signals_query.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/build_signals_query.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/get_signals.ts similarity index 92% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/get_signals.ts index ab202170e5764..5963cc0cb2211 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/get_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/get_signals.ts @@ -6,7 +6,7 @@ */ import type { ElasticsearchClient } from '@kbn/core/server'; -import type { SignalSearchResponse, SignalSource } from '../signals/types'; +import type { SignalSearchResponse, SignalSource } from '../../../signals/types'; import { buildSignalsSearchQuery } from './build_signals_query'; interface GetSignalsParams { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts index 5db2759ad88da..983519404b222 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_create_notifications.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_create_notifications.ts @@ -6,7 +6,7 @@ */ import type { SanitizedRule } from '@kbn/alerting-plugin/common'; -import { SERVER_APP_ID, LEGACY_NOTIFICATIONS_ID } from '../../../../common/constants'; +import { SERVER_APP_ID, LEGACY_NOTIFICATIONS_ID } from '../../../../../../common/constants'; // eslint-disable-next-line no-restricted-imports import type { CreateNotificationParams, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_find_notifications.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_find_notifications.test.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_find_notifications.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_find_notifications.test.ts index 32a1b0eacd55b..d5ebddf4d2b63 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_find_notifications.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_find_notifications.test.ts @@ -7,7 +7,7 @@ // eslint-disable-next-line no-restricted-imports import { legacyGetFilter } from './legacy_find_notifications'; -import { LEGACY_NOTIFICATIONS_ID } from '../../../../common/constants'; +import { LEGACY_NOTIFICATIONS_ID } from '../../../../../../common/constants'; describe('legacyFind_notifications', () => { test('it returns a full filter with an AND if sent down', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_find_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_find_notifications.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_find_notifications.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_find_notifications.ts index ba2f3e54dd9dc..0f981e6c6a005 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_find_notifications.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_find_notifications.ts @@ -6,7 +6,7 @@ */ import type { RuleTypeParams, FindResult } from '@kbn/alerting-plugin/server'; -import { LEGACY_NOTIFICATIONS_ID } from '../../../../common/constants'; +import { LEGACY_NOTIFICATIONS_ID } from '../../../../../../common/constants'; // eslint-disable-next-line no-restricted-imports import type { LegacyFindNotificationParams } from './legacy_types'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.test.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.test.ts index 0980159d67882..f39881ac63250 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.test.ts @@ -11,7 +11,7 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { legacyGetNotificationResult, legacyGetFindNotificationsResultWithSingleHit, -} from '../routes/__mocks__/request_responses'; +} from '../../../routes/__mocks__/request_responses'; class LegacyTestError extends Error { constructor() { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_read_notifications.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_read_notifications.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts index b79e8ac4cbbdb..ddfca67279074 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.test.ts @@ -9,7 +9,7 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import type { RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; -import { getRuleMock } from '../routes/__mocks__/request_responses'; +import { getRuleMock } from '../../../routes/__mocks__/request_responses'; // eslint-disable-next-line no-restricted-imports import { legacyRulesNotificationAlertType } from './legacy_rules_notification_alert_type'; import { buildSignalsSearchQuery } from './build_signals_query'; @@ -19,9 +19,9 @@ import { sampleDocSearchResultsNoSortIdNoVersion, sampleDocSearchResultsWithSortId, sampleEmptyDocSearchResults, -} from '../signals/__mocks__/es_results'; -import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../common/constants'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; +} from '../../../signals/__mocks__/es_results'; +import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../../../common/constants'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; jest.mock('./build_signals_query'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts similarity index 96% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts index 880882df04af2..7e76c2c1158d2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_rules_notification_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_rules_notification_alert_type.ts @@ -11,14 +11,14 @@ import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE, LEGACY_NOTIFICATIONS_ID, SERVER_APP_ID, -} from '../../../../common/constants'; +} from '../../../../../../common/constants'; // eslint-disable-next-line no-restricted-imports import type { LegacyNotificationAlertTypeDefinition } from './legacy_types'; // eslint-disable-next-line no-restricted-imports import { legacyRulesNotificationParams } from './legacy_types'; -import type { AlertAttributes } from '../signals/types'; -import { siemRuleActionGroups } from '../signals/siem_rule_action_groups'; +import type { AlertAttributes } from '../../../signals/types'; +import { siemRuleActionGroups } from '../../../signals/siem_rule_action_groups'; import { scheduleNotificationActions } from './schedule_notification_actions'; import { getNotificationResultsLink } from './utils'; import { getSignals } from './get_signals'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/README.md b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/README.md similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/README.md rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/README.md diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_references.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_references.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_references.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_references.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_rule_id.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_rule_id.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_rule_id.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_rule_id.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_rule_id.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_rule_id.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_extract_rule_id.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_extract_rule_id.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_references.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_references.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_references.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_references.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_references.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_references.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_references.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_saved_object_references/legacy_inject_rule_id_references.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_types.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts index a3516d2caa7f0..2aea76d8c51e1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/legacy_types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/legacy_types.ts @@ -19,7 +19,7 @@ import type { RuleExecutorOptions, } from '@kbn/alerting-plugin/server'; import type { Rule, RuleAction } from '@kbn/alerting-plugin/common'; -import { LEGACY_NOTIFICATIONS_ID } from '../../../../common/constants'; +import { LEGACY_NOTIFICATIONS_ID } from '../../../../../../common/constants'; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_notification_actions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_notification_actions.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_notification_actions.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_notification_actions.test.ts index 05741547241a3..b82136e33acf2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_notification_actions.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_notification_actions.test.ts @@ -7,9 +7,9 @@ import type { RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; -import type { DetectionAlert } from '../../../../common/detection_engine/schemas/alerts'; -import { ALERT_THRESHOLD_RESULT_COUNT } from '../../../../common/field_maps/field_names'; -import { sampleThresholdAlert } from '../rule_types/__mocks__/threshold'; +import type { DetectionAlert } from '../../../../../../common/detection_engine/schemas/alerts'; +import { ALERT_THRESHOLD_RESULT_COUNT } from '../../../../../../common/field_maps/field_names'; +import { sampleThresholdAlert } from '../../../rule_types/__mocks__/threshold'; import type { NotificationRuleTypeParams } from './schedule_notification_actions'; import { formatAlertsForNotificationActions, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_notification_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_notification_actions.ts similarity index 81% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_notification_actions.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_notification_actions.ts index 7783ca0e1ede8..8ca2bc0a4fb01 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_notification_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_notification_actions.ts @@ -9,13 +9,13 @@ import { mapKeys, snakeCase } from 'lodash/fp'; import type { Alert } from '@kbn/alerting-plugin/server'; import { ALERT_RULE_TYPE } from '@kbn/rule-data-utils'; import { flattenWithPrefix } from '@kbn/securitysolution-rules'; -import { ALERT_THRESHOLD_RESULT } from '../../../../common/field_maps/field_names'; -import { isThresholdRule } from '../../../../common/detection_engine/utils'; -import { expandDottedObject } from '../../../../common/utils/expand_dotted'; -import type { RuleParams } from '../schemas/rule_schemas'; -import aadFieldConversion from '../routes/index/signal_aad_mapping.json'; -import { isDetectionAlert } from '../signals/utils'; -import type { DetectionAlert } from '../../../../common/detection_engine/schemas/alerts'; +import { ALERT_THRESHOLD_RESULT } from '../../../../../../common/field_maps/field_names'; +import { isThresholdRule } from '../../../../../../common/detection_engine/utils'; +import { expandDottedObject } from '../../../../../../common/utils/expand_dotted'; +import type { RuleParams } from '../../../rule_schema'; +import aadFieldConversion from '../../../routes/index/signal_aad_mapping.json'; +import { isDetectionAlert } from '../../../signals/utils'; +import type { DetectionAlert } from '../../../../../../common/detection_engine/schemas/alerts'; export type NotificationRuleTypeParams = RuleParams & { id: string; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_throttle_notification_actions.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_throttle_notification_actions.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_throttle_notification_actions.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_throttle_notification_actions.ts index 90bc88a7ccb56..98f5ee9d42557 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/schedule_throttle_notification_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/schedule_throttle_notification_actions.ts @@ -8,13 +8,13 @@ import type { ElasticsearchClient, SavedObject, Logger } from '@kbn/core/server'; import { parseScheduleDates } from '@kbn/securitysolution-io-ts-utils'; import type { Alert } from '@kbn/alerting-plugin/server'; -import type { RuleParams } from '../schemas/rule_schemas'; +import type { RuleParams } from '../../../rule_schema'; import { deconflictSignalsAndResults, getNotificationResultsLink } from './utils'; -import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../common/constants'; +import { DEFAULT_RULE_NOTIFICATION_QUERY_SIZE } from '../../../../../../common/constants'; import { getSignals } from './get_signals'; import type { NotificationRuleTypeParams } from './schedule_notification_actions'; import { scheduleNotificationActions } from './schedule_notification_actions'; -import type { AlertAttributes } from '../signals/types'; +import type { AlertAttributes } from '../../../signals/types'; interface ScheduleThrottledNotificationActionsOptions { id: SavedObject['id']; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/utils.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/utils.test.ts index d281cc9ae977b..cb3c4e0d4bd41 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/utils.test.ts @@ -7,7 +7,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import type { SignalSource } from '../signals/types'; +import type { SignalSource } from '../../../signals/types'; import { deconflictSignalsAndResults, getNotificationResultsLink } from './utils'; describe('utils', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/utils.ts similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/utils.ts index 560ec11cbef19..9eef538efe859 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/notifications/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/notifications/utils.ts @@ -6,8 +6,8 @@ */ import type { Logger } from '@kbn/core/server'; -import { APP_PATH } from '../../../../common/constants'; -import type { SignalSearchResponse } from '../signals/types'; +import { APP_PATH } from '../../../../../../common/constants'; +import type { SignalSearchResponse } from '../../../signals/types'; export const getNotificationResultsLink = ({ kibanaSiemAppUrl = APP_PATH, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_create_rule_actions_saved_object.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_create_rule_actions_saved_object.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_create_rule_actions_saved_object.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_create_rule_actions_saved_object.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_create_rule_actions_saved_object.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_bulk_rule_actions_saved_object.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_bulk_rule_actions_saved_object.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_bulk_rule_actions_saved_object.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_bulk_rule_actions_saved_object.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_bulk_rule_actions_saved_object.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_bulk_rule_actions_saved_object.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_bulk_rule_actions_saved_object.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_bulk_rule_actions_saved_object.ts index e827bd4fe14e5..300d5307c1773 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_bulk_rule_actions_saved_object.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_bulk_rule_actions_saved_object.ts @@ -17,7 +17,7 @@ import type { LegacyIRuleActionsAttributesSavedObjectAttributes } from './legacy import { legacyGetRuleActionsFromSavedObject } from './legacy_utils'; // eslint-disable-next-line no-restricted-imports import type { LegacyRulesActionsSavedObject } from './legacy_get_rule_actions_saved_object'; -import { initPromisePool } from '../../../utils/promise_pool'; +import { initPromisePool } from '../../../../../utils/promise_pool'; /** * @deprecated Once we are confident all rules relying on side-car actions SO's have been migrated to SO references we should remove this function diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_rule_actions_saved_object.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_rule_actions_saved_object.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_rule_actions_saved_object.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_get_rule_actions_saved_object.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_get_rule_actions_saved_object.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_migrations.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_migrations.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_migrations.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_migrations.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_migrations.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_saved_object_mappings.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_saved_object_mappings.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_saved_object_mappings.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_saved_object_mappings.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_types.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_types.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_types.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_update_or_create_rule_actions_saved_object.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_update_or_create_rule_actions_saved_object.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_update_or_create_rule_actions_saved_object.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_update_or_create_rule_actions_saved_object.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_update_rule_actions_saved_object.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_update_rule_actions_saved_object.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_update_rule_actions_saved_object.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_update_rule_actions_saved_object.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_utils.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_utils.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_utils.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_utils.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions/legacy_utils.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_actions_legacy/logic/rule_actions/legacy_utils.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.test.ts index a65d165f9e109..ab7efc936a58a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.test.ts @@ -7,11 +7,11 @@ import { getDetectionsExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { getRuleMock, resolveRuleMock } from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { createRuleExceptionsRoute } from './create_rule_exceptions_route'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../common/constants'; +import { getRuleMock, resolveRuleMock } from '../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../routes/__mocks__'; +import { createRuleExceptionsRoute } from './route'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; const getMockExceptionItem = () => ({ description: 'Exception item for rule default exception list', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts similarity index 86% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts index 8b5c3e1b044f2..9a13833e08437 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rule_exceptions_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts @@ -27,35 +27,38 @@ import { formatErrors, validate } from '@kbn/securitysolution-io-ts-utils'; import type { SanitizedRule } from '@kbn/alerting-plugin/common'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; import type { RulesClient } from '@kbn/alerting-plugin/server'; + import type { - CreateRuleExceptionSchemaDecoded, - QueryRuleByIdSchemaDecoded, -} from '../../../../../common/detection_engine/schemas/request'; + CreateRuleExceptionsRequestBodyDecoded, + CreateRuleExceptionsRequestParamsDecoded, +} from '../../../../../../common/detection_engine/rule_exceptions'; import { - createRuleExceptionsSchema, - queryRuleByIdSchema, -} from '../../../../../common/detection_engine/schemas/request'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { buildSiemResponse } from '../utils'; -import { patchRules } from '../../rules/patch_rules'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import { readRules } from '../../rules/read_rules'; -import type { RuleParams } from '../../schemas/rule_schemas'; -import { checkDefaultRuleExceptionListReferences } from './utils/check_for_default_rule_exception_list'; + CREATE_RULE_EXCEPTIONS_URL, + CreateRuleExceptionsRequestBody, + CreateRuleExceptionsRequestParams, +} from '../../../../../../common/detection_engine/rule_exceptions'; + +import { readRules } from '../../../rule_management/logic/crud/read_rules'; +import { patchRules } from '../../../rule_management/logic/crud/patch_rules'; +import { checkDefaultRuleExceptionListReferences } from '../../../rule_management/logic/exceptions/check_for_default_rule_exception_list'; +import type { RuleParams } from '../../../rule_schema'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; +import { buildSiemResponse } from '../../../routes/utils'; +import { buildRouteValidation } from '../../../../../utils/build_validation/route_validation'; export const createRuleExceptionsRoute = (router: SecuritySolutionPluginRouter) => { router.post( { - path: `${DETECTION_ENGINE_RULES_URL}/{id}/exceptions`, + path: CREATE_RULE_EXCEPTIONS_URL, validate: { - params: buildRouteValidation( - queryRuleByIdSchema - ), + params: buildRouteValidation< + typeof CreateRuleExceptionsRequestParams, + CreateRuleExceptionsRequestParamsDecoded + >(CreateRuleExceptionsRequestParams), body: buildRouteValidation< - typeof createRuleExceptionsSchema, - CreateRuleExceptionSchemaDecoded - >(createRuleExceptionsSchema), + typeof CreateRuleExceptionsRequestBody, + CreateRuleExceptionsRequestBodyDecoded + >(CreateRuleExceptionsRequestBody), }, options: { tags: ['access:securitySolution'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.test.ts similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.test.ts index 39d2dca25f050..33e66bb6405f8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.test.ts @@ -5,16 +5,18 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '../../../../../common/constants'; +import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; + +import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '../../../../../../common/detection_engine/rule_exceptions'; + import { getEmptyFindResult, getFindResultWithSingleHit, getRuleMock, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { findRuleExceptionReferencesRoute } from './find_rule_exceptions_route'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; +} from '../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../routes/__mocks__'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; +import { findRuleExceptionReferencesRoute } from './route'; describe('findRuleExceptionReferencesRoute', () => { let server: ReturnType; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts similarity index 79% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts index 8d1dc2cc7c49e..a9643989a3a3b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rule_exceptions_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/find_exception_references/route.ts @@ -9,16 +9,22 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { getSavedObjectType } from '@kbn/securitysolution-list-utils'; import { validate } from '@kbn/securitysolution-io-ts-utils'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '../../../../../common/constants'; -import { buildSiemResponse } from '../utils'; -import { enrichFilterWithRuleTypeMapping } from '../../rules/enrich_filter_with_rule_type_mappings'; -import type { FindExceptionReferencesOnRuleSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/find_exception_list_references_schema'; -import { findExceptionReferencesOnRuleSchema } from '../../../../../common/detection_engine/schemas/request/find_exception_list_references_schema'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { RuleReferencesSchema } from '../../../../../common/detection_engine/schemas/response/find_exception_list_references_schema'; -import { rulesReferencedByExceptionListsSchema } from '../../../../../common/detection_engine/schemas/response/find_exception_list_references_schema'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import { buildRouteValidation } from '../../../../../utils/build_validation/route_validation'; +import { buildSiemResponse } from '../../../routes/utils'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; + +import type { + FindExceptionReferencesOnRuleSchemaDecoded, + RuleReferencesSchema, +} from '../../../../../../common/detection_engine/rule_exceptions'; +import { + DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL, + findExceptionReferencesOnRuleSchema, + rulesReferencedByExceptionListsSchema, +} from '../../../../../../common/detection_engine/rule_exceptions'; + +import { enrichFilterWithRuleTypeMapping } from '../../../rule_management/logic/search/enrich_filter_with_rule_type_mappings'; +import type { RuleParams } from '../../../rule_schema'; export const findRuleExceptionReferencesRoute = (router: SecuritySolutionPluginRouter) => { router.get( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/register_routes.ts new file mode 100644 index 0000000000000..4d65f13c94ee2 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/register_routes.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SecuritySolutionPluginRouter } from '../../../../types'; + +import { createRuleExceptionsRoute } from './create_rule_exceptions/route'; +import { findRuleExceptionReferencesRoute } from './find_exception_references/route'; + +export const registerRuleExceptionsRoutes = (router: SecuritySolutionPluginRouter) => { + createRuleExceptionsRoute(router); + findRuleExceptionReferencesRoute(router); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/index.ts new file mode 100644 index 0000000000000..c0123e587d9bf --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/register_routes'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/deprecation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/deprecation.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/deprecation.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/deprecation.ts index 314d7db33fcef..8e956e0e48aa6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/deprecation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/deprecation.ts @@ -7,7 +7,7 @@ import { getDocLinks } from '@kbn/doc-links'; import type { Logger } from '@kbn/core/server'; -import { DETECTION_ENGINE_RULES_BULK_ACTION } from '../../../../../../common/constants'; +import { DETECTION_ENGINE_RULES_BULK_ACTION } from '../../../../../common/constants'; /** * Helper method for building deprecation messages diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/register_routes.ts new file mode 100644 index 0000000000000..90a37a7dbe7da --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/register_routes.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger } from '@kbn/core/server'; +import type { ConfigType } from '../../../../config'; +import type { SetupPlugins } from '../../../../plugin_contract'; +import type { SecuritySolutionPluginRouter } from '../../../../types'; + +import { performBulkActionRoute } from './rules/bulk_actions/route'; +import { bulkCreateRulesRoute } from './rules/bulk_create_rules/route'; +import { bulkDeleteRulesRoute } from './rules/bulk_delete_rules/route'; +import { bulkPatchRulesRoute } from './rules/bulk_patch_rules/route'; +import { bulkUpdateRulesRoute } from './rules/bulk_update_rules/route'; +import { createRuleRoute } from './rules/create_rule/route'; +import { deleteRuleRoute } from './rules/delete_rule/route'; +import { exportRulesRoute } from './rules/export_rules/route'; +import { findRulesRoute } from './rules/find_rules/route'; +import { importRulesRoute } from './rules/import_rules/route'; +import { patchRuleRoute } from './rules/patch_rule/route'; +import { readRuleRoute } from './rules/read_rule/route'; +import { updateRuleRoute } from './rules/update_rule/route'; +import { readTagsRoute } from './tags/read_tags/route'; + +export const registerRuleManagementRoutes = ( + router: SecuritySolutionPluginRouter, + config: ConfigType, + ml: SetupPlugins['ml'], + logger: Logger +) => { + // Rules CRUD + createRuleRoute(router, ml); + readRuleRoute(router, logger); + updateRuleRoute(router, ml); + patchRuleRoute(router, ml); + deleteRuleRoute(router); + + // Rules bulk CRUD + bulkCreateRulesRoute(router, ml, logger); + bulkUpdateRulesRoute(router, ml, logger); + bulkPatchRulesRoute(router, ml, logger); + bulkDeleteRulesRoute(router, logger); + + // Rules bulk actions + performBulkActionRoute(router, ml, logger); + + // Rules export/import + exportRulesRoute(router, config, logger); + importRulesRoute(router, config, ml); + + // Rules search + findRulesRoute(router, logger); + + // Rule tags + readTagsRoute(router); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts index 1438905a5c079..f64de099dfcbe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts @@ -8,9 +8,9 @@ import { DETECTION_ENGINE_RULES_BULK_ACTION, BulkActionsDryRunErrCode, -} from '../../../../../common/constants'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; +} from '../../../../../../../common/constants'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; import { getEmptyFindResult, getBulkActionRequest, @@ -18,30 +18,31 @@ import { getFindResultWithSingleHit, getFindResultWithMultiHits, getRuleMock, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { performBulkActionRoute } from './perform_bulk_action_route'; +} from '../../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; +import { performBulkActionRoute } from './route'; import { getPerformBulkActionEditSchemaMock, getPerformBulkActionSchemaMock, -} from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema.mock'; +} from '../../../../../../../common/detection_engine/rule_management/mocks'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { readRules } from '../../rules/read_rules'; -import { legacyMigrate } from '../../rules/utils'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +import { readRules } from '../../../logic/crud/read_rules'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); -jest.mock('../../rules/read_rules', () => ({ readRules: jest.fn() })); +jest.mock('../../../../../machine_learning/authz'); +jest.mock('../../../logic/crud/read_rules', () => ({ readRules: jest.fn() })); -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +jest.mock('../../../logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual('../../../logic/rule_actions/legacy_action_migration'); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('perform_bulk_action', () => { +describe('Perform bulk action route', () => { const readRulesMock = readRules as jest.Mock; let server: ReturnType; let { clients, context } = requestContextMock.createTools(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts similarity index 90% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts index 56d93a1ed0336..67a9a233eb807 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/perform_bulk_action_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.ts @@ -13,43 +13,43 @@ import type { KibanaResponseFactory, Logger, SavedObjectsClientContract } from ' import type { RulesClient, BulkEditError } from '@kbn/alerting-plugin/server'; import type { SanitizedRule } from '@kbn/alerting-plugin/common'; import { AbortError } from '@kbn/kibana-utils-plugin/common'; -import type { RuleAlertType } from '../../rules/types'; +import type { RuleAlertType, RuleParams } from '../../../../rule_schema'; -import type { BulkActionsDryRunErrCode } from '../../../../../common/constants'; +import type { BulkActionsDryRunErrCode } from '../../../../../../../common/constants'; import { DETECTION_ENGINE_RULES_BULK_ACTION, MAX_RULES_TO_UPDATE_IN_PARALLEL, RULES_TABLE_MAX_PAGE_SIZE, -} from '../../../../../common/constants'; +} from '../../../../../../../common/constants'; import { - performBulkActionSchema, - performBulkActionQuerySchema, BulkAction, -} from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { SetupPlugins } from '../../../../plugin'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import { routeLimitedConcurrencyTag } from '../../../../utils/route_limited_concurrency_tag'; -import type { PromisePoolError, PromisePoolOutcome } from '../../../../utils/promise_pool'; -import { initPromisePool } from '../../../../utils/promise_pool'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { deleteRules } from '../../rules/delete_rules'; -import { duplicateRule } from '../../rules/duplicate_rule'; -import { findRules } from '../../rules/find_rules'; -import { readRules } from '../../rules/read_rules'; -import { bulkEditRules } from '../../rules/bulk_edit_rules'; -import { getExportByObjectIds } from '../../rules/get_export_by_object_ids'; -import { buildSiemResponse } from '../utils'; -import { internalRuleToAPIResponse } from '../../schemas/rule_converters'; -import { legacyMigrate } from '../../rules/utils'; -import type { DryRunError } from '../../rules/bulk_actions/dry_run'; + PerformBulkActionRequestBody, + PerformBulkActionRequestQuery, +} from '../../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { SetupPlugins } from '../../../../../../plugin'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import { routeLimitedConcurrencyTag } from '../../../../../../utils/route_limited_concurrency_tag'; +import type { PromisePoolError, PromisePoolOutcome } from '../../../../../../utils/promise_pool'; +import { initPromisePool } from '../../../../../../utils/promise_pool'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { deleteRules } from '../../../logic/crud/delete_rules'; +import { duplicateRule } from '../../../logic/actions/duplicate_rule'; +import { findRules } from '../../../logic/search/find_rules'; +import { readRules } from '../../../logic/crud/read_rules'; +import { getExportByObjectIds } from '../../../logic/export/get_export_by_object_ids'; +import { buildSiemResponse } from '../../../../routes/utils'; +import { internalRuleToAPIResponse } from '../../../normalization/rule_converters'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { bulkEditRules } from '../../../logic/bulk_actions/bulk_edit_rules'; +import type { DryRunError } from '../../../logic/bulk_actions/dry_run'; import { validateBulkEnableRule, validateBulkDisableRule, validateBulkDuplicateRule, dryRunValidateBulkEditRule, -} from '../../rules/bulk_actions/validations'; -import type { RuleParams } from '../../schemas/rule_schemas'; +} from '../../../logic/bulk_actions/validations'; const MAX_RULES_TO_PROCESS_TOTAL = 10000; const MAX_ERROR_MESSAGE_LENGTH = 1000; @@ -267,10 +267,8 @@ export const performBulkActionRoute = ( { path: DETECTION_ENGINE_RULES_BULK_ACTION, validate: { - body: buildRouteValidation(performBulkActionSchema), - query: buildRouteValidation( - performBulkActionQuerySchema - ), + body: buildRouteValidation(PerformBulkActionRequestBody), + query: buildRouteValidation(PerformBulkActionRequestQuery), }, options: { tags: ['access:securitySolution', routeLimitedConcurrencyTag(MAX_ROUTE_CONCURRENCY)], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/get_duplicates.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/get_duplicates.test.ts new file mode 100644 index 0000000000000..bc15b93639cdb --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/get_duplicates.test.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { BulkCreateRulesRequestBody } from '../../../../../../../common/detection_engine/rule_management'; +import { getDuplicates } from './get_duplicates'; + +describe('getDuplicates', () => { + test("returns array of ruleIds showing the duplicate keys of 'value2' and 'value3'", () => { + const output = getDuplicates( + [ + { rule_id: 'value1' }, + { rule_id: 'value2' }, + { rule_id: 'value2' }, + { rule_id: 'value3' }, + { rule_id: 'value3' }, + {}, + {}, + ] as BulkCreateRulesRequestBody, + 'rule_id' + ); + const expected = ['value2', 'value3']; + expect(output).toEqual(expected); + }); + + test('returns null when given a map of no duplicates', () => { + const output = getDuplicates( + [ + { rule_id: 'value1' }, + { rule_id: 'value2' }, + { rule_id: 'value3' }, + {}, + {}, + ] as BulkCreateRulesRequestBody, + 'rule_id' + ); + const expected: string[] = []; + expect(output).toEqual(expected); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/get_duplicates.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/get_duplicates.ts new file mode 100644 index 0000000000000..3d537bbd25c46 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/get_duplicates.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { countBy } from 'lodash/fp'; +import type { BulkCreateRulesRequestBody } from '../../../../../../../common/detection_engine/rule_management'; + +export const getDuplicates = ( + ruleDefinitions: BulkCreateRulesRequestBody, + by: 'rule_id' +): string[] => { + const mappedDuplicates = countBy( + by, + ruleDefinitions.filter((r) => r[by] != null) + ); + const hasDuplicates = Object.values(mappedDuplicates).some((i) => i > 1); + if (hasDuplicates) { + return Object.keys(mappedDuplicates).filter((key) => mappedDuplicates[key] > 1); + } + return []; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.test.ts similarity index 90% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.test.ts index c845f2e0a381c..1dcb5e885d72b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.test.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../../common/constants'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; +import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../../../../common/constants'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; import { getReadBulkRequest, getFindResultWithSingleHit, @@ -16,17 +16,17 @@ import { createBulkMlRuleRequest, getBasicEmptySearchResponse, getBasicNoShardsSearchResponse, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { createRulesBulkRoute } from './create_rules_bulk_route'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; +} from '../../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; +import { bulkCreateRulesRoute } from './route'; +import { getCreateRulesSchemaMock } from '../../../../../../../common/detection_engine/rule_schema/mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); +jest.mock('../../../../../machine_learning/authz'); -describe('create_rules_bulk', () => { +describe('Bulk create rules route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -43,7 +43,7 @@ describe('create_rules_bulk', () => { context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse()) ); - createRulesBulkRoute(server.router, ml, logger); + bulkCreateRulesRoute(server.router, ml, logger); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts similarity index 73% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts index b6bdba6fca3bd..960ddb15c5301 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts @@ -5,29 +5,37 @@ * 2.0. */ -import { validate } from '@kbn/securitysolution-io-ts-utils'; import type { Logger } from '@kbn/core/server'; -import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents'; -import { createRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/create_rules_bulk_schema'; -import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../../common/constants'; -import type { SetupPlugins } from '../../../../plugin'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { readRules } from '../../rules/read_rules'; -import { getDuplicates } from './utils'; -import { transformValidateBulkError } from './validate'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; +import { validate } from '@kbn/securitysolution-io-ts-utils'; + +import { DETECTION_ENGINE_RULES_BULK_CREATE } from '../../../../../../../common/constants'; +import { + BulkCreateRulesRequestBody, + validateCreateRuleProps, + BulkCrudRulesResponse, +} from '../../../../../../../common/detection_engine/rule_management'; + +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import type { SetupPlugins } from '../../../../../../plugin'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../../machine_learning/validation'; +import { createRules } from '../../../logic/crud/create_rules'; +import { readRules } from '../../../logic/crud/read_rules'; +import { getDuplicates } from './get_duplicates'; +import { transformValidateBulkError } from '../../../utils/validate'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; -import { transformBulkError, createBulkErrorObject, buildSiemResponse } from '../utils'; -import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation'; -import { createRules } from '../../rules/create_rules'; +import { + transformBulkError, + createBulkErrorObject, + buildSiemResponse, +} from '../../../../routes/utils'; +import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; /** * @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead */ -export const createRulesBulkRoute = ( +export const bulkCreateRulesRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], logger: Logger @@ -36,7 +44,7 @@ export const createRulesBulkRoute = ( { path: DETECTION_ENGINE_RULES_BULK_CREATE, validate: { - body: buildRouteValidation(createRulesBulkSchema), + body: buildRouteValidation(BulkCreateRulesRequestBody), }, options: { tags: ['access:securitySolution'], @@ -82,7 +90,7 @@ export const createRulesBulkRoute = ( } try { - const validationErrors = createRuleValidateTypeDependents(payloadRule); + const validationErrors = validateCreateRuleProps(payloadRule); if (validationErrors.length) { return createBulkErrorObject({ ruleId: payloadRule.rule_id, @@ -117,7 +125,7 @@ export const createRulesBulkRoute = ( }) ), ]; - const [validated, errors] = validate(rulesBulk, rulesBulkSchema); + const [validated, errors] = validate(rulesBulk, BulkCrudRulesResponse); if (errors != null) { return siemResponse.error({ statusCode: 500, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.test.ts similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.test.ts index 01683599e4cf6..750419c464b2a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../../common/constants'; +import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../../../../common/constants'; import { getEmptyFindResult, getFindResultWithSingleHit, @@ -14,12 +14,12 @@ import { getDeleteAsPostBulkRequest, getDeleteAsPostBulkRequestById, getEmptySavedObjectsResponse, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { deleteRulesBulkRoute } from './delete_rules_bulk_route'; +} from '../../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; +import { bulkDeleteRulesRoute } from './route'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -describe('delete_rules', () => { +describe('Bulk delete rules route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); @@ -32,7 +32,7 @@ describe('delete_rules', () => { clients.rulesClient.delete.mockResolvedValue({}); // successful deletion clients.savedObjectsClient.find.mockResolvedValue(getEmptySavedObjectsResponse()); // rule status request - deleteRulesBulkRoute(server.router, logger); + bulkDeleteRulesRoute(server.router, logger); }); describe('status codes with actionClient and alertClient', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts similarity index 68% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts index 2a459dd7c2941..399b12ded105e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts @@ -5,32 +5,40 @@ * 2.0. */ +import type { RouteConfig, RequestHandler, Logger } from '@kbn/core/server'; import { validate } from '@kbn/securitysolution-io-ts-utils'; -import type { RouteConfig, RequestHandler, Logger } from '@kbn/core/server'; -import { queryRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/query_rules_type_dependents'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { QueryRulesBulkSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/query_rules_bulk_schema'; -import { queryRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/query_rules_bulk_schema'; -import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema'; +import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../../../../common/constants'; +import { + BulkDeleteRulesRequestBody, + validateQueryRuleByIds, + BulkCrudRulesResponse, +} from '../../../../../../../common/detection_engine/rule_management'; + +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; import type { SecuritySolutionPluginRouter, SecuritySolutionRequestHandlerContext, -} from '../../../../types'; -import { DETECTION_ENGINE_RULES_BULK_DELETE } from '../../../../../common/constants'; -import { getIdBulkError } from './utils'; -import { transformValidateBulkError } from './validate'; -import { transformBulkError, buildSiemResponse, createBulkErrorObject } from '../utils'; -import { deleteRules } from '../../rules/delete_rules'; -import { readRules } from '../../rules/read_rules'; -import { legacyMigrate } from '../../rules/utils'; -import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation'; +} from '../../../../../../types'; + +import { getIdBulkError } from '../../../utils/utils'; +import { transformValidateBulkError } from '../../../utils/validate'; +import { + transformBulkError, + buildSiemResponse, + createBulkErrorObject, +} from '../../../../routes/utils'; +import { deleteRules } from '../../../logic/crud/delete_rules'; +import { readRules } from '../../../logic/crud/read_rules'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; -type Config = RouteConfig; +type Config = RouteConfig; type Handler = RequestHandler< unknown, unknown, - QueryRulesBulkSchemaDecoded, + BulkDeleteRulesRequestBody, SecuritySolutionRequestHandlerContext, 'delete' | 'post' >; @@ -38,12 +46,10 @@ type Handler = RequestHandler< /** * @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead */ -export const deleteRulesBulkRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { +export const bulkDeleteRulesRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { const config: Config = { validate: { - body: buildRouteValidation( - queryRulesBulkSchema - ), + body: buildRouteValidation(BulkDeleteRulesRequestBody), }, path: DETECTION_ENGINE_RULES_BULK_DELETE, options: { @@ -65,7 +71,7 @@ export const deleteRulesBulkRoute = (router: SecuritySolutionPluginRouter, logge request.body.map(async (payloadRule) => { const { id, rule_id: ruleId } = payloadRule; const idOrRuleIdOrUnknown = id ?? ruleId ?? '(unknown id)'; - const validationErrors = queryRuleValidateTypeDependents(payloadRule); + const validationErrors = validateQueryRuleByIds(payloadRule); if (validationErrors.length) { return createBulkErrorObject({ ruleId: idOrRuleIdOrUnknown, @@ -103,7 +109,7 @@ export const deleteRulesBulkRoute = (router: SecuritySolutionPluginRouter, logge } }) ); - const [validated, errors] = validate(rules, rulesBulkSchema); + const [validated, errors] = validate(rules, BulkCrudRulesResponse); if (errors != null) { return siemResponse.error({ statusCode: 500, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.test.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.test.ts index da2808e572cf3..2082aa51815fd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.test.ts @@ -8,34 +8,35 @@ import { DETECTION_ENGINE_RULES_BULK_UPDATE, DETECTION_ENGINE_RULES_URL, -} from '../../../../../common/constants'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; +} from '../../../../../../../common/constants'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; import { getEmptyFindResult, getFindResultWithSingleHit, getPatchBulkRequest, getRuleMock, typicalMlRulePayload, -} from '../__mocks__/request_responses'; -import { serverMock, requestContextMock, requestMock } from '../__mocks__'; -import { patchRulesBulkRoute } from './patch_rules_bulk_route'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getMlRuleParams, getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +} from '../../../../routes/__mocks__/request_responses'; +import { serverMock, requestContextMock, requestMock } from '../../../../routes/__mocks__'; +import { bulkPatchRulesRoute } from './route'; +import { getCreateRulesSchemaMock } from '../../../../../../../common/detection_engine/rule_schema/mocks'; +import { getMlRuleParams, getQueryRuleParams } from '../../../../rule_schema/mocks'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { legacyMigrate } from '../../rules/utils'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); +jest.mock('../../../../../machine_learning/authz'); -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +jest.mock('../../../logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual('../../../logic/rule_actions/legacy_action_migration'); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('patch_rules_bulk', () => { +describe('Bulk patch rules route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -51,7 +52,7 @@ describe('patch_rules_bulk', () => { (legacyMigrate as jest.Mock).mockResolvedValue(getRuleMock(getQueryRuleParams())); - patchRulesBulkRoute(server.router, ml, logger); + bulkPatchRulesRoute(server.router, ml, logger); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts similarity index 73% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts index f80a5ffb94e5c..1bbba63daa846 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts @@ -7,26 +7,31 @@ import { validate } from '@kbn/securitysolution-io-ts-utils'; import type { Logger } from '@kbn/core/server'; -import { patchRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/patch_rules_bulk_schema'; -import { buildRouteValidationNonExact } from '../../../../utils/build_validation/route_validation'; -import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../common/constants'; -import type { SetupPlugins } from '../../../../plugin'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { transformBulkError, buildSiemResponse } from '../utils'; -import { getIdBulkError } from './utils'; -import { transformValidateBulkError } from './validate'; -import { patchRules } from '../../rules/patch_rules'; -import { readRules } from '../../rules/read_rules'; -import { legacyMigrate } from '../../rules/utils'; -import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation'; + +import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../../../common/constants'; +import { + BulkPatchRulesRequestBody, + BulkCrudRulesResponse, +} from '../../../../../../../common/detection_engine/rule_management'; + +import { buildRouteValidationNonExact } from '../../../../../../utils/build_validation/route_validation'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import type { SetupPlugins } from '../../../../../../plugin'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../../machine_learning/validation'; +import { transformBulkError, buildSiemResponse } from '../../../../routes/utils'; +import { getIdBulkError } from '../../../utils/utils'; +import { transformValidateBulkError } from '../../../utils/validate'; +import { patchRules } from '../../../logic/crud/patch_rules'; +import { readRules } from '../../../logic/crud/read_rules'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; /** * @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead */ -export const patchRulesBulkRoute = ( +export const bulkPatchRulesRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], logger: Logger @@ -35,7 +40,7 @@ export const patchRulesBulkRoute = ( { path: DETECTION_ENGINE_RULES_BULK_UPDATE, validate: { - body: buildRouteValidationNonExact(patchRulesBulkSchema), + body: buildRouteValidationNonExact(BulkPatchRulesRequestBody), }, options: { tags: ['access:securitySolution'], @@ -101,7 +106,7 @@ export const patchRulesBulkRoute = ( }) ); - const [validated, errors] = validate(rules, rulesBulkSchema); + const [validated, errors] = validate(rules, BulkCrudRulesResponse); if (errors != null) { return siemResponse.error({ statusCode: 500, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.test.ts similarity index 85% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.test.ts index 09e4dacec09de..5c8433b3e87fb 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.test.ts @@ -5,35 +5,36 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../common/constants'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; +import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../../../common/constants'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; import { getEmptyFindResult, getRuleMock, getFindResultWithSingleHit, getUpdateBulkRequest, typicalMlRulePayload, -} from '../__mocks__/request_responses'; -import { serverMock, requestContextMock, requestMock } from '../__mocks__'; -import { updateRulesBulkRoute } from './update_rules_bulk_route'; -import type { BulkError } from '../utils'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +} from '../../../../routes/__mocks__/request_responses'; +import { serverMock, requestContextMock, requestMock } from '../../../../routes/__mocks__'; +import { bulkUpdateRulesRoute } from './route'; +import type { BulkError } from '../../../../routes/utils'; +import { getCreateRulesSchemaMock } from '../../../../../../../common/detection_engine/rule_schema/mocks'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { legacyMigrate } from '../../rules/utils'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); +jest.mock('../../../../../machine_learning/authz'); -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +jest.mock('../../../logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual('../../../logic/rule_actions/legacy_action_migration'); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('update_rules_bulk', () => { +describe('Bulk update rules route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -51,7 +52,7 @@ describe('update_rules_bulk', () => { (legacyMigrate as jest.Mock).mockResolvedValue(getRuleMock(getQueryRuleParams())); - updateRulesBulkRoute(server.router, ml, logger); + bulkUpdateRulesRoute(server.router, ml, logger); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts similarity index 71% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts index d949a4bb9f5f9..5e22fc4d41c20 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_bulk_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts @@ -5,29 +5,38 @@ * 2.0. */ -import { validate } from '@kbn/securitysolution-io-ts-utils'; import type { Logger } from '@kbn/core/server'; -import { updateRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/update_rules_type_dependents'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import { updateRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/update_rules_bulk_schema'; -import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../common/constants'; -import type { SetupPlugins } from '../../../../plugin'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { getIdBulkError } from './utils'; -import { transformValidateBulkError } from './validate'; -import { transformBulkError, buildSiemResponse, createBulkErrorObject } from '../utils'; -import { updateRules } from '../../rules/update_rules'; -import { legacyMigrate } from '../../rules/utils'; -import { readRules } from '../../rules/read_rules'; -import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from './utils/deprecation'; +import { validate } from '@kbn/securitysolution-io-ts-utils'; + +import { + BulkUpdateRulesRequestBody, + validateUpdateRuleProps, + BulkCrudRulesResponse, +} from '../../../../../../../common/detection_engine/rule_management'; + +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '../../../../../../../common/constants'; +import type { SetupPlugins } from '../../../../../../plugin'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../../machine_learning/validation'; +import { getIdBulkError } from '../../../utils/utils'; +import { transformValidateBulkError } from '../../../utils/validate'; +import { + transformBulkError, + buildSiemResponse, + createBulkErrorObject, +} from '../../../../routes/utils'; +import { updateRules } from '../../../logic/crud/update_rules'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { readRules } from '../../../logic/crud/read_rules'; +import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; /** * @deprecated since version 8.2.0. Use the detection_engine/rules/_bulk_action API instead */ -export const updateRulesBulkRoute = ( +export const bulkUpdateRulesRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'], logger: Logger @@ -36,7 +45,7 @@ export const updateRulesBulkRoute = ( { path: DETECTION_ENGINE_RULES_BULK_UPDATE, validate: { - body: buildRouteValidation(updateRulesBulkSchema), + body: buildRouteValidation(BulkUpdateRulesRequestBody), }, options: { tags: ['access:securitySolution'], @@ -64,7 +73,7 @@ export const updateRulesBulkRoute = ( request.body.map(async (payloadRule) => { const idOrRuleIdOrUnknown = payloadRule.id ?? payloadRule.rule_id ?? '(unknown id)'; try { - const validationErrors = updateRuleValidateTypeDependents(payloadRule); + const validationErrors = validateUpdateRuleProps(payloadRule); if (validationErrors.length) { return createBulkErrorObject({ ruleId: payloadRule.rule_id, @@ -104,7 +113,7 @@ export const updateRulesBulkRoute = ( }) ); - const [validated, errors] = validate(rules, rulesBulkSchema); + const [validated, errors] = validate(rules, BulkCrudRulesResponse); if (errors != null) { return siemResponse.error({ statusCode: 500, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts index f3c4a698d83d2..5c333cf240e2d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; import { getEmptyFindResult, getRuleMock, @@ -13,18 +13,18 @@ import { getFindResultWithSingleHit, createMlRuleRequest, getBasicEmptySearchResponse, -} from '../__mocks__/request_responses'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { createRulesRoute } from './create_rules_route'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; +} from '../../../../routes/__mocks__/request_responses'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; +import { createRuleRoute } from './route'; +import { getCreateRulesSchemaMock } from '../../../../../../../common/detection_engine/rule_schema/mocks'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); +jest.mock('../../../../../machine_learning/authz'); -describe('create_rules', () => { +describe('Create rule route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -40,7 +40,7 @@ describe('create_rules', () => { context.core.elasticsearch.client.asCurrentUser.search.mockResolvedValue( elasticsearchClientMock.createSuccessTransportRequestPromise(getBasicEmptySearchResponse()) ); - createRulesRoute(server.router, ml); + createRuleRoute(server.router, ml); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts similarity index 69% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts index 6e76de5aa420d..cfea8ec27a5a7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts @@ -6,22 +6,24 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import type { SetupPlugins } from '../../../../plugin'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { readRules } from '../../rules/read_rules'; -import { buildSiemResponse } from '../utils'; -import { createRulesSchema } from '../../../../../common/detection_engine/schemas/request'; -import { transformValidate } from './validate'; -import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents'; -import { createRules } from '../../rules/create_rules'; -import { checkDefaultRuleExceptionListReferences } from './utils/check_for_default_rule_exception_list'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { validateCreateRuleProps } from '../../../../../../../common/detection_engine/rule_management'; +import { RuleCreateProps } from '../../../../../../../common/detection_engine/rule_schema'; -export const createRulesRoute = ( +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import type { SetupPlugins } from '../../../../../../plugin'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../../machine_learning/validation'; +import { readRules } from '../../../logic/crud/read_rules'; +import { buildSiemResponse } from '../../../../routes/utils'; + +import { createRules } from '../../../logic/crud/create_rules'; +import { checkDefaultRuleExceptionListReferences } from '../../../logic/exceptions/check_for_default_rule_exception_list'; +import { transformValidate } from '../../../utils/validate'; + +export const createRuleRoute = ( router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml'] ): void => { @@ -29,7 +31,7 @@ export const createRulesRoute = ( { path: DETECTION_ENGINE_RULES_URL, validate: { - body: buildRouteValidation(createRulesSchema), + body: buildRouteValidation(RuleCreateProps), }, options: { tags: ['access:securitySolution'], @@ -37,7 +39,7 @@ export const createRulesRoute = ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = createRuleValidateTypeDependents(request.body); + const validationErrors = validateCreateRuleProps(request.body); if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.test.ts similarity index 83% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.test.ts index 85c324008856c..5f5e81a6c3960 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; import { getEmptyFindResult, resolveRuleMock, @@ -14,21 +14,22 @@ import { getDeleteRequestById, getEmptySavedObjectsResponse, getRuleMock, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { deleteRulesRoute } from './delete_rules_route'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { legacyMigrate } from '../../rules/utils'; +} from '../../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; +import { deleteRuleRoute } from './route'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +jest.mock('../../../logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual('../../../logic/rule_actions/legacy_action_migration'); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('delete_rules', () => { +describe('Delete rule route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); @@ -41,7 +42,7 @@ describe('delete_rules', () => { (legacyMigrate as jest.Mock).mockResolvedValue(getRuleMock(getQueryRuleParams())); - deleteRulesRoute(server.router); + deleteRuleRoute(server.router); }); describe('status codes with actionClient and alertClient', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts similarity index 65% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts index 2ad26472b699a..f5dfb61cd32ef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/delete_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts @@ -6,27 +6,29 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; -import { queryRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/query_rules_type_dependents'; -import type { QueryRulesSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/query_rules_schema'; -import { queryRulesSchema } from '../../../../../common/detection_engine/schemas/request/query_rules_schema'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { deleteRules } from '../../rules/delete_rules'; -import { getIdError, transform } from './utils'; -import { buildSiemResponse } from '../utils'; -import { readRules } from '../../rules/read_rules'; -import { legacyMigrate } from '../../rules/utils'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { + QueryRuleByIds, + validateQueryRuleByIds, +} from '../../../../../../../common/detection_engine/rule_management'; -export const deleteRulesRoute = (router: SecuritySolutionPluginRouter) => { +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import { buildSiemResponse } from '../../../../routes/utils'; + +import { deleteRules } from '../../../logic/crud/delete_rules'; +import { readRules } from '../../../logic/crud/read_rules'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { getIdError, transform } from '../../../utils/utils'; + +export const deleteRuleRoute = (router: SecuritySolutionPluginRouter) => { router.delete( { path: DETECTION_ENGINE_RULES_URL, validate: { - query: buildRouteValidation( - queryRulesSchema - ), + query: buildRouteValidation(QueryRuleByIds), }, options: { tags: ['access:securitySolution'], @@ -34,7 +36,7 @@ export const deleteRulesRoute = (router: SecuritySolutionPluginRouter) => { }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = queryRuleValidateTypeDependents(request.query); + const validationErrors = validateQueryRuleByIds(request.query); if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts similarity index 71% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts index 145ab6217d2ab..ec96f38f5f86e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/export_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/export_rules/route.ts @@ -7,22 +7,21 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { Logger } from '@kbn/core/server'; -import type { - ExportRulesQuerySchemaDecoded, - ExportRulesSchemaDecoded, -} from '../../../../../common/detection_engine/schemas/request/export_rules_schema'; + +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import type { ExportRulesRequestQueryDecoded } from '../../../../../../../common/detection_engine/rule_management'; import { - exportRulesQuerySchema, - exportRulesSchema, -} from '../../../../../common/detection_engine/schemas/request/export_rules_schema'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import type { ConfigType } from '../../../../config'; -import { getNonPackagedRulesCount } from '../../rules/get_existing_prepackaged_rules'; -import { getExportByObjectIds } from '../../rules/get_export_by_object_ids'; -import { getExportAll } from '../../rules/get_export_all'; -import { buildSiemResponse } from '../utils'; + ExportRulesRequestBody, + ExportRulesRequestQuery, +} from '../../../../../../../common/detection_engine/rule_management'; + +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import type { ConfigType } from '../../../../../../config'; +import { getNonPackagedRulesCount } from '../../../logic/search/get_existing_prepackaged_rules'; +import { getExportByObjectIds } from '../../../logic/export/get_export_by_object_ids'; +import { getExportAll } from '../../../logic/export/get_export_all'; +import { buildSiemResponse } from '../../../../routes/utils'; export const exportRulesRoute = ( router: SecuritySolutionPluginRouter, @@ -33,12 +32,10 @@ export const exportRulesRoute = ( { path: `${DETECTION_ENGINE_RULES_URL}/_export`, validate: { - query: buildRouteValidation( - exportRulesQuerySchema - ), - body: buildRouteValidation( - exportRulesSchema + query: buildRouteValidation( + ExportRulesRequestQuery ), + body: buildRouteValidation(ExportRulesRequestBody), }, options: { tags: ['access:securitySolution'], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.test.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.test.ts index b1f1ec8ead8ac..e34dff9733794 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.test.ts @@ -6,18 +6,18 @@ */ import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { DETECTION_ENGINE_RULES_URL_FIND } from '../../../../../common/constants'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { requestContextMock, requestMock, serverMock } from '../__mocks__'; +import { DETECTION_ENGINE_RULES_URL_FIND } from '../../../../../../../common/constants'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; +import { requestContextMock, requestMock, serverMock } from '../../../../routes/__mocks__'; import { getRuleMock, getFindRequest, getFindResultWithSingleHit, getEmptySavedObjectsResponse, -} from '../__mocks__/request_responses'; -import { findRulesRoute } from './find_rules_route'; +} from '../../../../routes/__mocks__/request_responses'; +import { findRulesRoute } from './route'; -describe('find_rules', () => { +describe('Find rules route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let logger: ReturnType; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts similarity index 70% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts index fa28a16e7bd4b..34117ca07f817 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/find_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/find_rules/route.ts @@ -5,28 +5,32 @@ * 2.0. */ -import { transformError } from '@kbn/securitysolution-es-utils'; import type { Logger } from '@kbn/core/server'; -import { findRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/find_rules_type_dependents'; -import type { FindRulesSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/find_rules_schema'; -import { findRulesSchema } from '../../../../../common/detection_engine/schemas/request/find_rules_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL_FIND } from '../../../../../common/constants'; -import { findRules } from '../../rules/find_rules'; -import { buildSiemResponse } from '../utils'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import { transformFindAlerts } from './utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; + +import { DETECTION_ENGINE_RULES_URL_FIND } from '../../../../../../../common/constants'; +import type { FindRulesRequestQueryDecoded } from '../../../../../../../common/detection_engine/rule_management'; +import { + FindRulesRequestQuery, + validateFindRulesRequestQuery, +} from '../../../../../../../common/detection_engine/rule_management'; + +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { findRules } from '../../../logic/search/find_rules'; +import { buildSiemResponse } from '../../../../routes/utils'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import { transformFindAlerts } from '../../../utils/utils'; // eslint-disable-next-line no-restricted-imports -import { legacyGetBulkRuleActionsSavedObject } from '../../rule_actions/legacy_get_bulk_rule_actions_saved_object'; +import { legacyGetBulkRuleActionsSavedObject } from '../../../../rule_actions_legacy'; export const findRulesRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { router.get( { path: DETECTION_ENGINE_RULES_URL_FIND, validate: { - query: buildRouteValidation( - findRulesSchema + query: buildRouteValidation( + FindRulesRequestQuery ), }, options: { @@ -36,7 +40,7 @@ export const findRulesRoute = (router: SecuritySolutionPluginRouter, logger: Log async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = findRuleValidateTypeDependents(request.query); + const validationErrors = validateFindRulesRequestQuery(request.query); if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.test.ts similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.test.ts index bf83471631a8c..3d466d2505074 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.test.ts @@ -5,7 +5,20 @@ * 2.0. */ -import { buildHapiStream } from '../__mocks__/utils'; +import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; + +import { + getImportRulesWithIdSchemaMock, + ruleIdsToNdJsonString, + rulesToNdJsonString, +} from '../../../../../../../common/detection_engine/rule_management/mocks'; + +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; + +import type { requestMock } from '../../../../routes/__mocks__'; +import { createMockConfig, requestContextMock, serverMock } from '../../../../routes/__mocks__'; +import { buildHapiStream } from '../../../../routes/__mocks__/utils'; import { getImportRulesRequest, getImportRulesRequestOverwriteTrue, @@ -13,24 +26,15 @@ import { getRuleMock, getFindResultWithSingleHit, getBasicEmptySearchResponse, -} from '../__mocks__/request_responses'; -import type { requestMock } from '../__mocks__'; -import { createMockConfig, requestContextMock, serverMock } from '../__mocks__'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { importRulesRoute } from './import_rules_route'; -import * as createRulesAndExceptionsStreamFromNdJson from '../../rules/create_rules_stream_from_ndjson'; -import { - getImportRulesWithIdSchemaMock, - ruleIdsToNdJsonString, - rulesToNdJsonString, -} from '../../../../../common/detection_engine/schemas/request/import_rules_schema.mock'; -import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +} from '../../../../routes/__mocks__/request_responses'; + +import * as createRulesAndExceptionsStreamFromNdJson from '../../../logic/import/create_rules_stream_from_ndjson'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; +import { importRulesRoute } from './route'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); +jest.mock('../../../../../machine_learning/authz'); -describe('import_rules_route', () => { +describe('Import rules route', () => { let config: ReturnType; let server: ReturnType; let request: ReturnType; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts similarity index 79% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts index 958993b34c03b..e306caac12194 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/import_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/import_rules/route.ts @@ -15,29 +15,29 @@ import { validate } from '@kbn/securitysolution-io-ts-utils'; import type { ImportQuerySchemaDecoded } from '@kbn/securitysolution-io-ts-types'; import { importQuerySchema } from '@kbn/securitysolution-io-ts-types'; -import type { ImportRulesSchema as ImportRulesResponseSchema } from '../../../../../common/detection_engine/schemas/response/import_rules_schema'; -import { importRulesSchema as importRulesResponseSchema } from '../../../../../common/detection_engine/schemas/response/import_rules_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import type { ConfigType } from '../../../../config'; -import type { SetupPlugins } from '../../../../plugin'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import type { ImportRuleResponse, BulkError } from '../utils'; -import { isBulkError, isImportRegular, buildSiemResponse } from '../utils'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import type { RuleToImport } from '../../../../../../../common/detection_engine/rule_management'; +import { ImportRulesResponse } from '../../../../../../../common/detection_engine/rule_management'; + +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import type { ConfigType } from '../../../../../../config'; +import type { SetupPlugins } from '../../../../../../plugin'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import type { ImportRuleResponse, BulkError } from '../../../../routes/utils'; +import { isBulkError, isImportRegular, buildSiemResponse } from '../../../../routes/utils'; import { getTupleDuplicateErrorsAndUniqueRules, getInvalidConnectors, migrateLegacyActionsIds, -} from './utils'; -import { createRulesAndExceptionsStreamFromNdJson } from '../../rules/create_rules_stream_from_ndjson'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { HapiReadableStream } from '../../rules/types'; -import type { RuleExceptionsPromiseFromStreams } from './utils/import_rules_utils'; -import { importRules as importRulesHelper } from './utils/import_rules_utils'; -import { getReferencedExceptionLists } from './utils/gather_referenced_exceptions'; -import { importRuleExceptions } from './utils/import_rule_exceptions'; -import type { ImportRulesSchema } from '../../../../../common/detection_engine/schemas/request/import_rules_schema'; +} from '../../../utils/utils'; +import { createRulesAndExceptionsStreamFromNdJson } from '../../../logic/import/create_rules_stream_from_ndjson'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import type { RuleExceptionsPromiseFromStreams } from '../../../logic/import/import_rules_utils'; +import { importRules as importRulesHelper } from '../../../logic/import/import_rules_utils'; +import { getReferencedExceptionLists } from '../../../logic/import/gather_referenced_exceptions'; +import { importRuleExceptions } from '../../../logic/import/import_rule_exceptions'; +import type { HapiReadableStream } from '../../../logic/import/hapi_readable_stream'; const CHUNK_PARSED_OBJECT_SIZE = 50; @@ -131,9 +131,7 @@ export const importRulesRoute = ( let parsedRules; let actionErrors: BulkError[] = []; - const actualRules = rules.filter( - (rule): rule is ImportRulesSchema => !(rule instanceof Error) - ); + const actualRules = rules.filter((rule): rule is RuleToImport => !(rule instanceof Error)); if (actualRules.some((rule) => rule.actions && rule.actions.length > 0)) { const [nonExistentActionErrors, uniqueParsedObjects] = await getInvalidConnectors( @@ -173,7 +171,7 @@ export const importRulesRoute = ( return false; } }); - const importRules: ImportRulesResponseSchema = { + const importRules: ImportRulesResponse = { success: errorsResp.length === 0, success_count: successes.length, rules_count: rules.length, @@ -183,7 +181,7 @@ export const importRulesRoute = ( exceptions_success_count: exceptionsSuccessCount, }; - const [validated, errors] = validate(importRules, importRulesResponseSchema); + const [validated, errors] = validate(importRules, ImportRulesResponse); if (errors != null) { return siemResponse.error({ statusCode: 500, body: errors }); } else { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.test.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.test.ts index 743fdefa7947f..07ae6a84df003 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.test.ts @@ -5,9 +5,13 @@ * 2.0. */ -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { getPatchRulesSchemaMock } from '../../../../../../../common/detection_engine/rule_management/mocks'; + +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; + +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; import { getEmptyFindResult, getRuleMock, @@ -15,24 +19,25 @@ import { getFindResultWithSingleHit, nonRuleFindResult, typicalMlRulePayload, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { patchRulesRoute } from './patch_rules_route'; -import { getPatchRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/patch_rules_schema.mock'; -import { getMlRuleParams, getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { legacyMigrate } from '../../rules/utils'; +} from '../../../../routes/__mocks__/request_responses'; + +import { getMlRuleParams, getQueryRuleParams } from '../../../../rule_schema/mocks'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; + +import { patchRuleRoute } from './route'; -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); +jest.mock('../../../../../machine_learning/authz'); -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +jest.mock('../../../logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual('../../../logic/rule_actions/legacy_action_migration'); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('patch_rules', () => { +describe('Patch rule route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -48,7 +53,7 @@ describe('patch_rules', () => { (legacyMigrate as jest.Mock).mockResolvedValue(getRuleMock(getQueryRuleParams())); - patchRulesRoute(server.router, ml); + patchRuleRoute(server.router, ml); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts similarity index 69% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts index aac618529c3bb..0e15e73b5e34d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/patch_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts @@ -6,23 +6,29 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; -import { patchRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/patch_rules_type_dependents'; -import { buildRouteValidationNonExact } from '../../../../utils/build_validation/route_validation'; -import { patchRulesSchema } from '../../../../../common/detection_engine/schemas/request/patch_rules_schema'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import type { SetupPlugins } from '../../../../plugin'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { patchRules } from '../../rules/patch_rules'; -import { buildSiemResponse } from '../utils'; -import { checkDefaultRuleExceptionListReferences } from './utils/check_for_default_rule_exception_list'; -import { getIdError } from './utils'; -import { transformValidate } from './validate'; -import { readRules } from '../../rules/read_rules'; -import { legacyMigrate } from '../../rules/utils'; -export const patchRulesRoute = (router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml']) => { +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { + PatchRuleRequestBody, + validatePatchRuleRequestBody, +} from '../../../../../../../common/detection_engine/rule_management'; + +import { buildRouteValidationNonExact } from '../../../../../../utils/build_validation/route_validation'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import type { SetupPlugins } from '../../../../../../plugin'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../../machine_learning/validation'; +import { buildSiemResponse } from '../../../../routes/utils'; + +import { readRules } from '../../../logic/crud/read_rules'; +import { patchRules } from '../../../logic/crud/patch_rules'; +import { checkDefaultRuleExceptionListReferences } from '../../../logic/exceptions/check_for_default_rule_exception_list'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { getIdError } from '../../../utils/utils'; +import { transformValidate } from '../../../utils/validate'; + +export const patchRuleRoute = (router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml']) => { router.patch( { path: DETECTION_ENGINE_RULES_URL, @@ -30,7 +36,7 @@ export const patchRulesRoute = (router: SecuritySolutionPluginRouter, ml: SetupP // Use non-exact validation because everything is optional in patch - since everything is optional, // io-ts can't find the right schema from the type specific union and the exact check breaks. // We do type specific validation after fetching the existing rule so we know the rule type. - body: buildRouteValidationNonExact(patchRulesSchema), + body: buildRouteValidationNonExact(PatchRuleRequestBody), }, options: { tags: ['access:securitySolution'], @@ -38,7 +44,7 @@ export const patchRulesRoute = (router: SecuritySolutionPluginRouter, ml: SetupP }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = patchRuleValidateTypeDependents(request.body); + const validationErrors = validatePatchRuleRequestBody(request.body); if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.test.ts similarity index 92% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.test.ts index 368a2b50cd962..573a85cc97b16 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.test.ts @@ -7,8 +7,8 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { readRulesRoute } from './read_rules_route'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { readRuleRoute } from './route'; import { getEmptyFindResult, getReadRequest, @@ -17,11 +17,11 @@ import { nonRuleFindResult, getEmptySavedObjectsResponse, resolveRuleMock, -} from '../__mocks__/request_responses'; -import { requestMock, requestContextMock, serverMock } from '../__mocks__'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +} from '../../../../routes/__mocks__/request_responses'; +import { requestMock, requestContextMock, serverMock } from '../../../../routes/__mocks__'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; -describe('read_rules', () => { +describe('Read rule route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let logger: ReturnType; @@ -41,7 +41,7 @@ describe('read_rules', () => { }), id: myFakeId, }); - readRulesRoute(server.router, logger); + readRuleRoute(server.router, logger); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts similarity index 65% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts index b19e94b6f0484..eaa58bf00a1be 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/read_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts @@ -5,29 +5,30 @@ * 2.0. */ -import { transformError } from '@kbn/securitysolution-es-utils'; import type { Logger } from '@kbn/core/server'; -import { queryRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/query_rules_type_dependents'; -import type { QueryRulesSchemaDecoded } from '../../../../../common/detection_engine/schemas/request/query_rules_schema'; -import { queryRulesSchema } from '../../../../../common/detection_engine/schemas/request/query_rules_schema'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { getIdError, transform } from './utils'; -import { buildSiemResponse } from '../utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; + +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { + QueryRuleByIds, + validateQueryRuleByIds, +} from '../../../../../../../common/detection_engine/rule_management'; + +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +import { buildSiemResponse } from '../../../../routes/utils'; +import { getIdError, transform } from '../../../utils/utils'; -import { readRules } from '../../rules/read_rules'; +import { readRules } from '../../../logic/crud/read_rules'; // eslint-disable-next-line no-restricted-imports -import { legacyGetRuleActionsSavedObject } from '../../rule_actions/legacy_get_rule_actions_saved_object'; +import { legacyGetRuleActionsSavedObject } from '../../../../rule_actions_legacy'; -export const readRulesRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { +export const readRuleRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { router.get( { path: DETECTION_ENGINE_RULES_URL, validate: { - query: buildRouteValidation( - queryRulesSchema - ), + query: buildRouteValidation(QueryRuleByIds), }, options: { tags: ['access:securitySolution'], @@ -35,7 +36,7 @@ export const readRulesRoute = (router: SecuritySolutionPluginRouter, logger: Log }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = queryRuleValidateTypeDependents(request.query); + const validationErrors = validateQueryRuleByIds(request.query); if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts similarity index 86% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts index ad7a7d1fe5365..4502e08fb950d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.test.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { mlServicesMock, mlAuthzMock as mockMlAuthzFactory } from '../../../machine_learning/mocks'; -import { buildMlAuthz } from '../../../machine_learning/authz'; +import { mlServicesMock } from '../../../../../machine_learning/mocks'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; import { getEmptyFindResult, getRuleMock, @@ -14,25 +14,26 @@ import { getFindResultWithSingleHit, nonRuleFindResult, typicalMlRulePayload, -} from '../__mocks__/request_responses'; -import { requestContextMock, serverMock, requestMock } from '../__mocks__'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import { updateRulesRoute } from './update_rules_route'; -import { getUpdateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import { legacyMigrate } from '../../rules/utils'; - -jest.mock('../../../machine_learning/authz', () => mockMlAuthzFactory.create()); - -jest.mock('../../rules/utils', () => { - const actual = jest.requireActual('../../rules/utils'); +} from '../../../../routes/__mocks__/request_responses'; +import { requestContextMock, serverMock, requestMock } from '../../../../routes/__mocks__'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { updateRuleRoute } from './route'; +import { getUpdateRulesSchemaMock } from '../../../../../../../common/detection_engine/rule_schema/mocks'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; + +jest.mock('../../../../../machine_learning/authz'); + +jest.mock('../../../logic/rule_actions/legacy_action_migration', () => { + const actual = jest.requireActual('../../../logic/rule_actions/legacy_action_migration'); return { ...actual, legacyMigrate: jest.fn(), }; }); -describe('update_rules', () => { +describe('Update rule route', () => { let server: ReturnType; let { clients, context } = requestContextMock.createTools(); let ml: ReturnType; @@ -49,7 +50,7 @@ describe('update_rules', () => { (legacyMigrate as jest.Mock).mockResolvedValue(getRuleMock(getQueryRuleParams())); - updateRulesRoute(server.router, ml); + updateRuleRoute(server.router, ml); }); describe('status codes', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts similarity index 64% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts index 8fa4f372fd597..8d24dd03d9d01 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/update_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts @@ -6,29 +6,31 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; -import { updateRulesSchema } from '../../../../../common/detection_engine/schemas/request'; -import { updateRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/update_rules_type_dependents'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants'; -import type { SetupPlugins } from '../../../../plugin'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { buildSiemResponse } from '../utils'; -import { getIdError } from './utils'; -import { transformValidate } from './validate'; -import { updateRules } from '../../rules/update_rules'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import { legacyMigrate } from '../../rules/utils'; -import { readRules } from '../../rules/read_rules'; -import { checkDefaultRuleExceptionListReferences } from './utils/check_for_default_rule_exception_list'; +import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constants'; +import { validateUpdateRuleProps } from '../../../../../../../common/detection_engine/rule_management'; +import { RuleUpdateProps } from '../../../../../../../common/detection_engine/rule_schema'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import type { SetupPlugins } from '../../../../../../plugin'; +import { buildMlAuthz } from '../../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../../machine_learning/validation'; +import { buildSiemResponse } from '../../../../routes/utils'; -export const updateRulesRoute = (router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml']) => { +import { getIdError } from '../../../utils/utils'; +import { transformValidate } from '../../../utils/validate'; +import { updateRules } from '../../../logic/crud/update_rules'; +import { buildRouteValidation } from '../../../../../../utils/build_validation/route_validation'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../../../logic/rule_actions/legacy_action_migration'; +import { readRules } from '../../../logic/crud/read_rules'; +import { checkDefaultRuleExceptionListReferences } from '../../../logic/exceptions/check_for_default_rule_exception_list'; + +export const updateRuleRoute = (router: SecuritySolutionPluginRouter, ml: SetupPlugins['ml']) => { router.put( { path: DETECTION_ENGINE_RULES_URL, validate: { - body: buildRouteValidation(updateRulesSchema), + body: buildRouteValidation(RuleUpdateProps), }, options: { tags: ['access:securitySolution'], @@ -36,7 +38,7 @@ export const updateRulesRoute = (router: SecuritySolutionPluginRouter, ml: Setup }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = updateRuleValidateTypeDependents(request.body); + const validationErrors = validateUpdateRuleProps(request.body); if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/read_tags.test.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/read_tags.test.ts index 2154e672e0089..ba9b00c01e3cf 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/read_tags.test.ts @@ -6,9 +6,12 @@ */ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { getRuleMock, getFindResultWithMultiHits } from '../routes/__mocks__/request_responses'; +import { + getRuleMock, + getFindResultWithMultiHits, +} from '../../../../routes/__mocks__/request_responses'; +import { getQueryRuleParams } from '../../../../rule_schema/mocks'; import { readTags, convertTagsToSet, convertToTags, isTags } from './read_tags'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; describe('read_tags', () => { afterEach(() => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/read_tags.ts similarity index 96% rename from x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/read_tags.ts index 72a886cd3e3a1..8819d95f366d8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/tags/read_tags.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/read_tags.ts @@ -7,7 +7,7 @@ import { has } from 'lodash/fp'; import type { RulesClient } from '@kbn/alerting-plugin/server'; -import { findRules } from '../rules/find_rules'; +import { findRules } from '../../../logic/search/find_rules'; export interface TagType { id: string; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts similarity index 81% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts index 508495cdeb9ef..c7cca7e443bd3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/tags/read_tags_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/tags/read_tags/route.ts @@ -6,11 +6,11 @@ */ import { transformError } from '@kbn/securitysolution-es-utils'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { DETECTION_ENGINE_TAGS_URL } from '../../../../../common/constants'; -import { buildSiemResponse } from '../utils'; +import type { SecuritySolutionPluginRouter } from '../../../../../../types'; +import { DETECTION_ENGINE_TAGS_URL } from '../../../../../../../common/constants'; +import { buildSiemResponse } from '../../../../routes/utils'; -import { readTags } from '../../tags/read_tags'; +import { readTags } from './read_tags'; export const readTagsRoute = (router: SecuritySolutionPluginRouter) => { router.get( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/index.ts new file mode 100644 index 0000000000000..f2a694c8df046 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/register_routes'; + +// TODO: https://github.com/elastic/kibana/pull/142950 +// eslint-disable-next-line no-restricted-imports +export { legacyMigrate } from './logic/rule_actions/legacy_action_migration'; + +// TODO: https://github.com/elastic/kibana/pull/142950 +// TODO: Revisit and consider moving to the rule_schema subdomain +export { + commonParamsCamelToSnake, + typeSpecificCamelToSnake, + convertCreateAPIToInternalSchema, +} from './normalization/rule_converters'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/actions/duplicate_rule.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/actions/duplicate_rule.test.ts index 29cc718379c96..8637236f654d2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/actions/duplicate_rule.test.ts @@ -7,7 +7,7 @@ import uuid from 'uuid'; import type { SanitizedRule } from '@kbn/alerting-plugin/common'; -import type { RuleParams } from '../schemas/rule_schemas'; +import type { RuleParams } from '../../../rule_schema'; import { duplicateRule } from './duplicate_rule'; jest.mock('uuid', () => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/actions/duplicate_rule.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/actions/duplicate_rule.ts index de077ef91b168..5f15a2ed81d1f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/duplicate_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/actions/duplicate_rule.ts @@ -6,13 +6,12 @@ */ import uuid from 'uuid'; - import { i18n } from '@kbn/i18n'; import { ruleTypeMappings } from '@kbn/securitysolution-rules'; - import type { SanitizedRule } from '@kbn/alerting-plugin/common'; -import { SERVER_APP_ID } from '../../../../common/constants'; -import type { InternalRuleCreate, RuleParams } from '../schemas/rule_schemas'; + +import { SERVER_APP_ID } from '../../../../../../common/constants'; +import type { InternalRuleCreate, RuleParams } from '../../../rule_schema'; const DUPLICATE_TITLE = i18n.translate( 'xpack.securitySolution.detectionEngine.rules.cloneRule.duplicateTitle', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/action_to_rules_client_operation.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.test.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/action_to_rules_client_operation.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.test.ts index 8627a5efeca2e..e48f0b4cbd3c4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/action_to_rules_client_operation.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.test.ts @@ -5,8 +5,7 @@ * 2.0. */ -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; - +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { bulkEditActionToRulesClientOperation } from './action_to_rules_client_operation'; describe('bulkEditActionToRulesClientOperation', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/action_to_rules_client_operation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/action_to_rules_client_operation.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts index 550f624ed9351..f767a5c246056 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/action_to_rules_client_operation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts @@ -7,11 +7,11 @@ import type { BulkEditOperation } from '@kbn/alerting-plugin/server'; -import type { BulkActionEditForRuleAttributes } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { assertUnreachable } from '../../../../../common/utility_types'; +import type { BulkActionEditForRuleAttributes } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { assertUnreachable } from '../../../../../../common/utility_types'; -import { transformToAlertThrottle, transformToNotifyWhen } from '../utils'; +import { transformToAlertThrottle, transformToNotifyWhen } from '../../normalization/rule_actions'; const getThrottleOperation = (throttle: string) => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts similarity index 80% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts index 75c7db48333c3..85610fcddb436 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_edit_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts @@ -7,24 +7,28 @@ import type { BulkEditError, RulesClient } from '@kbn/alerting-plugin/server'; import pMap from 'p-map'; -import type { - BulkActionEditPayload, - BulkActionEditPayloadRuleActions, -} from '../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { enrichFilterWithRuleTypeMapping } from './enrich_filter_with_rule_type_mappings'; -import type { MlAuthz } from '../../machine_learning/authz'; -import { ruleParamsModifier } from './bulk_actions/rule_params_modifier'; -import { splitBulkEditActions } from './bulk_actions/split_bulk_edit_actions'; -import { validateBulkEditRule } from './bulk_actions/validations'; -import { bulkEditActionToRulesClientOperation } from './bulk_actions/action_to_rules_client_operation'; -import type { RuleAlertType } from './types'; import { MAX_RULES_TO_UPDATE_IN_PARALLEL, NOTIFICATION_THROTTLE_NO_ACTIONS, -} from '../../../../common/constants'; -import { readRules } from './read_rules'; +} from '../../../../../../common/constants'; + +import type { + BulkActionEditPayload, + BulkActionEditPayloadRuleActions, +} from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; + +import type { MlAuthz } from '../../../../machine_learning/authz'; + +import { enrichFilterWithRuleTypeMapping } from '../search/enrich_filter_with_rule_type_mappings'; +import { readRules } from '../crud/read_rules'; +import type { RuleAlertType } from '../../../rule_schema'; + +import { ruleParamsModifier } from './rule_params_modifier'; +import { splitBulkEditActions } from './split_bulk_edit_actions'; +import { validateBulkEditRule } from './validations'; +import { bulkEditActionToRulesClientOperation } from './action_to_rules_client_operation'; export interface BulkEditRulesArguments { rulesClient: RulesClient; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/dry_run.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/dry_run.ts similarity index 93% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/dry_run.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/dry_run.ts index 608324e5bb280..fa05b1fc822d2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/dry_run.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/dry_run.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { BulkActionsDryRunErrCode } from '../../../../../common/constants'; +import type { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; /** * Error instance that has properties: errorCode & statusCode to use within run_dry diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/rule_params_modifier.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/rule_params_modifier.test.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/rule_params_modifier.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/rule_params_modifier.test.ts index 5c194cc6c4614..b7763f20eec9c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/rule_params_modifier.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/rule_params_modifier.test.ts @@ -6,8 +6,8 @@ */ import { addItemsToArray, deleteItemsFromArray, ruleParamsModifier } from './rule_params_modifier'; -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { RuleAlertType } from '../types'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { RuleAlertType } from '../../../rule_schema'; describe('addItemsToArray', () => { test('should add single item to array', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/rule_params_modifier.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/rule_params_modifier.ts similarity index 92% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/rule_params_modifier.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/rule_params_modifier.ts index 6831668258554..9f5f252b9fd86 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/rule_params_modifier.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/rule_params_modifier.ts @@ -9,10 +9,10 @@ import moment from 'moment'; import { parseInterval } from '@kbn/data-plugin/common/search/aggs/utils/date_interval_utils'; -import type { RuleAlertType } from '../types'; -import type { BulkActionEditForRuleParams } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { invariant } from '../../../../../common/utils/invariant'; +import type { RuleAlertType } from '../../../rule_schema'; +import type { BulkActionEditForRuleParams } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { invariant } from '../../../../../../common/utils/invariant'; export const addItemsToArray = (arr: T[], items: T[]): T[] => Array.from(new Set([...arr, ...items])); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/split_bulk_edit_actions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/split_bulk_edit_actions.test.ts similarity index 87% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/split_bulk_edit_actions.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/split_bulk_edit_actions.test.ts index 46205c060be78..33f1e0e4ad15e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/split_bulk_edit_actions.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/split_bulk_edit_actions.test.ts @@ -5,8 +5,8 @@ * 2.0. */ -import type { BulkActionEditPayload } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import type { BulkActionEditPayload } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { splitBulkEditActions } from './split_bulk_edit_actions'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/split_bulk_edit_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/split_bulk_edit_actions.ts similarity index 85% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/split_bulk_edit_actions.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/split_bulk_edit_actions.ts index c752ca6653ad6..b6441d46c5ebd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/split_bulk_edit_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/split_bulk_edit_actions.ts @@ -5,12 +5,12 @@ * 2.0. */ -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import type { BulkActionEditPayload, BulkActionEditForRuleAttributes, BulkActionEditForRuleParams, -} from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +} from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; /** * Split bulk edit actions in 2 chunks: actions applied to params and diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/utils.ts similarity index 84% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/utils.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/utils.ts index 91cfe9544d550..993750cfc0964 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/utils.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; /** * helper utility that defines whether bulk edit action is related to index patterns, i.e. one of: diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/validations.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/validations.ts similarity index 84% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/validations.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/validations.ts index 5252fd1982ff3..ce9b084679a5b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/bulk_actions/validations.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/validations.ts @@ -6,16 +6,16 @@ */ import type { Type as RuleType } from '@kbn/securitysolution-io-ts-alerting-types'; -import { invariant } from '../../../../../common/utils/invariant'; -import { isMlRule } from '../../../../../common/machine_learning/helpers'; -import { BulkActionsDryRunErrCode } from '../../../../../common/constants'; -import type { BulkActionEditPayload } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import { BulkActionEditType } from '../../../../../common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { RuleAlertType } from '../types'; +import { invariant } from '../../../../../../common/utils/invariant'; +import { isMlRule } from '../../../../../../common/machine_learning/helpers'; +import { BulkActionsDryRunErrCode } from '../../../../../../common/constants'; +import type { BulkActionEditPayload } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; +import type { RuleAlertType } from '../../../rule_schema'; import { isIndexPatternsBulkEditAction } from './utils'; import { throwDryRunError } from './dry_run'; -import type { MlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; +import type { MlAuthz } from '../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../machine_learning/validation'; interface BulkActionsValidationArgs { rule: RuleAlertType; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/create_rules.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/create_rules.test.ts index fb62434563183..8b59effd9c910 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/create_rules.test.ts @@ -7,11 +7,11 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { createRules } from './create_rules'; -import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../common/constants'; +import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../../common/constants'; import { getCreateMachineLearningRulesSchemaMock, getCreateThreatMatchRulesSchemaMock, -} from '../../../../common/detection_engine/schemas/request/rule_schemas.mock'; +} from '../../../../../../common/detection_engine/rule_schema/mocks'; describe('createRules', () => { it('calls the rulesClient with legacy ML params', async () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/create_rules.ts similarity index 60% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/create_rules.ts index 5405fed52b79b..f621542fe433f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/create_rules.ts @@ -6,10 +6,20 @@ */ import type { SanitizedRule } from '@kbn/alerting-plugin/common'; -import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../common/constants'; -import type { CreateRulesOptions } from './types'; -import { convertCreateAPIToInternalSchema } from '../schemas/rule_converters'; -import type { RuleParams } from '../schemas/rule_schemas'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; + +import type { RuleCreateProps } from '../../../../../../common/detection_engine/rule_schema'; +import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../../common/constants'; +import { convertCreateAPIToInternalSchema } from '../../normalization/rule_converters'; +import type { RuleParams } from '../../../rule_schema'; + +export interface CreateRulesOptions { + rulesClient: RulesClient; + params: T; + id?: string; + immutable?: boolean; + defaultEnabled?: boolean; +} export const createRules = async ({ rulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/delete_rules.test.ts similarity index 89% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/delete_rules.test.ts index 0c7edae7022c7..e7176b8d51af0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/delete_rules.test.ts @@ -6,9 +6,9 @@ */ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { ruleExecutionLogMock } from '../rule_monitoring/mocks'; +import { ruleExecutionLogMock } from '../../../rule_monitoring/mocks'; +import type { DeleteRuleOptions } from './delete_rules'; import { deleteRules } from './delete_rules'; -import type { DeleteRuleOptions } from './types'; describe('deleteRules', () => { let rulesClient: ReturnType; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/delete_rules.ts similarity index 55% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/delete_rules.ts index e0ab62df17c37..a1190d8827c0d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/delete_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/delete_rules.ts @@ -5,7 +5,15 @@ * 2.0. */ -import type { DeleteRuleOptions } from './types'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { RuleObjectId } from '../../../../../../common/detection_engine/rule_schema'; +import type { IRuleExecutionLogForRoutes } from '../../../rule_monitoring'; + +export interface DeleteRuleOptions { + ruleId: RuleObjectId; + rulesClient: RulesClient; + ruleExecutionLog: IRuleExecutionLogForRoutes; +} export const deleteRules = async ({ ruleId, rulesClient, ruleExecutionLog }: DeleteRuleOptions) => { await rulesClient.delete({ id: ruleId }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/patch_rules.test.ts similarity index 96% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/patch_rules.test.ts index e99f7f85df156..cfb051273255a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/patch_rules.test.ts @@ -8,12 +8,12 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/rules_client.mock'; import { patchRules } from './patch_rules'; -import { getRuleMock } from '../routes/__mocks__/request_responses'; -import { getMlRuleParams, getQueryRuleParams } from '../schemas/rule_schemas.mock'; +import { getRuleMock } from '../../../routes/__mocks__/request_responses'; +import { getMlRuleParams, getQueryRuleParams } from '../../../rule_schema/mocks'; import { getCreateMachineLearningRulesSchemaMock, getCreateRulesSchemaMock, -} from '../../../../common/detection_engine/schemas/request/rule_schemas.mock'; +} from '../../../../../../common/detection_engine/rule_schema/mocks'; describe('patchRules', () => { it('should call rulesClient.disable if the rule was enabled and enabled is false', async () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/patch_rules.ts similarity index 70% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/patch_rules.ts index 0a8342ae265a0..656366ec9f92b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/patch_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/patch_rules.ts @@ -5,11 +5,18 @@ * 2.0. */ -import type { PartialRule } from '@kbn/alerting-plugin/server'; -import type { RuleParams } from '../schemas/rule_schemas'; -import type { PatchRulesOptions } from './types'; -import { maybeMute } from './utils'; -import { convertPatchAPIToInternalSchema } from '../schemas/rule_converters'; +import type { PartialRule, RulesClient } from '@kbn/alerting-plugin/server'; + +import type { PatchRuleRequestBody } from '../../../../../../common/detection_engine/rule_management'; +import type { RuleAlertType, RuleParams } from '../../../rule_schema'; +import { convertPatchAPIToInternalSchema } from '../../normalization/rule_converters'; +import { maybeMute } from '../rule_actions/muting'; + +export interface PatchRulesOptions { + rulesClient: RulesClient; + nextParams: PatchRuleRequestBody; + existingRule: RuleAlertType | null | undefined; +} export const patchRules = async ({ rulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/read_rules.test.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/read_rules.test.ts index dd0d1ff7090c7..fa6ccba511833 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/read_rules.test.ts @@ -11,8 +11,8 @@ import { resolveRuleMock, getRuleMock, getFindResultWithSingleHit, -} from '../routes/__mocks__/request_responses'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; +} from '../../../routes/__mocks__/request_responses'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; export class TestError extends Error { constructor() { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/read_rules.ts similarity index 80% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/read_rules.ts index 1e853084a3635..76969b31aab66 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/read_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/read_rules.ts @@ -6,11 +6,22 @@ */ import type { ResolvedSanitizedRule, SanitizedRule } from '@kbn/alerting-plugin/common'; -import { withSecuritySpan } from '../../../utils/with_security_span'; -import type { RuleParams } from '../schemas/rule_schemas'; -import { findRules } from './find_rules'; -import type { ReadRuleOptions } from './types'; -import { isAlertType } from './types'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; + +import type { + RuleObjectId, + RuleSignatureId, +} from '../../../../../../common/detection_engine/rule_schema'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import type { RuleParams } from '../../../rule_schema'; +import { isAlertType } from '../../../rule_schema'; +import { findRules } from '../search/find_rules'; + +export interface ReadRuleOptions { + rulesClient: RulesClient; + id: RuleObjectId | undefined; + ruleId: RuleSignatureId | undefined; +} /** * This reads the rules through a cascade try of what is fastest to what is slowest. diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.mock.ts similarity index 78% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.mock.ts index bdaf757cb086e..3e3da2e6f5530 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.mock.ts @@ -9,9 +9,9 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { getUpdateMachineLearningSchemaMock, getUpdateRulesSchemaMock, -} from '../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import { getRuleMock } from '../routes/__mocks__/request_responses'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; +} from '../../../../../../common/detection_engine/rule_schema/mocks'; +import { getRuleMock } from '../../../routes/__mocks__/request_responses'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; export const getUpdateRulesOptionsMock = () => ({ rulesClient: rulesClientMock.create(), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.test.ts similarity index 93% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.test.ts index 453a305d2e1ec..6abba4dba0ab9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.test.ts @@ -5,11 +5,11 @@ * 2.0. */ -import { getRuleMock, resolveRuleMock } from '../routes/__mocks__/request_responses'; +import type { RulesClientMock } from '@kbn/alerting-plugin/server/rules_client.mock'; +import { getRuleMock, resolveRuleMock } from '../../../routes/__mocks__/request_responses'; +import { getMlRuleParams, getQueryRuleParams } from '../../../rule_schema/mocks'; import { updateRules } from './update_rules'; import { getUpdateRulesOptionsMock, getUpdateMlRulesOptionsMock } from './update_rules.mock'; -import type { RulesClientMock } from '@kbn/alerting-plugin/server/rules_client.mock'; -import { getMlRuleParams, getQueryRuleParams } from '../schemas/rule_schemas.mock'; // Failing with rule registry enabled describe('updateRules', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.ts similarity index 80% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.ts index c75e7534417e9..625204efbe4f6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/update_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/crud/update_rules.ts @@ -6,14 +6,21 @@ */ /* eslint-disable complexity */ -import type { PartialRule } from '@kbn/alerting-plugin/server'; -import { DEFAULT_MAX_SIGNALS } from '../../../../common/constants'; -import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions'; +import type { PartialRule, RulesClient } from '@kbn/alerting-plugin/server'; +import { DEFAULT_MAX_SIGNALS } from '../../../../../../common/constants'; +import type { RuleUpdateProps } from '../../../../../../common/detection_engine/rule_schema'; +import { transformRuleToAlertAction } from '../../../../../../common/detection_engine/transform_actions'; -import type { UpdateRulesOptions } from './types'; -import { typeSpecificSnakeToCamel } from '../schemas/rule_converters'; -import type { InternalRuleUpdate, RuleParams } from '../schemas/rule_schemas'; -import { maybeMute, transformToAlertThrottle, transformToNotifyWhen } from './utils'; +import type { InternalRuleUpdate, RuleParams, RuleAlertType } from '../../../rule_schema'; +import { transformToAlertThrottle, transformToNotifyWhen } from '../../normalization/rule_actions'; +import { typeSpecificSnakeToCamel } from '../../normalization/rule_converters'; +import { maybeMute } from '../rule_actions/muting'; + +export interface UpdateRulesOptions { + rulesClient: RulesClient; + existingRule: RuleAlertType | null | undefined; + ruleUpdate: RuleUpdateProps; +} export const updateRules = async ({ rulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_for_default_rule_exception_list.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/exceptions/check_for_default_rule_exception_list.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_for_default_rule_exception_list.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/exceptions/check_for_default_rule_exception_list.test.ts index b95007d834b09..222badf14dfa6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_for_default_rule_exception_list.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/exceptions/check_for_default_rule_exception_list.test.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { checkDefaultRuleExceptionListReferences } from './check_for_default_rule_exception_list'; import type { ListArray } from '@kbn/securitysolution-io-ts-list-types'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; +import { checkDefaultRuleExceptionListReferences } from './check_for_default_rule_exception_list'; describe('checkDefaultRuleExceptionListReferences', () => { it('returns undefined if "exceptionLists" is undefined', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_for_default_rule_exception_list.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/exceptions/check_for_default_rule_exception_list.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_for_default_rule_exception_list.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/exceptions/check_for_default_rule_exception_list.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts index 25818c30f387b..b7395236a2152 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.test.ts @@ -5,25 +5,25 @@ * 2.0. */ -import type { FindHit } from '../routes/__mocks__/request_responses'; +import type { FindHit } from '../../../routes/__mocks__/request_responses'; import { getRuleMock, getFindResultWithSingleHit, getEmptySavedObjectsResponse, -} from '../routes/__mocks__/request_responses'; +} from '../../../routes/__mocks__/request_responses'; import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { getExportAll } from './get_export_all'; -import { getListArrayMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; -import { getThreatMock } from '../../../../common/detection_engine/schemas/types/threat.mock'; +import { getListArrayMock } from '../../../../../../common/detection_engine/schemas/types/lists.mock'; +import { getThreatMock } from '../../../../../../common/detection_engine/schemas/types/threat.mock'; import { getOutputDetailsSampleWithExceptions, getSampleDetailsAsNdjson, -} from '../../../../common/detection_engine/schemas/response/export_rules_details_schema.mock'; +} from '../../../../../../common/detection_engine/rule_management/mocks'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; import { getExceptionListClientMock } from '@kbn/lists-plugin/server/services/exception_lists/exception_list_client.mock'; import type { loggingSystemMock } from '@kbn/core/server/mocks'; -import { requestContextMock } from '../routes/__mocks__/request_context'; +import { requestContextMock } from '../../../routes/__mocks__/request_context'; const exceptionsClient = getExceptionListClientMock(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.ts similarity index 87% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.ts index 60d75fdd64709..058559de7db59 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_all.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_all.ts @@ -10,13 +10,13 @@ import { transformDataToNdjson } from '@kbn/securitysolution-utils'; import type { Logger } from '@kbn/core/server'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; import type { RulesClient, RuleExecutorServices } from '@kbn/alerting-plugin/server'; -import { getNonPackagedRules } from './get_existing_prepackaged_rules'; +import { getNonPackagedRules } from '../search/get_existing_prepackaged_rules'; import { getExportDetailsNdjson } from './get_export_details_ndjson'; -import { transformAlertsToRules } from '../routes/rules/utils'; +import { transformAlertsToRules } from '../../utils/utils'; import { getRuleExceptionsForExport } from './get_export_rule_exceptions'; // eslint-disable-next-line no-restricted-imports -import { legacyGetBulkRuleActionsSavedObject } from '../rule_actions/legacy_get_bulk_rule_actions_saved_object'; +import { legacyGetBulkRuleActionsSavedObject } from '../../../rule_actions_legacy'; export const getExportAll = async ( rulesClient: RulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts index b890315bf1977..0242f17509a99 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.test.ts @@ -7,25 +7,25 @@ import type { RulesErrors } from './get_export_by_object_ids'; import { getExportByObjectIds, getRulesFromObjects } from './get_export_by_object_ids'; -import type { FindHit } from '../routes/__mocks__/request_responses'; +import type { FindHit } from '../../../routes/__mocks__/request_responses'; import { getRuleMock, getFindResultWithSingleHit, getEmptySavedObjectsResponse, -} from '../routes/__mocks__/request_responses'; +} from '../../../routes/__mocks__/request_responses'; import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; -import { getListArrayMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; -import { getThreatMock } from '../../../../common/detection_engine/schemas/types/threat.mock'; +import { getListArrayMock } from '../../../../../../common/detection_engine/schemas/types/lists.mock'; +import { getThreatMock } from '../../../../../../common/detection_engine/schemas/types/threat.mock'; import { getSampleDetailsAsNdjson, getOutputDetailsSampleWithExceptions, -} from '../../../../common/detection_engine/schemas/response/export_rules_details_schema.mock'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; +} from '../../../../../../common/detection_engine/rule_management/mocks'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; import { getExceptionListClientMock } from '@kbn/lists-plugin/server/services/exception_lists/exception_list_client.mock'; const exceptionsClient = getExceptionListClientMock(); import type { loggingSystemMock } from '@kbn/core/server/mocks'; -import { requestContextMock } from '../routes/__mocks__/request_context'; +import { requestContextMock } from '../../../routes/__mocks__/request_context'; describe('get_export_by_object_ids', () => { let logger: ReturnType; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.ts index e044c8fdfd1ca..67da643d503e4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_by_object_ids.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_by_object_ids.ts @@ -14,18 +14,18 @@ import type { RulesClient, RuleExecutorServices } from '@kbn/alerting-plugin/ser import { getExportDetailsNdjson } from './get_export_details_ndjson'; -import { isAlertType } from './types'; -import { findRules } from './find_rules'; +import { isAlertType } from '../../../rule_schema'; +import { findRules } from '../search/find_rules'; import { getRuleExceptionsForExport } from './get_export_rule_exceptions'; // eslint-disable-next-line no-restricted-imports -import { legacyGetBulkRuleActionsSavedObject } from '../rule_actions/legacy_get_bulk_rule_actions_saved_object'; -import { internalRuleToAPIResponse } from '../schemas/rule_converters'; -import type { FullResponseSchema } from '../../../../common/detection_engine/schemas/request'; +import { legacyGetBulkRuleActionsSavedObject } from '../../../rule_actions_legacy'; +import { internalRuleToAPIResponse } from '../../normalization/rule_converters'; +import type { RuleResponse } from '../../../../../../common/detection_engine/rule_schema'; interface ExportSuccessRule { statusCode: 200; - rule: FullResponseSchema; + rule: RuleResponse; } interface ExportFailedRule { @@ -36,7 +36,7 @@ interface ExportFailedRule { export interface RulesErrors { exportedCount: number; missingRules: Array<{ rule_id: string }>; - rules: FullResponseSchema[]; + rules: RuleResponse[]; } export const getExportByObjectIds = async ( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_details_ndjson.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_details_ndjson.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_details_ndjson.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_details_ndjson.test.ts index e58d1b5088fce..b380fc804233b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_details_ndjson.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_details_ndjson.test.ts @@ -5,8 +5,8 @@ * 2.0. */ +import { getRulesSchemaMock } from '../../../../../../common/detection_engine/rule_schema/mocks'; import { getExportDetailsNdjson } from './get_export_details_ndjson'; -import { getRulesSchemaMock } from '../../../../common/detection_engine/schemas/response/rules_schema.mocks'; describe('getExportDetailsNdjson', () => { test('it ends with a new line character', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_details_ndjson.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_details_ndjson.ts similarity index 79% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_details_ndjson.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_details_ndjson.ts index 204d78f5fe7d2..465c4b53b1e51 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_details_ndjson.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_details_ndjson.ts @@ -6,12 +6,11 @@ */ import type { ExportExceptionDetails } from '@kbn/securitysolution-io-ts-list-types'; -import type { FullResponseSchema } from '../../../../common/detection_engine/schemas/request'; - -import type { ExportRulesDetails } from '../../../../common/detection_engine/schemas/response/export_rules_details_schema'; +import type { ExportRulesDetails } from '../../../../../../common/detection_engine/rule_management'; +import type { RuleResponse } from '../../../../../../common/detection_engine/rule_schema'; export const getExportDetailsNdjson = ( - rules: FullResponseSchema[], + rules: RuleResponse[], missingRules: Array<{ rule_id: string }> = [], exceptionDetails?: ExportExceptionDetails ): string => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_rule_exceptions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_rule_exceptions.test.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_rule_exceptions.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_rule_exceptions.test.ts index 79507a73147a9..07360aeda2986 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_rule_exceptions.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_rule_exceptions.test.ts @@ -11,12 +11,12 @@ import { getExceptionListClientMock } from '@kbn/lists-plugin/server/services/ex import { getDetectionsExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; import { getExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_item_schema.mock'; +import { getListMock } from '../../../../../../common/detection_engine/schemas/types/lists.mock'; import { getRuleExceptionsForExport, getExportableExceptions, getDefaultExportDetails, } from './get_export_rule_exceptions'; -import { getListMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; describe('get_export_rule_exceptions', () => { describe('getRuleExceptionsForExport', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_rule_exceptions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_rule_exceptions.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_export_rule_exceptions.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/export/get_export_rule_exceptions.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_rule_exception_references.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/check_rule_exception_references.test.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_rule_exception_references.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/check_rule_exception_references.test.ts index d1fb4881ae9a8..fdee52eac1a24 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_rule_exception_references.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/check_rule_exception_references.test.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { getImportRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/request/import_rules_schema.mock'; -import { checkRuleExceptionReferences } from './check_rule_exception_references'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; +import { getImportRulesSchemaMock } from '../../../../../../common/detection_engine/rule_management/mocks'; +import { checkRuleExceptionReferences } from './check_rule_exception_references'; describe('checkRuleExceptionReferences', () => { it('returns empty array if rule has no exception list references', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_rule_exception_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/check_rule_exception_references.ts similarity index 89% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_rule_exception_references.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/check_rule_exception_references.ts index a92d7e4ec1723..23494c3fc23dd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/check_rule_exception_references.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/check_rule_exception_references.ts @@ -6,9 +6,9 @@ */ import type { ListArray, ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; -import type { ImportRulesSchema } from '../../../../../../common/detection_engine/schemas/request/import_rules_schema'; -import type { BulkError } from '../../utils'; -import { createBulkErrorObject } from '../../utils'; +import type { RuleToImport } from '../../../../../../common/detection_engine/rule_management'; +import type { BulkError } from '../../../routes/utils'; +import { createBulkErrorObject } from '../../../routes/utils'; /** * Helper to check if all the exception lists referenced on a @@ -25,7 +25,7 @@ export const checkRuleExceptionReferences = ({ rule, existingLists, }: { - rule: ImportRulesSchema; + rule: RuleToImport; existingLists: Record; }): [BulkError[], ListArray] => { let ruleExceptions: ListArray = []; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/create_rules_stream_from_ndjson.test.ts similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/create_rules_stream_from_ndjson.test.ts index 4b3483229af89..47a4a4832b034 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/create_rules_stream_from_ndjson.test.ts @@ -9,14 +9,15 @@ import { Readable } from 'stream'; import { createPromiseFromStreams } from '@kbn/utils'; import { createRulesAndExceptionsStreamFromNdJson } from './create_rules_stream_from_ndjson'; import { BadRequestError } from '@kbn/securitysolution-es-utils'; -import type { ImportRulesSchema } from '../../../../common/detection_engine/schemas/request/import_rules_schema'; + +import type { RuleToImport } from '../../../../../../common/detection_engine/rule_management'; import { getOutputDetailsSample, getSampleDetailsAsNdjson, -} from '../../../../common/detection_engine/schemas/response/export_rules_details_schema.mock'; -import type { RuleExceptionsPromiseFromStreams } from '../routes/rules/utils/import_rules_utils'; +} from '../../../../../../common/detection_engine/rule_management/mocks'; +import type { RuleExceptionsPromiseFromStreams } from './import_rules_utils'; -export const getOutputSample = (): Partial => ({ +export const getOutputSample = (): Partial => ({ rule_id: 'rule-1', output_index: '.siem-signals', risk_score: 50, @@ -30,7 +31,7 @@ export const getOutputSample = (): Partial => ({ type: 'query', }); -export const getSampleAsNdjson = (sample: Partial): string => { +export const getSampleAsNdjson = (sample: Partial): string => { return `${JSON.stringify(sample)}\n`; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/create_rules_stream_from_ndjson.ts similarity index 74% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/create_rules_stream_from_ndjson.ts index 486b8b531a3fd..e325496225d9f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/create_rules_stream_from_ndjson.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/create_rules_stream_from_ndjson.ts @@ -5,10 +5,11 @@ * 2.0. */ -import type { Transform } from 'stream'; -import type * as t from 'io-ts'; +import { has } from 'lodash/fp'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; +import type * as t from 'io-ts'; +import type { Transform } from 'stream'; import { createSplitStream, createMapStream, @@ -16,21 +17,22 @@ import { createReduceStream, } from '@kbn/utils'; -import { exactCheck, formatErrors } from '@kbn/securitysolution-io-ts-utils'; import { BadRequestError } from '@kbn/securitysolution-es-utils'; +import { exactCheck, formatErrors } from '@kbn/securitysolution-io-ts-utils'; import type { ImportExceptionListItemSchema, ImportExceptionsListSchema, } from '@kbn/securitysolution-io-ts-list-types'; -import { has } from 'lodash/fp'; -import { importRuleValidateTypeDependents } from '../../../../common/detection_engine/schemas/request/import_rules_type_dependents'; -import type { ImportRulesSchema } from '../../../../common/detection_engine/schemas/request/import_rules_schema'; -import { importRulesSchema } from '../../../../common/detection_engine/schemas/request/import_rules_schema'; + +import { + RuleToImport, + validateRuleToImport, +} from '../../../../../../common/detection_engine/rule_management'; import { parseNdjsonStrings, createRulesLimitStream, filterExportedCounts, -} from '../../../utils/read_stream/create_stream_from_ndjson'; +} from '../../../../../utils/read_stream/create_stream_from_ndjson'; /** * Validates exception lists and items schemas @@ -38,25 +40,23 @@ import { export const validateRulesStream = (): Transform => { return createMapStream<{ exceptions: Array; - rules: Array; + rules: Array; }>((items) => ({ exceptions: items.exceptions, rules: validateRules(items.rules), })); }; -export const validateRules = ( - rules: Array -): Array => { - return rules.map((obj: ImportRulesSchema | Error) => { +export const validateRules = (rules: Array): Array => { + return rules.map((obj: RuleToImport | Error) => { if (!(obj instanceof Error)) { - const decoded = importRulesSchema.decode(obj); + const decoded = RuleToImport.decode(obj); const checked = exactCheck(obj, decoded); - const onLeft = (errors: t.Errors): BadRequestError | ImportRulesSchema => { + const onLeft = (errors: t.Errors): BadRequestError | RuleToImport => { return new BadRequestError(formatErrors(errors).join()); }; - const onRight = (schema: ImportRulesSchema): BadRequestError | ImportRulesSchema => { - const validationErrors = importRuleValidateTypeDependents(schema); + const onRight = (schema: RuleToImport): BadRequestError | RuleToImport => { + const validationErrors = validateRuleToImport(schema); if (validationErrors.length) { return new BadRequestError(validationErrors.join()); } else { @@ -79,7 +79,7 @@ export const validateRules = ( export const sortImports = (): Transform => { return createReduceStream<{ exceptions: Array; - rules: Array; + rules: Array; }>( (acc, importItem) => { if (has('list_id', importItem) || has('item_id', importItem) || has('entries', importItem)) { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/gather_referenced_exceptions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/gather_referenced_exceptions.test.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/gather_referenced_exceptions.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/gather_referenced_exceptions.test.ts index 62c591abc5e9d..797c45ea45fa2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/gather_referenced_exceptions.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/gather_referenced_exceptions.test.ts @@ -6,12 +6,11 @@ */ import type { SavedObjectsClientContract } from '@kbn/core/server'; - import { savedObjectsClientMock } from '@kbn/core/server/mocks'; import { findExceptionList } from '@kbn/lists-plugin/server/services/exception_lists/find_exception_list'; import { getExceptionListSchemaMock } from '@kbn/lists-plugin/common/schemas/response/exception_list_schema.mock'; +import { getImportRulesSchemaMock } from '../../../../../../common/detection_engine/rule_management/mocks'; import { getReferencedExceptionLists } from './gather_referenced_exceptions'; -import { getImportRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/request/import_rules_schema.mock'; jest.mock('@kbn/lists-plugin/server/services/exception_lists/find_exception_list'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/gather_referenced_exceptions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/gather_referenced_exceptions.ts similarity index 92% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/gather_referenced_exceptions.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/gather_referenced_exceptions.ts index ce6ab5c84678f..cbf6050b10b1c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/gather_referenced_exceptions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/gather_referenced_exceptions.ts @@ -8,7 +8,7 @@ import type { ExceptionListSchema, ListArray } from '@kbn/securitysolution-io-ts import type { SavedObjectsClientContract } from '@kbn/core/server'; import type { ExceptionListQueryInfo } from '@kbn/lists-plugin/server/services/exception_lists/utils/import/find_all_exception_list_types'; import { getAllListTypes } from '@kbn/lists-plugin/server/services/exception_lists/utils/import/find_all_exception_list_types'; -import type { ImportRulesSchema } from '../../../../../../common/detection_engine/schemas/request/import_rules_schema'; +import type { RuleToImport } from '../../../../../../common/detection_engine/rule_management'; /** * Helper that takes rules, goes through their referenced exception lists and @@ -21,7 +21,7 @@ export const getReferencedExceptionLists = async ({ rules, savedObjectsClient, }: { - rules: Array; + rules: Array; savedObjectsClient: SavedObjectsClientContract; }): Promise> => { const [lists] = rules.reduce((acc, rule) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/hapi_readable_stream.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/hapi_readable_stream.ts new file mode 100644 index 0000000000000..420d264a617ac --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/hapi_readable_stream.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Readable } from 'stream'; + +export interface HapiReadableStream extends Readable { + hapi: { + filename: string; + }; +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rule_exceptions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rule_exceptions.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rule_exceptions.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rule_exceptions.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rule_exceptions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rule_exceptions.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rule_exceptions.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rule_exceptions.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.test.ts index c98bac15d457c..2de1816e4541f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.test.ts @@ -5,20 +5,22 @@ * 2.0. */ -import { requestContextMock } from '../../__mocks__'; -import { importRules } from './import_rules_utils'; +import { getImportRulesSchemaMock } from '../../../../../../common/detection_engine/rule_management/mocks'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; + +import { requestContextMock } from '../../../routes/__mocks__'; import { getRuleMock, getEmptyFindResult, getFindResultWithSingleHit, -} from '../../__mocks__/request_responses'; -import { getQueryRuleParams } from '../../../schemas/rule_schemas.mock'; -import { getImportRulesSchemaMock } from '../../../../../../common/detection_engine/schemas/request/import_rules_schema.mock'; -import { createRules } from '../../../rules/create_rules'; -import { patchRules } from '../../../rules/patch_rules'; +} from '../../../routes/__mocks__/request_responses'; + +import { createRules } from '../crud/create_rules'; +import { patchRules } from '../crud/patch_rules'; +import { importRules } from './import_rules_utils'; -jest.mock('../../../rules/create_rules'); -jest.mock('../../../rules/patch_rules'); +jest.mock('../crud/create_rules'); +jest.mock('../crud/patch_rules'); describe('importRules', () => { const mlAuthz = { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts index a623f3887276a..694bc916fefe3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/import_rules_utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts @@ -14,18 +14,20 @@ import type { import type { RulesClient } from '@kbn/alerting-plugin/server'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; -import { legacyMigrate } from '../../../rules/utils'; -import type { ImportRuleResponse } from '../../utils'; -import { createBulkErrorObject } from '../../utils'; -import { createRules } from '../../../rules/create_rules'; -import { readRules } from '../../../rules/read_rules'; -import { patchRules } from '../../../rules/patch_rules'; -import type { ImportRulesSchema } from '../../../../../../common/detection_engine/schemas/request/import_rules_schema'; + +import type { RuleToImport } from '../../../../../../common/detection_engine/rule_management'; +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate } from '../rule_actions/legacy_action_migration'; +import type { ImportRuleResponse } from '../../../routes/utils'; +import { createBulkErrorObject } from '../../../routes/utils'; +import { createRules } from '../crud/create_rules'; +import { readRules } from '../crud/read_rules'; +import { patchRules } from '../crud/patch_rules'; import type { MlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; import { checkRuleExceptionReferences } from './check_rule_exception_references'; -export type PromiseFromStreams = ImportRulesSchema | Error; +export type PromiseFromStreams = RuleToImport | Error; export interface RuleExceptionsPromiseFromStreams { rules: PromiseFromStreams[]; exceptions: Array; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/legacy_action_migration.test.ts similarity index 56% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/utils.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/legacy_action_migration.test.ts index eb5d877d01942..f8332d5c3f3b1 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/legacy_action_migration.test.ts @@ -5,33 +5,21 @@ * 2.0. */ -import { - transformToNotifyWhen, - transformToAlertThrottle, - transformFromAlertThrottle, - transformActions, - legacyMigrate, - getUpdatedActionsParams, -} from './utils'; -import type { RuleAction, SanitizedRule } from '@kbn/alerting-plugin/common'; -import type { RuleParams } from '../schemas/rule_schemas'; -import { - NOTIFICATION_THROTTLE_NO_ACTIONS, - NOTIFICATION_THROTTLE_RULE, -} from '../../../../common/constants'; -import type { FullResponseSchema } from '../../../../common/detection_engine/schemas/request'; -// eslint-disable-next-line no-restricted-imports -import type { LegacyRuleActions } from '../rule_actions/legacy_types'; +import { requestContextMock } from '../../../routes/__mocks__'; import { getEmptyFindResult, - legacyGetSiemNotificationRuleActionsSOResultWithSingleHit, legacyGetDailyNotificationResult, legacyGetHourlyNotificationResult, + legacyGetSiemNotificationRuleActionsSOResultWithSingleHit, legacyGetWeeklyNotificationResult, -} from '../routes/__mocks__/request_responses'; -import { requestContextMock } from '../routes/__mocks__'; +} from '../../../routes/__mocks__/request_responses'; -const getRuleLegacyActions = (): SanitizedRule => +import type { RuleAlertType } from '../../../rule_schema'; + +// eslint-disable-next-line no-restricted-imports +import { legacyMigrate, getUpdatedActionsParams } from './legacy_action_migration'; + +const getRuleLegacyActions = (): RuleAlertType => ({ id: '123', notifyWhen: 'onThrottleInterval', @@ -82,377 +70,10 @@ const getRuleLegacyActions = (): SanitizedRule => lastExecutionDate: '2022-03-31T21:47:25.695Z', lastDuration: 0, }, - } as unknown as SanitizedRule); - -describe('utils', () => { - describe('#transformToNotifyWhen', () => { - test('"null" throttle returns "null" notify', () => { - expect(transformToNotifyWhen(null)).toEqual(null); - }); - - test('"undefined" throttle returns "null" notify', () => { - expect(transformToNotifyWhen(undefined)).toEqual(null); - }); - - test('"NOTIFICATION_THROTTLE_NO_ACTIONS" throttle returns "null" notify', () => { - expect(transformToNotifyWhen(NOTIFICATION_THROTTLE_NO_ACTIONS)).toEqual(null); - }); - - test('"NOTIFICATION_THROTTLE_RULE" throttle returns "onActiveAlert" notify', () => { - expect(transformToNotifyWhen(NOTIFICATION_THROTTLE_RULE)).toEqual('onActiveAlert'); - }); - - test('"1h" throttle returns "onThrottleInterval" notify', () => { - expect(transformToNotifyWhen('1d')).toEqual('onThrottleInterval'); - }); - - test('"1d" throttle returns "onThrottleInterval" notify', () => { - expect(transformToNotifyWhen('1d')).toEqual('onThrottleInterval'); - }); - - test('"7d" throttle returns "onThrottleInterval" notify', () => { - expect(transformToNotifyWhen('7d')).toEqual('onThrottleInterval'); - }); - }); - - describe('#transformToAlertThrottle', () => { - test('"null" throttle returns "null" alert throttle', () => { - expect(transformToAlertThrottle(null)).toEqual(null); - }); - - test('"undefined" throttle returns "null" alert throttle', () => { - expect(transformToAlertThrottle(undefined)).toEqual(null); - }); - - test('"NOTIFICATION_THROTTLE_NO_ACTIONS" throttle returns "null" alert throttle', () => { - expect(transformToAlertThrottle(NOTIFICATION_THROTTLE_NO_ACTIONS)).toEqual(null); - }); - - test('"NOTIFICATION_THROTTLE_RULE" throttle returns "null" alert throttle', () => { - expect(transformToAlertThrottle(NOTIFICATION_THROTTLE_RULE)).toEqual(null); - }); - - test('"1h" throttle returns "1h" alert throttle', () => { - expect(transformToAlertThrottle('1h')).toEqual('1h'); - }); - - test('"1d" throttle returns "1d" alert throttle', () => { - expect(transformToAlertThrottle('1d')).toEqual('1d'); - }); - - test('"7d" throttle returns "7d" alert throttle', () => { - expect(transformToAlertThrottle('7d')).toEqual('7d'); - }); - }); - - describe('#transformFromAlertThrottle', () => { - test('muteAll returns "NOTIFICATION_THROTTLE_NO_ACTIONS" even with notifyWhen set and actions has an array element', () => { - expect( - transformFromAlertThrottle( - { - muteAll: true, - notifyWhen: 'onActiveAlert', - actions: [ - { - group: 'group', - id: 'id-123', - actionTypeId: 'id-456', - params: {}, - }, - ], - } as SanitizedRule, - undefined - ) - ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); - }); - - test('returns "NOTIFICATION_THROTTLE_NO_ACTIONS" if actions is an empty array and we do not have a throttle', () => { - expect( - transformFromAlertThrottle( - { - muteAll: false, - notifyWhen: 'onActiveAlert', - actions: [], - } as unknown as SanitizedRule, - undefined - ) - ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); - }); - - test('returns "NOTIFICATION_THROTTLE_NO_ACTIONS" if actions is an empty array and we have a throttle', () => { - expect( - transformFromAlertThrottle( - { - muteAll: false, - notifyWhen: 'onThrottleInterval', - actions: [], - throttle: '1d', - } as unknown as SanitizedRule, - undefined - ) - ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); - }); - - test('it returns "NOTIFICATION_THROTTLE_RULE" if "notifyWhen" is set, muteAll is false and we have an actions array', () => { - expect( - transformFromAlertThrottle( - { - muteAll: false, - notifyWhen: 'onActiveAlert', - actions: [ - { - group: 'group', - id: 'id-123', - actionTypeId: 'id-456', - params: {}, - }, - ], - } as SanitizedRule, - undefined - ) - ).toEqual(NOTIFICATION_THROTTLE_RULE); - }); - - test('it returns "NOTIFICATION_THROTTLE_RULE" if "notifyWhen" and "throttle" are not set, but we have an actions array', () => { - expect( - transformFromAlertThrottle( - { - muteAll: false, - actions: [ - { - group: 'group', - id: 'id-123', - actionTypeId: 'id-456', - params: {}, - }, - ], - } as SanitizedRule, - undefined - ) - ).toEqual(NOTIFICATION_THROTTLE_RULE); - }); - - test('it will use the "rule" and not the "legacyRuleActions" if the rule and actions is defined', () => { - const legacyRuleActions: LegacyRuleActions = { - id: 'id_1', - ruleThrottle: '', - alertThrottle: '', - actions: [ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ], - }; - - expect( - transformFromAlertThrottle( - { - muteAll: true, - notifyWhen: 'onActiveAlert', - actions: [ - { - group: 'group', - id: 'id-123', - actionTypeId: 'id-456', - params: {}, - }, - ], - } as SanitizedRule, - legacyRuleActions - ) - ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); - }); - - test('it will use the "legacyRuleActions" and not the "rule" if the rule actions is an empty array', () => { - const legacyRuleActions: LegacyRuleActions = { - id: 'id_1', - ruleThrottle: NOTIFICATION_THROTTLE_RULE, - alertThrottle: null, - actions: [ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ], - }; - - expect( - transformFromAlertThrottle( - { - muteAll: true, - notifyWhen: 'onActiveAlert', - actions: [], - } as unknown as SanitizedRule, - legacyRuleActions - ) - ).toEqual(NOTIFICATION_THROTTLE_RULE); - }); - - test('it will use the "legacyRuleActions" and not the "rule" if the rule actions is a null', () => { - const legacyRuleActions: LegacyRuleActions = { - id: 'id_1', - ruleThrottle: NOTIFICATION_THROTTLE_RULE, - alertThrottle: null, - actions: [ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ], - }; - - expect( - transformFromAlertThrottle( - { - muteAll: true, - notifyWhen: 'onActiveAlert', - actions: null, - } as unknown as SanitizedRule, - legacyRuleActions - ) - ).toEqual(NOTIFICATION_THROTTLE_RULE); - }); - }); - - describe('#transformActions', () => { - test('It transforms two alert actions', () => { - const alertAction: RuleAction[] = [ - { - id: 'id_1', - group: 'group', - actionTypeId: 'actionTypeId', - params: {}, - }, - { - id: 'id_2', - group: 'group', - actionTypeId: 'actionTypeId', - params: {}, - }, - ]; - - const transformed = transformActions(alertAction, null); - expect(transformed).toEqual([ - { - id: 'id_1', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ]); - }); - - test('It transforms two alert actions but not a legacyRuleActions if this is also passed in', () => { - const alertAction: RuleAction[] = [ - { - id: 'id_1', - group: 'group', - actionTypeId: 'actionTypeId', - params: {}, - }, - { - id: 'id_2', - group: 'group', - actionTypeId: 'actionTypeId', - params: {}, - }, - ]; - const legacyRuleActions: LegacyRuleActions = { - id: 'id_1', - ruleThrottle: '', - alertThrottle: '', - actions: [ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ], - }; - const transformed = transformActions(alertAction, legacyRuleActions); - expect(transformed).toEqual([ - { - id: 'id_1', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ]); - }); - - test('It will transform the legacyRuleActions if the alertAction is an empty array', () => { - const alertAction: RuleAction[] = []; - const legacyRuleActions: LegacyRuleActions = { - id: 'id_1', - ruleThrottle: '', - alertThrottle: '', - actions: [ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ], - }; - const transformed = transformActions(alertAction, legacyRuleActions); - expect(transformed).toEqual([ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ]); - }); - - test('It will transform the legacyRuleActions if the alertAction is undefined', () => { - const legacyRuleActions: LegacyRuleActions = { - id: 'id_1', - ruleThrottle: '', - alertThrottle: '', - actions: [ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ], - }; - const transformed = transformActions(undefined, legacyRuleActions); - expect(transformed).toEqual([ - { - id: 'id_2', - group: 'group', - action_type_id: 'actionTypeId', - params: {}, - }, - ]); - }); - }); + } as unknown as RuleAlertType); - describe('#legacyMigrate', () => { +describe('Legacy rule action migration logic', () => { + describe('legacyMigrate', () => { const ruleId = '123'; const connectorId = '456'; const { clients } = requestContextMock.createTools(); @@ -477,7 +98,7 @@ describe('utils', () => { throttle: null, notifyWhen: 'onActiveAlert', muteAll: true, - } as SanitizedRule; + } as RuleAlertType; const migratedRule = await legacyMigrate({ rulesClient: clients.rulesClient, @@ -720,7 +341,7 @@ describe('utils', () => { }); }); - describe('#getUpdatedActionsParams', () => { + describe('getUpdatedActionsParams', () => { it('updates one action', () => { const { id, ...rule } = { ...getRuleLegacyActions(), @@ -728,7 +349,7 @@ describe('utils', () => { actions: [], throttle: null, notifyWhen: 'onActiveAlert', - } as SanitizedRule; + } as RuleAlertType; expect( getUpdatedActionsParams({ @@ -788,7 +409,7 @@ describe('utils', () => { actions: [], throttle: null, notifyWhen: 'onActiveAlert', - } as SanitizedRule; + } as RuleAlertType; expect( getUpdatedActionsParams({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/legacy_action_migration.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/legacy_action_migration.ts new file mode 100644 index 0000000000000..8c69edc33064b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/legacy_action_migration.ts @@ -0,0 +1,178 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty } from 'lodash/fp'; + +import type { RuleAction } from '@kbn/alerting-plugin/common'; +import type { RulesClient } from '@kbn/alerting-plugin/server'; +import type { SavedObjectReference, SavedObjectsClientContract } from '@kbn/core/server'; + +import { withSecuritySpan } from '../../../../../utils/with_security_span'; +import type { RuleAlertType } from '../../../rule_schema'; + +// eslint-disable-next-line no-restricted-imports +import { legacyRuleActionsSavedObjectType } from '../../../rule_actions_legacy'; +// eslint-disable-next-line no-restricted-imports +import type { + LegacyIRuleActionsAttributes, + LegacyRuleAlertSavedObjectAction, +} from '../../../rule_actions_legacy'; + +import { transformToAlertThrottle, transformToNotifyWhen } from '../../normalization/rule_actions'; + +export interface LegacyMigrateParams { + rulesClient: RulesClient; + savedObjectsClient: SavedObjectsClientContract; + rule: RuleAlertType | null | undefined; +} + +/** + * Determines if rule needs to be migrated from legacy actions + * and returns necessary pieces for the updated rule + */ +export const legacyMigrate = async ({ + rulesClient, + savedObjectsClient, + rule, +}: LegacyMigrateParams): Promise => + withSecuritySpan('legacyMigrate', async () => { + if (rule == null || rule.id == null) { + return rule; + } + /** + * On update / patch I'm going to take the actions as they are, better off taking rules client.find (siem.notification) result + * and putting that into the actions array of the rule, then set the rules onThrottle property, notifyWhen and throttle from null -> actual value (1hr etc..) + * Then use the rules client to delete the siem.notification + * Then with the legacy Rule Actions saved object type, just delete it. + */ + // find it using the references array, not params.ruleAlertId + const [siemNotification, legacyRuleActionsSO] = await Promise.all([ + rulesClient.find({ + options: { + filter: 'alert.attributes.alertTypeId:(siem.notifications)', + hasReference: { + type: 'alert', + id: rule.id, + }, + }, + }), + savedObjectsClient.find({ + type: legacyRuleActionsSavedObjectType, + hasReference: { + type: 'alert', + id: rule.id, + }, + }), + ]); + + const siemNotificationsExist = siemNotification != null && siemNotification.data.length > 0; + const legacyRuleNotificationSOsExist = + legacyRuleActionsSO != null && legacyRuleActionsSO.saved_objects.length > 0; + + // Assumption: if no legacy sidecar SO or notification rule types exist + // that reference the rule in question, assume rule actions are not legacy + if (!siemNotificationsExist && !legacyRuleNotificationSOsExist) { + return rule; + } + // If the legacy notification rule type ("siem.notification") exist, + // migration and cleanup are needed + if (siemNotificationsExist) { + await rulesClient.delete({ id: siemNotification.data[0].id }); + } + // If legacy notification sidecar ("siem-detection-engine-rule-actions") + // exist, migration and cleanup are needed + if (legacyRuleNotificationSOsExist) { + // Delete the legacy sidecar SO + await savedObjectsClient.delete( + legacyRuleActionsSavedObjectType, + legacyRuleActionsSO.saved_objects[0].id + ); + + // If "siem-detection-engine-rule-actions" notes that `ruleThrottle` is + // "no_actions" or "rule", rule has no actions or rule is set to run + // action on every rule run. In these cases, sidecar deletion is the only + // cleanup needed and updates to the "throttle" and "notifyWhen". "siem.notification" are + // not created for these action types + if ( + legacyRuleActionsSO.saved_objects[0].attributes.ruleThrottle === 'no_actions' || + legacyRuleActionsSO.saved_objects[0].attributes.ruleThrottle === 'rule' + ) { + return rule; + } + + // Use "legacyRuleActionsSO" instead of "siemNotification" as "siemNotification" is not created + // until a rule is run and added to task manager. That means that if by chance a user has a rule + // with actions which they have yet to enable, the actions would be lost. Instead, + // "legacyRuleActionsSO" is created on rule creation (pre 7.15) and we can rely on it to be there + const migratedRule = getUpdatedActionsParams({ + rule, + ruleThrottle: legacyRuleActionsSO.saved_objects[0].attributes.ruleThrottle, + actions: legacyRuleActionsSO.saved_objects[0].attributes.actions, + references: legacyRuleActionsSO.saved_objects[0].references, + }); + + await rulesClient.update({ + id: rule.id, + data: migratedRule, + }); + + return { id: rule.id, ...migratedRule }; + } + }); + +/** + * Translate legacy action sidecar action to rule action + */ +export const getUpdatedActionsParams = ({ + rule, + ruleThrottle, + actions, + references, +}: { + rule: RuleAlertType; + ruleThrottle: string | null; + actions: LegacyRuleAlertSavedObjectAction[]; + references: SavedObjectReference[]; +}): Omit => { + const { id, ...restOfRule } = rule; + + const actionReference = references.reduce>( + (acc, reference) => { + acc[reference.name] = reference; + return acc; + }, + {} + ); + + if (isEmpty(actionReference)) { + throw new Error( + `An error occurred migrating legacy action for rule with id:${id}. Connector reference id not found.` + ); + } + // If rule has an action on any other interval (other than on every + // rule run), need to move the action info from the sidecar/legacy action + // into the rule itself + return { + ...restOfRule, + actions: actions.reduce((acc, action) => { + const { actionRef, action_type_id: actionTypeId, ...resOfAction } = action; + if (!actionReference[actionRef]) { + return acc; + } + return [ + ...acc, + { + ...resOfAction, + id: actionReference[actionRef].id, + actionTypeId, + }, + ]; + }, []), + throttle: transformToAlertThrottle(ruleThrottle), + notifyWhen: transformToNotifyWhen(ruleThrottle), + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/muting.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/muting.ts new file mode 100644 index 0000000000000..6c0c7d9686767 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_actions/muting.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RulesClient } from '@kbn/alerting-plugin/server'; +import { NOTIFICATION_THROTTLE_NO_ACTIONS } from '../../../../../../common/constants'; +import type { RuleAlertType } from '../../../rule_schema'; + +/** + * Mutes, unmutes, or does nothing to the alert if no changed is detected + * @param id The id of the alert to (un)mute + * @param rulesClient the rules client + * @param muteAll If the existing alert has all actions muted + * @param throttle If the existing alert has a throttle set + */ +export const maybeMute = async ({ + id, + rulesClient, + muteAll, + throttle, +}: { + id: RuleAlertType['id']; + rulesClient: RulesClient; + muteAll: RuleAlertType['muteAll']; + throttle: string | null | undefined; +}): Promise => { + if (muteAll && throttle !== NOTIFICATION_THROTTLE_NO_ACTIONS) { + await rulesClient.unmuteAll({ id }); + } else if (!muteAll && throttle === NOTIFICATION_THROTTLE_NO_ACTIONS) { + await rulesClient.muteAll({ id }); + } else { + // Do nothing, no-operation + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/enrich_filter_with_rule_type_mappings.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/enrich_filter_with_rule_type_mappings.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/enrich_filter_with_rule_type_mappings.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/enrich_filter_with_rule_type_mappings.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/enrich_filter_with_rule_type_mappings.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/enrich_filter_with_rule_type_mappings.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/enrich_filter_with_rule_type_mappings.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/enrich_filter_with_rule_type_mappings.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/find_rules.ts similarity index 53% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/find_rules.ts index db45306420bb8..bb46831417d71 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/find_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/find_rules.ts @@ -5,11 +5,29 @@ * 2.0. */ -import type { FindResult } from '@kbn/alerting-plugin/server'; +import type { FindResult, RulesClient } from '@kbn/alerting-plugin/server'; + +import type { + FieldsOrUndefined, + PageOrUndefined, + PerPageOrUndefined, + QueryFilterOrUndefined, + SortFieldOrUndefined, + SortOrderOrUndefined, +} from '../../../../../../common/detection_engine/schemas/common'; + +import type { RuleParams } from '../../../rule_schema'; import { enrichFilterWithRuleTypeMapping } from './enrich_filter_with_rule_type_mappings'; -import type { RuleParams } from '../schemas/rule_schemas'; -import type { FindRuleOptions } from './types'; +export interface FindRuleOptions { + rulesClient: RulesClient; + filter: QueryFilterOrUndefined; + fields: FieldsOrUndefined; + sortField: SortFieldOrUndefined; + sortOrder: SortOrderOrUndefined; + page: PageOrUndefined; + perPage: PerPageOrUndefined; +} export const findRules = ({ rulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/get_existing_prepackaged_rules.test.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/get_existing_prepackaged_rules.test.ts index 279a211c9ea33..338a0239b6250 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/get_existing_prepackaged_rules.test.ts @@ -10,8 +10,8 @@ import { getRuleMock, getFindResultWithSingleHit, getFindResultWithMultiHits, -} from '../routes/__mocks__/request_responses'; -import { getQueryRuleParams } from '../schemas/rule_schemas.mock'; +} from '../../../routes/__mocks__/request_responses'; +import { getQueryRuleParams } from '../../../rule_schema/mocks'; import { getExistingPrepackagedRules, getNonPackagedRules, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/get_existing_prepackaged_rules.ts similarity index 93% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/get_existing_prepackaged_rules.ts index 0536a7e0a264d..469de8544a13a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/search/get_existing_prepackaged_rules.ts @@ -6,9 +6,9 @@ */ import type { RulesClient } from '@kbn/alerting-plugin/server'; -import { withSecuritySpan } from '../../../utils/with_security_span'; +import { withSecuritySpan } from '../../../../../utils/with_security_span'; import { findRules } from './find_rules'; -import type { RuleAlertType } from './types'; +import type { RuleAlertType } from '../../../rule_schema'; export const FILTER_NON_PREPACKED_RULES = 'alert.attributes.params.immutable: false'; export const FILTER_PREPACKED_RULES = 'alert.attributes.params.immutable: true'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.test.ts new file mode 100644 index 0000000000000..419e84d4d8373 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.test.ts @@ -0,0 +1,394 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RuleAction } from '@kbn/alerting-plugin/common'; + +import { + NOTIFICATION_THROTTLE_NO_ACTIONS, + NOTIFICATION_THROTTLE_RULE, +} from '../../../../../common/constants'; + +import type { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; +// eslint-disable-next-line no-restricted-imports +import type { LegacyRuleActions } from '../../rule_actions_legacy'; +import type { RuleAlertType } from '../../rule_schema'; + +import { + transformActions, + transformFromAlertThrottle, + transformToAlertThrottle, + transformToNotifyWhen, +} from './rule_actions'; + +describe('Rule actions normalization', () => { + describe('transformToNotifyWhen', () => { + test('"null" throttle returns "null" notify', () => { + expect(transformToNotifyWhen(null)).toEqual(null); + }); + + test('"undefined" throttle returns "null" notify', () => { + expect(transformToNotifyWhen(undefined)).toEqual(null); + }); + + test('"NOTIFICATION_THROTTLE_NO_ACTIONS" throttle returns "null" notify', () => { + expect(transformToNotifyWhen(NOTIFICATION_THROTTLE_NO_ACTIONS)).toEqual(null); + }); + + test('"NOTIFICATION_THROTTLE_RULE" throttle returns "onActiveAlert" notify', () => { + expect(transformToNotifyWhen(NOTIFICATION_THROTTLE_RULE)).toEqual('onActiveAlert'); + }); + + test('"1h" throttle returns "onThrottleInterval" notify', () => { + expect(transformToNotifyWhen('1d')).toEqual('onThrottleInterval'); + }); + + test('"1d" throttle returns "onThrottleInterval" notify', () => { + expect(transformToNotifyWhen('1d')).toEqual('onThrottleInterval'); + }); + + test('"7d" throttle returns "onThrottleInterval" notify', () => { + expect(transformToNotifyWhen('7d')).toEqual('onThrottleInterval'); + }); + }); + + describe('transformToAlertThrottle', () => { + test('"null" throttle returns "null" alert throttle', () => { + expect(transformToAlertThrottle(null)).toEqual(null); + }); + + test('"undefined" throttle returns "null" alert throttle', () => { + expect(transformToAlertThrottle(undefined)).toEqual(null); + }); + + test('"NOTIFICATION_THROTTLE_NO_ACTIONS" throttle returns "null" alert throttle', () => { + expect(transformToAlertThrottle(NOTIFICATION_THROTTLE_NO_ACTIONS)).toEqual(null); + }); + + test('"NOTIFICATION_THROTTLE_RULE" throttle returns "null" alert throttle', () => { + expect(transformToAlertThrottle(NOTIFICATION_THROTTLE_RULE)).toEqual(null); + }); + + test('"1h" throttle returns "1h" alert throttle', () => { + expect(transformToAlertThrottle('1h')).toEqual('1h'); + }); + + test('"1d" throttle returns "1d" alert throttle', () => { + expect(transformToAlertThrottle('1d')).toEqual('1d'); + }); + + test('"7d" throttle returns "7d" alert throttle', () => { + expect(transformToAlertThrottle('7d')).toEqual('7d'); + }); + }); + + describe('transformFromAlertThrottle', () => { + test('muteAll returns "NOTIFICATION_THROTTLE_NO_ACTIONS" even with notifyWhen set and actions has an array element', () => { + expect( + transformFromAlertThrottle( + { + muteAll: true, + notifyWhen: 'onActiveAlert', + actions: [ + { + group: 'group', + id: 'id-123', + actionTypeId: 'id-456', + params: {}, + }, + ], + } as RuleAlertType, + undefined + ) + ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); + }); + + test('returns "NOTIFICATION_THROTTLE_NO_ACTIONS" if actions is an empty array and we do not have a throttle', () => { + expect( + transformFromAlertThrottle( + { + muteAll: false, + notifyWhen: 'onActiveAlert', + actions: [], + } as unknown as RuleAlertType, + undefined + ) + ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); + }); + + test('returns "NOTIFICATION_THROTTLE_NO_ACTIONS" if actions is an empty array and we have a throttle', () => { + expect( + transformFromAlertThrottle( + { + muteAll: false, + notifyWhen: 'onThrottleInterval', + actions: [], + throttle: '1d', + } as unknown as RuleAlertType, + undefined + ) + ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); + }); + + test('it returns "NOTIFICATION_THROTTLE_RULE" if "notifyWhen" is set, muteAll is false and we have an actions array', () => { + expect( + transformFromAlertThrottle( + { + muteAll: false, + notifyWhen: 'onActiveAlert', + actions: [ + { + group: 'group', + id: 'id-123', + actionTypeId: 'id-456', + params: {}, + }, + ], + } as RuleAlertType, + undefined + ) + ).toEqual(NOTIFICATION_THROTTLE_RULE); + }); + + test('it returns "NOTIFICATION_THROTTLE_RULE" if "notifyWhen" and "throttle" are not set, but we have an actions array', () => { + expect( + transformFromAlertThrottle( + { + muteAll: false, + actions: [ + { + group: 'group', + id: 'id-123', + actionTypeId: 'id-456', + params: {}, + }, + ], + } as RuleAlertType, + undefined + ) + ).toEqual(NOTIFICATION_THROTTLE_RULE); + }); + + test('it will use the "rule" and not the "legacyRuleActions" if the rule and actions is defined', () => { + const legacyRuleActions: LegacyRuleActions = { + id: 'id_1', + ruleThrottle: '', + alertThrottle: '', + actions: [ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ], + }; + + expect( + transformFromAlertThrottle( + { + muteAll: true, + notifyWhen: 'onActiveAlert', + actions: [ + { + group: 'group', + id: 'id-123', + actionTypeId: 'id-456', + params: {}, + }, + ], + } as RuleAlertType, + legacyRuleActions + ) + ).toEqual(NOTIFICATION_THROTTLE_NO_ACTIONS); + }); + + test('it will use the "legacyRuleActions" and not the "rule" if the rule actions is an empty array', () => { + const legacyRuleActions: LegacyRuleActions = { + id: 'id_1', + ruleThrottle: NOTIFICATION_THROTTLE_RULE, + alertThrottle: null, + actions: [ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ], + }; + + expect( + transformFromAlertThrottle( + { + muteAll: true, + notifyWhen: 'onActiveAlert', + actions: [], + } as unknown as RuleAlertType, + legacyRuleActions + ) + ).toEqual(NOTIFICATION_THROTTLE_RULE); + }); + + test('it will use the "legacyRuleActions" and not the "rule" if the rule actions is a null', () => { + const legacyRuleActions: LegacyRuleActions = { + id: 'id_1', + ruleThrottle: NOTIFICATION_THROTTLE_RULE, + alertThrottle: null, + actions: [ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ], + }; + + expect( + transformFromAlertThrottle( + { + muteAll: true, + notifyWhen: 'onActiveAlert', + actions: null, + } as unknown as RuleAlertType, + legacyRuleActions + ) + ).toEqual(NOTIFICATION_THROTTLE_RULE); + }); + }); + + describe('transformActions', () => { + test('It transforms two alert actions', () => { + const alertAction: RuleAction[] = [ + { + id: 'id_1', + group: 'group', + actionTypeId: 'actionTypeId', + params: {}, + }, + { + id: 'id_2', + group: 'group', + actionTypeId: 'actionTypeId', + params: {}, + }, + ]; + + const transformed = transformActions(alertAction, null); + expect(transformed).toEqual([ + { + id: 'id_1', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ]); + }); + + test('It transforms two alert actions but not a legacyRuleActions if this is also passed in', () => { + const alertAction: RuleAction[] = [ + { + id: 'id_1', + group: 'group', + actionTypeId: 'actionTypeId', + params: {}, + }, + { + id: 'id_2', + group: 'group', + actionTypeId: 'actionTypeId', + params: {}, + }, + ]; + const legacyRuleActions: LegacyRuleActions = { + id: 'id_1', + ruleThrottle: '', + alertThrottle: '', + actions: [ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ], + }; + const transformed = transformActions(alertAction, legacyRuleActions); + expect(transformed).toEqual([ + { + id: 'id_1', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ]); + }); + + test('It will transform the legacyRuleActions if the alertAction is an empty array', () => { + const alertAction: RuleAction[] = []; + const legacyRuleActions: LegacyRuleActions = { + id: 'id_1', + ruleThrottle: '', + alertThrottle: '', + actions: [ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ], + }; + const transformed = transformActions(alertAction, legacyRuleActions); + expect(transformed).toEqual([ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ]); + }); + + test('It will transform the legacyRuleActions if the alertAction is undefined', () => { + const legacyRuleActions: LegacyRuleActions = { + id: 'id_1', + ruleThrottle: '', + alertThrottle: '', + actions: [ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ], + }; + const transformed = transformActions(undefined, legacyRuleActions); + expect(transformed).toEqual([ + { + id: 'id_2', + group: 'group', + action_type_id: 'actionTypeId', + params: {}, + }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts new file mode 100644 index 0000000000000..99b97ea6d89ec --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RuleAction, RuleNotifyWhenType } from '@kbn/alerting-plugin/common'; + +import { + NOTIFICATION_THROTTLE_NO_ACTIONS, + NOTIFICATION_THROTTLE_RULE, +} from '../../../../../common/constants'; + +import type { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; +import { transformAlertToRuleAction } from '../../../../../common/detection_engine/transform_actions'; +// eslint-disable-next-line no-restricted-imports +import type { LegacyRuleActions } from '../../rule_actions_legacy'; +import type { RuleAlertType } from '../../rule_schema'; + +/** + * Given a throttle from a "security_solution" rule this will transform it into an "alerting" notifyWhen + * on their saved object. + * @params throttle The throttle from a "security_solution" rule + * @returns The correct "NotifyWhen" for a Kibana alerting. + */ +export const transformToNotifyWhen = ( + throttle: string | null | undefined +): RuleNotifyWhenType | null => { + if (throttle == null || throttle === NOTIFICATION_THROTTLE_NO_ACTIONS) { + return null; // Although I return null, this does not change the value of the "notifyWhen" and it keeps the current value of "notifyWhen" + } else if (throttle === NOTIFICATION_THROTTLE_RULE) { + return 'onActiveAlert'; + } else { + return 'onThrottleInterval'; + } +}; + +/** + * Given a throttle from a "security_solution" rule this will transform it into an "alerting" "throttle" + * on their saved object. + * @params throttle The throttle from a "security_solution" rule + * @returns The "alerting" throttle + */ +export const transformToAlertThrottle = (throttle: string | null | undefined): string | null => { + if ( + throttle == null || + throttle === NOTIFICATION_THROTTLE_RULE || + throttle === NOTIFICATION_THROTTLE_NO_ACTIONS + ) { + return null; + } else { + return throttle; + } +}; + +/** + * Given a throttle from an "alerting" Saved Object (SO) this will transform it into a "security_solution" + * throttle type. If given the "legacyRuleActions" but we detect that the rule for an unknown reason has actions + * on it to which should not be typical but possible due to the split nature of the API's, this will prefer the + * usage of the non-legacy version. Eventually the "legacyRuleActions" should be removed. + * @param throttle The throttle from a "alerting" Saved Object (SO) + * @param legacyRuleActions Legacy "side car" rule actions that if it detects it being passed it in will transform using it. + * @returns The "security_solution" throttle + */ +export const transformFromAlertThrottle = ( + rule: RuleAlertType, + legacyRuleActions: LegacyRuleActions | null | undefined +): string => { + if (legacyRuleActions == null || (rule.actions != null && rule.actions.length > 0)) { + if (rule.muteAll || rule.actions.length === 0) { + return NOTIFICATION_THROTTLE_NO_ACTIONS; + } else if ( + rule.notifyWhen === 'onActiveAlert' || + (rule.throttle == null && rule.notifyWhen == null) + ) { + return NOTIFICATION_THROTTLE_RULE; + } else if (rule.throttle == null) { + return NOTIFICATION_THROTTLE_NO_ACTIONS; + } else { + return rule.throttle; + } + } else { + return legacyRuleActions.ruleThrottle; + } +}; + +/** + * Given a set of actions from an "alerting" Saved Object (SO) this will transform it into a "security_solution" alert action. + * If this detects any legacy rule actions it will transform it. If both are sent in which is not typical but possible due to + * the split nature of the API's this will prefer the usage of the non-legacy version. Eventually the "legacyRuleActions" should + * be removed. + * @param alertAction The alert action form a "alerting" Saved Object (SO). + * @param legacyRuleActions Legacy "side car" rule actions that if it detects it being passed it in will transform using it. + * @returns The actions of the RuleResponse + */ +export const transformActions = ( + alertAction: RuleAction[] | undefined, + legacyRuleActions: LegacyRuleActions | null | undefined +): RuleResponse['actions'] => { + if (alertAction != null && alertAction.length !== 0) { + return alertAction.map((action) => transformAlertToRuleAction(action)); + } else if (legacyRuleActions != null) { + return legacyRuleActions.actions; + } else { + return []; + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.test.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.test.ts index 50cfce7ac905a..f5e17d2bff231 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.test.ts @@ -14,8 +14,8 @@ import { getSavedQueryRuleParams, getThreatRuleParams, getThresholdRuleParams, -} from './rule_schemas.mock'; -import { getRuleMock } from '../routes/__mocks__/request_responses'; +} from '../../rule_schema/mocks'; +import { getRuleMock } from '../../routes/__mocks__/request_responses'; describe('rule_converters', () => { describe('patchTypeSpecificSnakeToCamel', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts similarity index 92% rename from x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts index e25f387160e5b..82d6ee6b1c4b2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts @@ -8,14 +8,53 @@ import uuid from 'uuid'; import { BadRequestError } from '@kbn/securitysolution-es-utils'; -import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; - +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; import type { ResolvedSanitizedRule, SanitizedRule } from '@kbn/alerting-plugin/common'; + +import { + DEFAULT_INDICATOR_SOURCE_PATH, + DEFAULT_MAX_SIGNALS, + SERVER_APP_ID, +} from '../../../../../common/constants'; + +import type { PatchRuleRequestBody } from '../../../../../common/detection_engine/rule_management'; +import type { RuleExecutionSummary } from '../../../../../common/detection_engine/rule_monitoring'; +import type { + RelatedIntegrationArray, + RequiredFieldArray, + SetupGuide, + RuleCreateProps, + RuleResponse, + TypeSpecificCreateProps, + TypeSpecificResponse, +} from '../../../../../common/detection_engine/rule_schema'; +import { + EqlPatchParams, + MachineLearningPatchParams, + NewTermsPatchParams, + QueryPatchParams, + SavedQueryPatchParams, + ThreatMatchPatchParams, + ThresholdPatchParams, +} from '../../../../../common/detection_engine/rule_schema'; + +import { + transformAlertToRuleResponseAction, + transformRuleToAlertAction, + transformRuleToAlertResponseAction, +} from '../../../../../common/detection_engine/transform_actions'; + import { normalizeMachineLearningJobIds, normalizeThresholdObject, -} from '../../../../common/detection_engine/utils'; +} from '../../../../../common/detection_engine/utils'; + +import { assertUnreachable } from '../../../../../common/utility_types'; + +// eslint-disable-next-line no-restricted-imports +import type { LegacyRuleActions } from '../../rule_actions_legacy'; +import { mergeRuleExecutionSummary } from '../../rule_monitoring'; import type { InternalRuleCreate, RuleParams, @@ -36,56 +75,13 @@ import type { InternalRuleUpdate, NewTermsRuleParams, NewTermsSpecificRuleParams, -} from './rule_schemas'; -import { assertUnreachable } from '../../../../common/utility_types'; -import type { - RelatedIntegrationArray, - RequiredFieldArray, - SetupGuide, -} from '../../../../common/detection_engine/schemas/common'; -import type { RuleExecutionSummary } from '../../../../common/detection_engine/rule_monitoring'; -import { - eqlPatchParams, - machineLearningPatchParams, - newTermsPatchParams, - queryPatchParams, - savedQueryPatchParams, - threatMatchPatchParams, - thresholdPatchParams, -} from '../../../../common/detection_engine/schemas/request'; -import type { - CreateRulesSchema, - CreateTypeSpecific, - EqlPatchParams, - FullResponseSchema, - MachineLearningPatchParams, - NewTermsPatchParams, - QueryPatchParams, - ResponseTypeSpecific, - SavedQueryPatchParams, - ThreatMatchPatchParams, - ThresholdPatchParams, -} from '../../../../common/detection_engine/schemas/request'; -import type { PatchRulesSchema } from '../../../../common/detection_engine/schemas/request/patch_rules_schema'; -import { - DEFAULT_INDICATOR_SOURCE_PATH, - DEFAULT_MAX_SIGNALS, - SERVER_APP_ID, -} from '../../../../common/constants'; -import { - transformAlertToRuleResponseAction, - transformRuleToAlertAction, - transformRuleToAlertResponseAction, -} from '../../../../common/detection_engine/transform_actions'; +} from '../../rule_schema'; import { + transformActions, transformFromAlertThrottle, transformToAlertThrottle, transformToNotifyWhen, - transformActions, -} from '../rules/utils'; -// eslint-disable-next-line no-restricted-imports -import type { LegacyRuleActions } from '../rule_actions/legacy_types'; -import { mergeRuleExecutionSummary } from '../rule_monitoring'; +} from './rule_actions'; // These functions provide conversions from the request API schema to the internal rule schema and from the internal rule schema // to the response API schema. This provides static type-check assurances that the internal schema is in sync with the API schema for @@ -95,7 +91,9 @@ import { mergeRuleExecutionSummary } from '../rule_monitoring'; // Converts params from the snake case API format to the internal camel case format AND applies default values where needed. // Notice that params.language is possibly undefined for most rule types in the API but we default it to kuery to match // the legacy API behavior -export const typeSpecificSnakeToCamel = (params: CreateTypeSpecific): TypeSpecificRuleParams => { +export const typeSpecificSnakeToCamel = ( + params: TypeSpecificCreateProps +): TypeSpecificRuleParams => { switch (params.type) { case 'eql': { return { @@ -322,7 +320,7 @@ const parseValidationError = (error: string | null): BadRequestError => { }; export const patchTypeSpecificSnakeToCamel = ( - params: PatchRulesSchema, + params: PatchRuleRequestBody, existingRule: RuleParams ): TypeSpecificRuleParams => { // Here we do the validation of patch params by rule type to ensure that the fields that are @@ -332,49 +330,49 @@ export const patchTypeSpecificSnakeToCamel = ( // but would be assignable to the other rule types since they don't specify `event_category_override`. switch (existingRule.type) { case 'eql': { - const [validated, error] = validateNonExact(params, eqlPatchParams); + const [validated, error] = validateNonExact(params, EqlPatchParams); if (validated == null) { throw parseValidationError(error); } return patchEqlParams(validated, existingRule); } case 'threat_match': { - const [validated, error] = validateNonExact(params, threatMatchPatchParams); + const [validated, error] = validateNonExact(params, ThreatMatchPatchParams); if (validated == null) { throw parseValidationError(error); } return patchThreatMatchParams(validated, existingRule); } case 'query': { - const [validated, error] = validateNonExact(params, queryPatchParams); + const [validated, error] = validateNonExact(params, QueryPatchParams); if (validated == null) { throw parseValidationError(error); } return patchQueryParams(validated, existingRule); } case 'saved_query': { - const [validated, error] = validateNonExact(params, savedQueryPatchParams); + const [validated, error] = validateNonExact(params, SavedQueryPatchParams); if (validated == null) { throw parseValidationError(error); } return patchSavedQueryParams(validated, existingRule); } case 'threshold': { - const [validated, error] = validateNonExact(params, thresholdPatchParams); + const [validated, error] = validateNonExact(params, ThresholdPatchParams); if (validated == null) { throw parseValidationError(error); } return patchThresholdParams(validated, existingRule); } case 'machine_learning': { - const [validated, error] = validateNonExact(params, machineLearningPatchParams); + const [validated, error] = validateNonExact(params, MachineLearningPatchParams); if (validated == null) { throw parseValidationError(error); } return patchMachineLearningParams(validated, existingRule); } case 'new_terms': { - const [validated, error] = validateNonExact(params, newTermsPatchParams); + const [validated, error] = validateNonExact(params, NewTermsPatchParams); if (validated == null) { throw parseValidationError(error); } @@ -387,7 +385,7 @@ export const patchTypeSpecificSnakeToCamel = ( }; const versionExcludedKeys = ['enabled', 'id', 'rule_id']; -const incrementVersion = (nextParams: PatchRulesSchema, existingRule: RuleParams) => { +const incrementVersion = (nextParams: PatchRuleRequestBody, existingRule: RuleParams) => { // The the version from nextParams if it's provided if (nextParams.version) { return nextParams.version; @@ -409,7 +407,7 @@ const incrementVersion = (nextParams: PatchRulesSchema, existingRule: RuleParams // eslint-disable-next-line complexity export const convertPatchAPIToInternalSchema = ( - nextParams: PatchRulesSchema & { + nextParams: PatchRuleRequestBody & { related_integrations?: RelatedIntegrationArray; required_fields?: RequiredFieldArray; setup?: SetupGuide; @@ -473,7 +471,7 @@ export const convertPatchAPIToInternalSchema = ( // eslint-disable-next-line complexity export const convertCreateAPIToInternalSchema = ( - input: CreateRulesSchema & { + input: RuleCreateProps & { related_integrations?: RelatedIntegrationArray; required_fields?: RequiredFieldArray; setup?: SetupGuide; @@ -530,7 +528,7 @@ export const convertCreateAPIToInternalSchema = ( }; // Converts the internal rule data structure to the response API schema -export const typeSpecificCamelToSnake = (params: TypeSpecificRuleParams): ResponseTypeSpecific => { +export const typeSpecificCamelToSnake = (params: TypeSpecificRuleParams): TypeSpecificResponse => { switch (params.type) { case 'eql': { return { @@ -666,10 +664,15 @@ export const internalRuleToAPIResponse = ( rule: SanitizedRule | ResolvedSanitizedRule, ruleExecutionSummary?: RuleExecutionSummary | null, legacyRuleActions?: LegacyRuleActions | null -): FullResponseSchema => { - const mergedExecutionSummary = mergeRuleExecutionSummary(rule, ruleExecutionSummary ?? null); +): RuleResponse => { + const mergedExecutionSummary = mergeRuleExecutionSummary( + rule.executionStatus, + ruleExecutionSummary ?? null + ); + const isResolvedRule = (obj: unknown): obj is ResolvedSanitizedRule => (obj as ResolvedSanitizedRule).outcome != null; + return { // saved object properties outcome: isResolvedRule(rule) ? rule.outcome : undefined, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts similarity index 94% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts index dd9d7ef74cb30..4737fad57a7e9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.test.ts @@ -5,49 +5,47 @@ * 2.0. */ +import { partition } from 'lodash/fp'; import { Readable } from 'stream'; import { createPromiseFromStreams } from '@kbn/utils'; -import type { Action, ThreatMapping } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { RuleAction, ThreatMapping } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { PartialRule } from '@kbn/alerting-plugin/server'; + +import type { RuleToImport } from '../../../../../common/detection_engine/rule_management'; +import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/rule_schema/mocks'; +import { requestContextMock } from '../../routes/__mocks__'; +import { getOutputRuleAlertForRest } from '../../routes/__mocks__/utils'; import { getIdError, transformFindAlerts, transform, getIdBulkError, transformAlertsToRules, - getDuplicates, getTupleDuplicateErrorsAndUniqueRules, getInvalidConnectors, swapActionIds, migrateLegacyActionsIds, } from './utils'; -import { getRuleMock } from '../__mocks__/request_responses'; +import { getRuleMock } from '../../routes/__mocks__/request_responses'; import type { PartialFilter } from '../../types'; -import type { BulkError } from '../utils'; -import { createBulkErrorObject } from '../utils'; -import { getOutputRuleAlertForRest } from '../__mocks__/utils'; -import type { PartialRule } from '@kbn/alerting-plugin/server'; -import { createRulesAndExceptionsStreamFromNdJson } from '../../rules/create_rules_stream_from_ndjson'; -import type { RuleAlertType } from '../../rules/types'; -import type { ImportRulesSchema } from '../../../../../common/detection_engine/schemas/request/import_rules_schema'; -import { getCreateRulesSchemaMock } from '../../../../../common/detection_engine/schemas/request/rule_schemas.mock'; -import type { CreateRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request'; -import { - getMlRuleParams, - getQueryRuleParams, - getThreatRuleParams, -} from '../../schemas/rule_schemas.mock'; -import { internalRuleToAPIResponse } from '../../schemas/rule_converters'; -import { requestContextMock } from '../__mocks__'; +import type { BulkError } from '../../routes/utils'; +import { createBulkErrorObject } from '../../routes/utils'; + +import type { RuleAlertType } from '../../rule_schema'; +import { getMlRuleParams, getQueryRuleParams, getThreatRuleParams } from '../../rule_schema/mocks'; // eslint-disable-next-line no-restricted-imports -import type { LegacyRulesActionsSavedObject } from '../../rule_actions/legacy_get_rule_actions_saved_object'; -// eslint-disable-next-line no-restricted-imports -import type { LegacyRuleAlertAction } from '../../rule_actions/legacy_types'; -import type { RuleExceptionsPromiseFromStreams } from './utils/import_rules_utils'; -import { partition } from 'lodash/fp'; +import type { + LegacyRuleAlertAction, + LegacyRulesActionsSavedObject, +} from '../../rule_actions_legacy'; + +import { createRulesAndExceptionsStreamFromNdJson } from '../logic/import/create_rules_stream_from_ndjson'; +import type { RuleExceptionsPromiseFromStreams } from '../logic/import/import_rules_utils'; +import { internalRuleToAPIResponse } from '../normalization/rule_converters'; -type PromiseFromStreams = ImportRulesSchema | Error; +type PromiseFromStreams = RuleToImport | Error; const createMockImportRule = async (rule: ReturnType) => { const ndJsonStream = new Readable({ @@ -492,39 +490,6 @@ describe('utils', () => { }); }); - describe('getDuplicates', () => { - test("returns array of ruleIds showing the duplicate keys of 'value2' and 'value3'", () => { - const output = getDuplicates( - [ - { rule_id: 'value1' }, - { rule_id: 'value2' }, - { rule_id: 'value2' }, - { rule_id: 'value3' }, - { rule_id: 'value3' }, - {}, - {}, - ] as CreateRulesBulkSchema, - 'rule_id' - ); - const expected = ['value2', 'value3']; - expect(output).toEqual(expected); - }); - test('returns null when given a map of no duplicates', () => { - const output = getDuplicates( - [ - { rule_id: 'value1' }, - { rule_id: 'value2' }, - { rule_id: 'value3' }, - {}, - {}, - ] as CreateRulesBulkSchema, - 'rule_id' - ); - const expected: string[] = []; - expect(output).toEqual(expected); - }); - }); - describe('getTupleDuplicateErrorsAndUniqueRules', () => { test('returns tuple of empty duplicate errors array and rule array with instance of Syntax Error when imported rule contains parse error', async () => { // This is a string because we have a double "::" below to make an error happen on purpose. @@ -645,7 +610,7 @@ describe('utils', () => { }); describe('swapActionIds', () => { - const mockAction: Action = { + const mockAction: RuleAction = { group: 'group string', id: 'some-7.x-id', action_type_id: '.slack', @@ -706,7 +671,7 @@ describe('utils', () => { }); describe('migrateLegacyActionsIds', () => { - const mockAction: Action = { + const mockAction: RuleAction = { group: 'group string', id: 'some-7.x-id', action_type_id: '.slack', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.ts similarity index 85% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.ts index 9dfd5b1efed7c..3c8ca41801303 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/utils.ts @@ -5,29 +5,29 @@ * 2.0. */ -import { countBy, partition } from 'lodash/fp'; -import uuid from 'uuid'; -import type { Action } from '@kbn/securitysolution-io-ts-alerting-types'; -import type { SavedObjectsClientContract } from '@kbn/core/server'; +import { partition } from 'lodash/fp'; import pMap from 'p-map'; +import uuid from 'uuid'; +import type { SavedObjectsClientContract } from '@kbn/core/server'; +import type { RuleAction } from '@kbn/securitysolution-io-ts-alerting-types'; import type { PartialRule, FindResult } from '@kbn/alerting-plugin/server'; import type { ActionsClient, FindActionResult } from '@kbn/actions-plugin/server'; + +import type { RuleToImport } from '../../../../../common/detection_engine/rule_management'; import type { RuleExecutionSummary } from '../../../../../common/detection_engine/rule_monitoring'; -import type { ImportRulesSchema } from '../../../../../common/detection_engine/schemas/request/import_rules_schema'; -import type { CreateRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/create_rules_bulk_schema'; -import type { RuleAlertType } from '../../rules/types'; -import { isAlertType } from '../../rules/types'; -import type { BulkError, OutputError } from '../utils'; -import { createBulkErrorObject } from '../utils'; -import { internalRuleToAPIResponse } from '../../schemas/rule_converters'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; + // eslint-disable-next-line no-restricted-imports -import type { LegacyRulesActionsSavedObject } from '../../rule_actions/legacy_get_rule_actions_saved_object'; +import type { LegacyRulesActionsSavedObject } from '../../rule_actions_legacy'; import type { RuleExecutionSummariesByRuleId } from '../../rule_monitoring'; -import type { FullResponseSchema } from '../../../../../common/detection_engine/schemas/request'; +import type { RuleAlertType, RuleParams } from '../../rule_schema'; +import { isAlertType } from '../../rule_schema'; +import type { BulkError, OutputError } from '../../routes/utils'; +import { createBulkErrorObject } from '../../routes/utils'; +import { internalRuleToAPIResponse } from '../normalization/rule_converters'; -type PromiseFromStreams = ImportRulesSchema | Error; +type PromiseFromStreams = RuleToImport | Error; const MAX_CONCURRENT_SEARCHES = 10; export const getIdError = ({ @@ -92,7 +92,7 @@ export const getIdBulkError = ({ export const transformAlertsToRules = ( rules: RuleAlertType[], legacyRuleActions: Record -): FullResponseSchema[] => { +): RuleResponse[] => { return rules.map((rule) => internalRuleToAPIResponse(rule, null, legacyRuleActions[rule.id])); }; @@ -104,7 +104,7 @@ export const transformFindAlerts = ( page: number; perPage: number; total: number; - data: Array>; + data: Array>; } | null => { return { page: ruleFindResults.page, @@ -121,7 +121,7 @@ export const transform = ( rule: PartialRule, ruleExecutionSummary?: RuleExecutionSummary | null, legacyRuleActions?: LegacyRulesActionsSavedObject | null -): FullResponseSchema | null => { +): RuleResponse | null => { if (isAlertType(rule)) { return internalRuleToAPIResponse(rule, ruleExecutionSummary, legacyRuleActions); } @@ -129,18 +129,6 @@ export const transform = ( return null; }; -export const getDuplicates = (ruleDefinitions: CreateRulesBulkSchema, by: 'rule_id'): string[] => { - const mappedDuplicates = countBy( - by, - ruleDefinitions.filter((r) => r[by] != null) - ); - const hasDuplicates = Object.values(mappedDuplicates).some((i) => i > 1); - if (hasDuplicates) { - return Object.keys(mappedDuplicates).filter((key) => mappedDuplicates[key] > 1); - } - return []; -}; - export const getTupleDuplicateErrorsAndUniqueRules = ( rules: PromiseFromStreams[], isOverwrite: boolean @@ -189,12 +177,12 @@ const createQuery = (type: string, id: string) => * @returns */ export const swapActionIds = async ( - action: Action, + action: RuleAction, savedObjectsClient: SavedObjectsClientContract -): Promise => { +): Promise => { try { const search = createQuery('action', action.id); - const foundAction = await savedObjectsClient.find({ + const foundAction = await savedObjectsClient.find({ type: 'action', search, rootSearchFields: ['_id', 'originId'], @@ -247,7 +235,7 @@ export const migrateLegacyActionsIds = async ( rules: PromiseFromStreams[], savedObjectsClient: SavedObjectsClientContract ): Promise => { - const isImportRule = (r: unknown): r is ImportRulesSchema => !(r instanceof Error); + const isImportRule = (r: unknown): r is RuleToImport => !(r instanceof Error); const toReturn = await pMap( rules, @@ -255,14 +243,14 @@ export const migrateLegacyActionsIds = async ( if (isImportRule(rule)) { // can we swap the pre 8.0 action connector(s) id with the new, // post-8.0 action id (swap the originId for the new _id?) - const newActions: Array = await pMap( + const newActions: Array = await pMap( rule.actions ?? [], - (action: Action) => swapActionIds(action, savedObjectsClient), + (action: RuleAction) => swapActionIds(action, savedObjectsClient), { concurrency: MAX_CONCURRENT_SEARCHES } ); // were there any errors discovered while trying to migrate and swap the action connector ids? - const [actionMigrationErrors, newlyMigratedActions] = partition( + const [actionMigrationErrors, newlyMigratedActions] = partition( (item): item is Error => item instanceof Error )(newActions); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.test.ts similarity index 92% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.test.ts index fbd763aed9758..8d920ef4ba652 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.test.ts @@ -6,15 +6,15 @@ */ import { transformValidate, transformValidateBulkError } from './validate'; -import type { BulkError } from '../utils'; -import { getRuleMock } from '../__mocks__/request_responses'; +import type { BulkError } from '../../routes/utils'; +import { getRuleMock } from '../../routes/__mocks__/request_responses'; import { ruleExecutionSummaryMock } from '../../../../../common/detection_engine/rule_monitoring/mocks'; import { getListArrayMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; import { getThreatMock } from '../../../../../common/detection_engine/schemas/types/threat.mock'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; -import type { FullResponseSchema } from '../../../../../common/detection_engine/schemas/request'; +import { getQueryRuleParams } from '../../rule_schema/mocks'; +import type { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; -export const ruleOutput = (): FullResponseSchema => ({ +export const ruleOutput = (): RuleResponse => ({ actions: [], author: ['Elastic'], building_block_type: 'default', @@ -124,7 +124,7 @@ describe('validate', () => { const rule = getRuleMock(getQueryRuleParams()); const ruleExecutionSumary = ruleExecutionSummaryMock.getSummarySucceeded(); const validatedOrError = transformValidateBulkError('rule-1', rule, ruleExecutionSumary); - const expected: FullResponseSchema = { + const expected: RuleResponse = { ...ruleOutput(), execution_summary: ruleExecutionSumary, }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts similarity index 68% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts index 42e50db79294a..e784068e0248e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/validate.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/utils/validate.ts @@ -9,27 +9,26 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import type { PartialRule } from '@kbn/alerting-plugin/server'; import type { RuleExecutionSummary } from '../../../../../common/detection_engine/rule_monitoring'; -import type { FullResponseSchema } from '../../../../../common/detection_engine/schemas/request'; -import { fullResponseSchema } from '../../../../../common/detection_engine/schemas/request'; -import { isAlertType } from '../../rules/types'; -import type { BulkError } from '../utils'; -import { createBulkErrorObject } from '../utils'; +import { RuleResponse } from '../../../../../common/detection_engine/rule_schema'; +import type { RuleParams } from '../../rule_schema'; +import { isAlertType } from '../../rule_schema'; +import type { BulkError } from '../../routes/utils'; +import { createBulkErrorObject } from '../../routes/utils'; import { transform } from './utils'; -import type { RuleParams } from '../../schemas/rule_schemas'; // eslint-disable-next-line no-restricted-imports -import type { LegacyRulesActionsSavedObject } from '../../rule_actions/legacy_get_rule_actions_saved_object'; -import { internalRuleToAPIResponse } from '../../schemas/rule_converters'; +import type { LegacyRulesActionsSavedObject } from '../../rule_actions_legacy'; +import { internalRuleToAPIResponse } from '../normalization/rule_converters'; export const transformValidate = ( rule: PartialRule, ruleExecutionSummary: RuleExecutionSummary | null, legacyRuleActions?: LegacyRulesActionsSavedObject | null -): [FullResponseSchema | null, string | null] => { +): [RuleResponse | null, string | null] => { const transformed = transform(rule, ruleExecutionSummary, legacyRuleActions); if (transformed == null) { return [null, 'Internal error transforming']; } else { - return validateNonExact(transformed, fullResponseSchema); + return validateNonExact(transformed, RuleResponse); } }; @@ -37,10 +36,10 @@ export const transformValidateBulkError = ( ruleId: string, rule: PartialRule, ruleExecutionSummary: RuleExecutionSummary | null -): FullResponseSchema | BulkError => { +): RuleResponse | BulkError => { if (isAlertType(rule)) { const transformed = internalRuleToAPIResponse(rule, ruleExecutionSummary); - const [validated, errors] = validateNonExact(transformed, fullResponseSchema); + const [validated, errors] = validateNonExact(transformed, RuleResponse); if (errors != null || validated == null) { return createBulkErrorObject({ ruleId, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/merge_rule_execution_summary.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/merge_rule_execution_summary.ts index 2b017d27bb971..cf403f3d6b66c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/merge_rule_execution_summary.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/rule_execution_log/merge_rule_execution_summary.ts @@ -5,22 +5,23 @@ * 2.0. */ +import type { RuleExecutionStatus as RuleExecutionStatusByFramework } from '@kbn/alerting-plugin/common'; + import type { RuleExecutionSummary } from '../../../../../../common/detection_engine/rule_monitoring'; import { RuleExecutionStatus, ruleExecutionStatusToNumber, } from '../../../../../../common/detection_engine/rule_monitoring'; -import type { RuleAlertType } from '../../../rules/types'; export const mergeRuleExecutionSummary = ( - rule: RuleAlertType, + ruleExecutionStatus: RuleExecutionStatusByFramework, ruleExecutionSummary: RuleExecutionSummary | null ): RuleExecutionSummary | null => { if (ruleExecutionSummary == null) { return null; } - const frameworkStatus = rule.executionStatus; + const frameworkStatus = ruleExecutionStatus; const customStatus = ruleExecutionSummary.last_execution; if ( diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts similarity index 88% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts index 9a1ba3a2b144c..1c82dc1194cef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/route.ts @@ -17,30 +17,35 @@ import type { import { parseDuration } from '@kbn/alerting-plugin/common'; import type { ExecutorType } from '@kbn/alerting-plugin/server/types'; import type { Alert } from '@kbn/alerting-plugin/server'; -import type { StartPlugins, SetupPlugins } from '../../../../plugin'; -import { buildSiemResponse } from '../utils'; -import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters'; -import type { RuleParams } from '../../schemas/rule_schemas'; -import { createPreviewRuleExecutionLogger } from '../../signals/preview/preview_rule_execution_logger'; -import { parseInterval } from '../../signals/utils'; -import { buildMlAuthz } from '../../../machine_learning/authz'; -import { throwAuthzError } from '../../../machine_learning/validation'; -import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents'; + import { DEFAULT_PREVIEW_INDEX, DETECTION_ENGINE_RULES_PREVIEW, -} from '../../../../../common/constants'; -import { wrapScopedClusterClient } from './utils/wrap_scoped_cluster_client'; -import type { RulePreviewLogs } from '../../../../../common/detection_engine/schemas/request'; -import { previewRulesSchema } from '../../../../../common/detection_engine/schemas/request'; -import { RuleExecutionStatus } from '../../../../../common/detection_engine/rule_monitoring'; -import type { RuleExecutionContext, StatusChangeArgs } from '../../rule_monitoring'; +} from '../../../../../../common/constants'; +import { validateCreateRuleProps } from '../../../../../../common/detection_engine/rule_management'; +import { RuleExecutionStatus } from '../../../../../../common/detection_engine/rule_monitoring'; +import type { RulePreviewLogs } from '../../../../../../common/detection_engine/rule_schema'; +import { previewRulesSchema } from '../../../../../../common/detection_engine/rule_schema'; + +import type { StartPlugins, SetupPlugins } from '../../../../../plugin'; +import { buildSiemResponse } from '../../../routes/utils'; +import { convertCreateAPIToInternalSchema } from '../../../rule_management'; +import type { RuleParams } from '../../../rule_schema'; +import { createPreviewRuleExecutionLogger } from '../../../signals/preview/preview_rule_execution_logger'; +import { parseInterval } from '../../../signals/utils'; +import { buildMlAuthz } from '../../../../machine_learning/authz'; +import { throwAuthzError } from '../../../../machine_learning/validation'; +import { buildRouteValidation } from '../../../../../utils/build_validation/route_validation'; +import type { SecuritySolutionPluginRouter } from '../../../../../types'; -import type { ConfigType } from '../../../../config'; -import { alertInstanceFactoryStub } from '../../signals/preview/alert_instance_factory_stub'; -import type { CreateRuleOptions, CreateSecurityRuleTypeWrapperProps } from '../../rule_types/types'; +import type { RuleExecutionContext, StatusChangeArgs } from '../../../rule_monitoring'; + +import type { ConfigType } from '../../../../../config'; +import { alertInstanceFactoryStub } from '../../../signals/preview/alert_instance_factory_stub'; +import type { + CreateRuleOptions, + CreateSecurityRuleTypeWrapperProps, +} from '../../../rule_types/types'; import { createEqlAlertType, createIndicatorMatchAlertType, @@ -49,10 +54,11 @@ import { createSavedQueryAlertType, createThresholdAlertType, createNewTermsAlertType, -} from '../../rule_types'; -import { createSecurityRuleTypeWrapper } from '../../rule_types/create_security_rule_type_wrapper'; -import { assertUnreachable } from '../../../../../common/utility_types'; -import { wrapSearchSourceClient } from './utils/wrap_search_source_client'; +} from '../../../rule_types'; +import { createSecurityRuleTypeWrapper } from '../../../rule_types/create_security_rule_type_wrapper'; +import { assertUnreachable } from '../../../../../../common/utility_types'; +import { wrapScopedClusterClient } from './wrap_scoped_cluster_client'; +import { wrapSearchSourceClient } from './wrap_search_source_client'; const PREVIEW_TIMEOUT_SECONDS = 60; @@ -79,7 +85,7 @@ export const previewRulesRoute = async ( }, async (context, request, response) => { const siemResponse = buildSiemResponse(response); - const validationErrors = createRuleValidateTypeDependents(request.body); + const validationErrors = validateCreateRuleProps(request.body); const coreContext = await context.core; if (validationErrors.length) { return siemResponse.error({ statusCode: 400, body: validationErrors }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_scoped_cluster_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_scoped_cluster_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_scoped_cluster_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_scoped_cluster_client.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_scoped_cluster_client.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/utils/wrap_search_source_client.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/preview_rules/wrap_search_source_client.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/register_routes.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/register_routes.ts new file mode 100644 index 0000000000000..4fedc1ea27849 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/api/register_routes.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger, StartServicesAccessor } from '@kbn/core/server'; +import type { IRuleDataClient } from '@kbn/rule-registry-plugin/server'; + +import type { ConfigType } from '../../../../config'; +import type { SetupPlugins, StartPlugins } from '../../../../plugin_contract'; +import type { SecuritySolutionPluginRouter } from '../../../../types'; +import type { CreateRuleOptions, CreateSecurityRuleTypeWrapperProps } from '../../rule_types/types'; + +import { previewRulesRoute } from './preview_rules/route'; + +export const registerRulePreviewRoutes = ( + router: SecuritySolutionPluginRouter, + config: ConfigType, + ml: SetupPlugins['ml'], + security: SetupPlugins['security'], + ruleOptions: CreateRuleOptions, + securityRuleTypeOptions: CreateSecurityRuleTypeWrapperProps, + previewRuleDataClient: IRuleDataClient, + getStartServices: StartServicesAccessor, + logger: Logger +) => { + previewRulesRoute( + router, + config, + ml, + security, + ruleOptions, + securityRuleTypeOptions, + previewRuleDataClient, + getStartServices, + logger + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/index.ts new file mode 100644 index 0000000000000..c0123e587d9bf --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_preview/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './api/register_routes'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/index.ts new file mode 100644 index 0000000000000..9b4598ed13641 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './model/rule_alert_type'; +export * from './model/rule_schemas'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/mocks.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/mocks.ts new file mode 100644 index 0000000000000..7b2a4f4440689 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/mocks.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './model/rule_schemas.mock'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_alert_type.ts new file mode 100644 index 0000000000000..f7e73b49104c1 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_alert_type.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ruleTypeMappings } from '@kbn/securitysolution-rules'; +import type { SanitizedRule } from '@kbn/alerting-plugin/common'; +import type { PartialRule } from '@kbn/alerting-plugin/server'; +import type { RuleParams } from './rule_schemas'; + +export type RuleAlertType = SanitizedRule; + +export const isAlertType = ( + partialAlert: PartialRule +): partialAlert is RuleAlertType => { + const ruleTypeValues = Object.values(ruleTypeMappings) as unknown as string[]; + return ruleTypeValues.includes(partialAlert.alertTypeId as string); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_schemas.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts similarity index 93% rename from x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_schemas.mock.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts index d608c08eabcd9..f41494cf5fed4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_schemas.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.mock.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { getThreatMock } from '../../../../common/detection_engine/schemas/types/threat.mock'; -import { getListArrayMock } from '../../../../common/detection_engine/schemas/types/lists.mock'; -import { getThreatMappingMock } from '../signals/threat_mapping/build_threat_mapping_filter.mock'; +import { getThreatMock } from '../../../../../common/detection_engine/schemas/types/threat.mock'; +import { getListArrayMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; +import { getThreatMappingMock } from '../../signals/threat_mapping/build_threat_mapping_filter.mock'; import type { BaseRuleParams, CompleteRule, @@ -19,9 +19,9 @@ import type { SavedQueryRuleParams, ThreatRuleParams, ThresholdRuleParams, -} from './rule_schemas'; +} from '..'; import type { SanitizedRuleConfig } from '@kbn/alerting-plugin/common'; -import { sampleRuleGuid } from '../signals/__mocks__/es_results'; +import { sampleRuleGuid } from '../../signals/__mocks__/es_results'; const getBaseRuleParams = (): BaseRuleParams => { return { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_schemas.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts similarity index 62% rename from x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_schemas.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts index 80f9adf29aacb..0e64cc3788a12 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_schemas.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts @@ -8,25 +8,22 @@ import * as t from 'io-ts'; import { - actionsCamel, - from, + concurrentSearchesOrUndefined, + itemsPerSearchOrUndefined, machine_learning_job_id_normalized, - risk_score, - risk_score_mapping, - threat_mapping, + RiskScore, + RiskScoreMapping, + RuleActionArrayCamel, + RuleActionThrottle, + RuleIntervalFrom, + RuleIntervalTo, + Severity, + SeverityMapping, threat_index, + threat_mapping, threat_query, - concurrentSearchesOrUndefined, - itemsPerSearchOrUndefined, threatIndicatorPathOrUndefined, - threats, - severity, - severity_mapping, - throttleOrNull, - max_signals, } from '@kbn/securitysolution-io-ts-alerting-types'; -import { listArray } from '@kbn/securitysolution-io-ts-list-types'; -import { version } from '@kbn/securitysolution-io-ts-types'; import { SIGNALS_ID, EQL_RULE_TYPE_ID, @@ -40,80 +37,84 @@ import { import type { SanitizedRuleConfig } from '@kbn/alerting-plugin/common'; import { - author, - buildingBlockTypeOrUndefined, - description, - enabled, - namespaceOrUndefined, - noteOrUndefined, - false_positives, - rule_id, - immutable, - dataViewIdOrUndefined, - indexOrUndefined, - licenseOrUndefined, - output_index, - timelineIdOrUndefined, - timelineTitleOrUndefined, - metaOrUndefined, - name, - query, - queryOrUndefined, - filtersOrUndefined, - ruleNameOverrideOrUndefined, - tags, - timestampOverrideOrUndefined, - to, - references, - timestampFieldOrUndefined, - eventCategoryOverrideOrUndefined, - tiebreakerFieldOrUndefined, - savedIdOrUndefined, - saved_id, - thresholdNormalized, - anomaly_threshold, + AlertsIndex, + AlertsIndexNamespace, + BuildingBlockType, + DataViewId, + EventCategoryOverride, + ExceptionListArray, + HistoryWindowStart, + IndexPatternArray, + InvestigationGuide, + IsRuleEnabled, + IsRuleImmutable, + MaxSignals, + NewTermsFields, RelatedIntegrationArray, RequiredFieldArray, + RuleAuthorArray, + RuleDescription, + RuleFalsePositiveArray, + RuleFilterArray, + RuleLicense, + RuleMetadata, + RuleName, + RuleNameOverride, + RuleQuery, + RuleReferenceArray, + RuleSignatureId, + RuleTagArray, + RuleVersion, SetupGuide, - newTermsFields, - historyWindowStart, - timestampOverrideFallbackDisabledOrUndefined, -} from '../../../../common/detection_engine/schemas/common'; -import { SERVER_APP_ID } from '../../../../common/constants'; -import { ResponseActionRuleParamsOrUndefined } from '../../../../common/detection_engine/rule_response_actions/schemas'; + ThreatArray, + ThresholdNormalized, + TiebreakerField, + TimelineTemplateId, + TimelineTemplateTitle, + TimestampField, + TimestampOverride, + TimestampOverrideFallbackDisabled, +} from '../../../../../common/detection_engine/rule_schema'; +import { + savedIdOrUndefined, + saved_id, + anomaly_threshold, +} from '../../../../../common/detection_engine/schemas/common'; +import { SERVER_APP_ID } from '../../../../../common/constants'; +import { ResponseActionRuleParamsOrUndefined } from '../../../../../common/detection_engine/rule_response_actions/schemas'; const nonEqlLanguages = t.keyof({ kuery: null, lucene: null }); export const baseRuleParams = t.exact( t.type({ - author, - buildingBlockType: buildingBlockTypeOrUndefined, - description, - namespace: namespaceOrUndefined, - note: noteOrUndefined, - falsePositives: false_positives, - from, - ruleId: rule_id, - immutable, - license: licenseOrUndefined, - outputIndex: output_index, - timelineId: timelineIdOrUndefined, - timelineTitle: timelineTitleOrUndefined, - meta: metaOrUndefined, + author: RuleAuthorArray, + buildingBlockType: t.union([BuildingBlockType, t.undefined]), + description: RuleDescription, + namespace: t.union([AlertsIndexNamespace, t.undefined]), + note: t.union([InvestigationGuide, t.undefined]), + falsePositives: RuleFalsePositiveArray, + from: RuleIntervalFrom, + ruleId: RuleSignatureId, + immutable: IsRuleImmutable, + license: t.union([RuleLicense, t.undefined]), + outputIndex: AlertsIndex, + timelineId: t.union([TimelineTemplateId, t.undefined]), + timelineTitle: t.union([TimelineTemplateTitle, t.undefined]), + meta: t.union([RuleMetadata, t.undefined]), // maxSignals not used in ML rules but probably should be used - maxSignals: max_signals, - riskScore: risk_score, - riskScoreMapping: risk_score_mapping, - ruleNameOverride: ruleNameOverrideOrUndefined, - severity, - severityMapping: severity_mapping, - timestampOverride: timestampOverrideOrUndefined, - timestampOverrideFallbackDisabled: timestampOverrideFallbackDisabledOrUndefined, - threat: threats, - to, - references, - version, - exceptionsList: listArray, + maxSignals: MaxSignals, + riskScore: RiskScore, + riskScoreMapping: RiskScoreMapping, + ruleNameOverride: t.union([RuleNameOverride, t.undefined]), + severity: Severity, + severityMapping: SeverityMapping, + timestampOverride: t.union([TimestampOverride, t.undefined]), + timestampOverrideFallbackDisabled: t.union([TimestampOverrideFallbackDisabled, t.undefined]), + threat: ThreatArray, + to: RuleIntervalTo, + references: RuleReferenceArray, + version: RuleVersion, + exceptionsList: ExceptionListArray, relatedIntegrations: t.union([RelatedIntegrationArray, t.undefined]), requiredFields: t.union([RequiredFieldArray, t.undefined]), setup: t.union([SetupGuide, t.undefined]), @@ -124,13 +125,13 @@ export type BaseRuleParams = t.TypeOf; const eqlSpecificRuleParams = t.type({ type: t.literal('eql'), language: t.literal('eql'), - index: indexOrUndefined, - query, - filters: filtersOrUndefined, - timestampField: timestampFieldOrUndefined, - eventCategoryOverride: eventCategoryOverrideOrUndefined, - dataViewId: dataViewIdOrUndefined, - tiebreakerField: tiebreakerFieldOrUndefined, + index: t.union([IndexPatternArray, t.undefined]), + dataViewId: t.union([DataViewId, t.undefined]), + query: RuleQuery, + filters: t.union([RuleFilterArray, t.undefined]), + eventCategoryOverride: t.union([EventCategoryOverride, t.undefined]), + timestampField: t.union([TimestampField, t.undefined]), + tiebreakerField: t.union([TiebreakerField, t.undefined]), }); export const eqlRuleParams = t.intersection([baseRuleParams, eqlSpecificRuleParams]); export type EqlSpecificRuleParams = t.TypeOf; @@ -139,11 +140,11 @@ export type EqlRuleParams = t.TypeOf; const threatSpecificRuleParams = t.type({ type: t.literal('threat_match'), language: nonEqlLanguages, - index: indexOrUndefined, - query, - filters: filtersOrUndefined, + index: t.union([IndexPatternArray, t.undefined]), + query: RuleQuery, + filters: t.union([RuleFilterArray, t.undefined]), savedId: savedIdOrUndefined, - threatFilters: filtersOrUndefined, + threatFilters: t.union([RuleFilterArray, t.undefined]), threatQuery: threat_query, threatMapping: threat_mapping, threatLanguage: t.union([nonEqlLanguages, t.undefined]), @@ -151,7 +152,7 @@ const threatSpecificRuleParams = t.type({ threatIndicatorPath: threatIndicatorPathOrUndefined, concurrentSearches: concurrentSearchesOrUndefined, itemsPerSearch: itemsPerSearchOrUndefined, - dataViewId: dataViewIdOrUndefined, + dataViewId: t.union([DataViewId, t.undefined]), }); export const threatRuleParams = t.intersection([baseRuleParams, threatSpecificRuleParams]); export type ThreatSpecificRuleParams = t.TypeOf; @@ -161,11 +162,11 @@ const querySpecificRuleParams = t.exact( t.type({ type: t.literal('query'), language: nonEqlLanguages, - index: indexOrUndefined, - query, - filters: filtersOrUndefined, + index: t.union([IndexPatternArray, t.undefined]), + query: RuleQuery, + filters: t.union([RuleFilterArray, t.undefined]), savedId: savedIdOrUndefined, - dataViewId: dataViewIdOrUndefined, + dataViewId: t.union([DataViewId, t.undefined]), responseActions: ResponseActionRuleParamsOrUndefined, }) ); @@ -178,10 +179,10 @@ const savedQuerySpecificRuleParams = t.type({ // Having language, query, and filters possibly defined adds more code confusion and probably user confusion // if the saved object gets deleted for some reason language: nonEqlLanguages, - index: indexOrUndefined, - dataViewId: dataViewIdOrUndefined, - query: queryOrUndefined, - filters: filtersOrUndefined, + index: t.union([IndexPatternArray, t.undefined]), + dataViewId: t.union([DataViewId, t.undefined]), + query: t.union([RuleQuery, t.undefined]), + filters: t.union([RuleFilterArray, t.undefined]), savedId: saved_id, responseActions: ResponseActionRuleParamsOrUndefined, }); @@ -198,12 +199,12 @@ export type UnifiedQueryRuleParams = t.TypeOf; const thresholdSpecificRuleParams = t.type({ type: t.literal('threshold'), language: nonEqlLanguages, - index: indexOrUndefined, - query, - filters: filtersOrUndefined, + index: t.union([IndexPatternArray, t.undefined]), + query: RuleQuery, + filters: t.union([RuleFilterArray, t.undefined]), savedId: savedIdOrUndefined, - threshold: thresholdNormalized, - dataViewId: dataViewIdOrUndefined, + threshold: ThresholdNormalized, + dataViewId: t.union([DataViewId, t.undefined]), }); export const thresholdRuleParams = t.intersection([baseRuleParams, thresholdSpecificRuleParams]); export type ThresholdSpecificRuleParams = t.TypeOf; @@ -223,13 +224,13 @@ export type MachineLearningRuleParams = t.TypeOf; @@ -274,30 +275,30 @@ export const allRuleTypes = t.union([ ]); export const internalRuleCreate = t.type({ - name, - tags, + name: RuleName, + tags: RuleTagArray, alertTypeId: allRuleTypes, consumer: t.literal(SERVER_APP_ID), schedule: t.type({ interval: t.string, }), - enabled, - actions: actionsCamel, + enabled: IsRuleEnabled, + actions: RuleActionArrayCamel, params: ruleParams, - throttle: throttleOrNull, + throttle: t.union([RuleActionThrottle, t.null]), notifyWhen, }); export type InternalRuleCreate = t.TypeOf; export const internalRuleUpdate = t.type({ - name, - tags, + name: RuleName, + tags: RuleTagArray, schedule: t.type({ interval: t.string, }), - actions: actionsCamel, + actions: RuleActionArrayCamel, params: ruleParams, - throttle: throttleOrNull, + throttle: t.union([RuleActionThrottle, t.null]), notifyWhen, }); export type InternalRuleUpdate = t.TypeOf; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts index 505560ee6a25c..8ec684b2065fe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleParams } from '../../rule_schema'; export const createRuleMock = (params: Partial) => ({ actions: [], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts index bfe25804de29a..a76e3d3d3af7e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/rule_type.ts @@ -20,10 +20,10 @@ import type { ConfigType } from '../../../../config'; import type { AlertAttributes } from '../../signals/types'; import { createRuleMock } from './rule'; import { listMock } from '@kbn/lists-plugin/server/mocks'; -import type { QueryRuleParams, RuleParams } from '../../schemas/rule_schemas'; +import type { QueryRuleParams, RuleParams } from '../../rule_schema'; // this is only used in tests import { createDefaultAlertExecutorOptions } from '@kbn/rule-registry-plugin/server/utils/rule_executor.test_helpers'; -import { getCompleteRuleMock } from '../../schemas/rule_schemas.mock'; +import { getCompleteRuleMock } from '../../rule_schema/mocks'; export const createRuleTypeMocks = ( ruleType: string = 'query', diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/threshold.ts index 21107ba361645..ab6d64e69b58d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/__mocks__/threshold.ts @@ -26,7 +26,7 @@ import { flattenWithPrefix } from '@kbn/securitysolution-rules'; import type { TypeOfFieldMap } from '@kbn/rule-registry-plugin/common/field_map'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import { ANCHOR_DATE } from '../../../../../common/detection_engine/schemas/response/rules_schema.mocks'; +import { ANCHOR_DATE } from '../../../../../common/detection_engine/rule_schema/mocks'; import { getListArrayMock } from '../../../../../common/detection_engine/schemas/types/lists.mock'; import type { RulesFieldMap } from '../../../../../common/field_maps'; import { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts index 05813ed1ee29c..bd630b1a71107 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/create_security_rule_type_wrapper.ts @@ -25,14 +25,18 @@ import { import { DEFAULT_MAX_SIGNALS, DEFAULT_SEARCH_AFTER_PAGE_SIZE } from '../../../../common/constants'; import type { CreateSecurityRuleTypeWrapper } from './types'; import { getListClient } from './utils/get_list_client'; -import type { NotificationRuleTypeParams } from '../notifications/schedule_notification_actions'; -import { scheduleNotificationActions } from '../notifications/schedule_notification_actions'; -import { getNotificationResultsLink } from '../notifications/utils'; +// eslint-disable-next-line no-restricted-imports +import type { NotificationRuleTypeParams } from '../rule_actions_legacy'; +// eslint-disable-next-line no-restricted-imports +import { + scheduleNotificationActions, + scheduleThrottledNotificationActions, + getNotificationResultsLink, +} from '../rule_actions_legacy'; import { createResultObject } from './utils'; import { bulkCreateFactory, wrapHitsFactory, wrapSequencesFactory } from './factories'; import { RuleExecutionStatus } from '../../../../common/detection_engine/rule_monitoring'; import { truncateList } from '../rule_monitoring'; -import { scheduleThrottledNotificationActions } from '../notifications/schedule_throttle_notification_actions'; import aadFieldConversion from '../routes/index/signal_aad_mapping.json'; import { extractReferences, injectReferences } from '../signals/saved_object_references'; import { withSecuritySpan } from '../../../utils/with_security_span'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts index 0d1a8462ac738..6e31a9753d381 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/eql/create_eql_alert_type.ts @@ -9,8 +9,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { EQL_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { EqlRuleParams } from '../../schemas/rule_schemas'; -import { eqlRuleParams } from '../../schemas/rule_schemas'; +import type { EqlRuleParams } from '../../rule_schema'; +import { eqlRuleParams } from '../../rule_schema'; import { eqlExecutor } from '../../signals/executors/eql'; import type { CreateRuleOptions, SecurityAlertType } from '../types'; import { validateIndexPatterns } from '../utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.test.ts index b1f9ed1361da1..5e6cccd11e037 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.test.ts @@ -41,7 +41,7 @@ import { ALERT_BUILDING_BLOCK_TYPE, ALERT_RULE_INDICES, } from '../../../../../../common/field_maps/field_names'; -import { getCompleteRuleMock, getQueryRuleParams } from '../../../schemas/rule_schemas.mock'; +import { getCompleteRuleMock, getQueryRuleParams } from '../../../rule_schema/mocks'; type SignalDoc = SignalSourceHit & { _source: Required['_source'] & { [TIMESTAMP]: string }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts index 38115347a8241..c716af17361ec 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert.ts @@ -74,11 +74,8 @@ import { ALERT_RULE_EXCEPTIONS_LIST, ALERT_RULE_IMMUTABLE, } from '../../../../../../common/field_maps/field_names'; -import type { CompleteRule, RuleParams } from '../../../schemas/rule_schemas'; -import { - commonParamsCamelToSnake, - typeSpecificCamelToSnake, -} from '../../../schemas/rule_converters'; +import type { CompleteRule, RuleParams } from '../../../rule_schema'; +import { commonParamsCamelToSnake, typeSpecificCamelToSnake } from '../../../rule_management'; import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; import type { AncestorLatest, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.test.ts index d90bc09fb7794..e047c86e75473 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.test.ts @@ -16,8 +16,8 @@ import { objectPairIntersection, } from './build_alert_group_from_sequence'; import { SERVER_APP_ID } from '../../../../../../common/constants'; -import { getCompleteRuleMock, getQueryRuleParams } from '../../../schemas/rule_schemas.mock'; -import type { QueryRuleParams } from '../../../schemas/rule_schemas'; +import { getCompleteRuleMock, getQueryRuleParams } from '../../../rule_schema/mocks'; +import type { QueryRuleParams } from '../../../rule_schema'; import { ALERT_ANCESTORS, ALERT_DEPTH, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.ts index ccd089e767308..700986198468c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_alert_group_from_sequence.ts @@ -16,7 +16,7 @@ import { buildBulkBody } from './build_bulk_body'; import type { EqlSequence } from '../../../../../../common/detection_engine/types'; import { generateBuildingBlockIds } from './generate_building_block_ids'; import type { BuildReasonMessage } from '../../../signals/reason_formatters'; -import type { CompleteRule, RuleParams } from '../../../schemas/rule_schemas'; +import type { CompleteRule, RuleParams } from '../../../rule_schema'; import { ALERT_BUILDING_BLOCK_TYPE, ALERT_GROUP_ID, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_bulk_body.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_bulk_body.ts index 5ea566ce33af0..4d63f5c848484 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_bulk_body.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/build_bulk_body.ts @@ -15,7 +15,7 @@ import { getMergeStrategy } from '../../../signals/source_fields_merging/strateg import type { BaseSignalHit, SignalSource, SignalSourceHit } from '../../../signals/types'; import { additionalAlertFields, buildAlert } from './build_alert'; import { filterSource } from './filter_source'; -import type { CompleteRule, RuleParams } from '../../../schemas/rule_schemas'; +import type { CompleteRule, RuleParams } from '../../../rule_schema'; import { buildRuleNameFromMapping } from '../../../signals/mappings/build_rule_name_from_mapping'; import { buildSeverityFromMapping } from '../../../signals/mappings/build_severity_from_mapping'; import { buildRiskScoreFromMapping } from '../../../signals/mappings/build_risk_score_from_mapping'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.test.ts index dfdd2ce715ee4..6742f21759648 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.test.ts @@ -7,7 +7,7 @@ import { ALERT_UUID } from '@kbn/rule-data-utils'; import { ALERT_NEW_TERMS } from '../../../../../../common/field_maps/field_names'; -import { getCompleteRuleMock, getNewTermsRuleParams } from '../../../schemas/rule_schemas.mock'; +import { getCompleteRuleMock, getNewTermsRuleParams } from '../../../rule_schema/mocks'; import { sampleDocNoSortIdWithTimestamp } from '../../../signals/__mocks__/es_results'; import { wrapNewTermsAlerts } from './wrap_new_terms_alerts'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.ts index f3e1434b75f2b..38ae5b1be75ae 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/utils/wrap_new_terms_alerts.ts @@ -15,7 +15,7 @@ import type { } from '../../../../../../common/detection_engine/schemas/alerts'; import { ALERT_NEW_TERMS } from '../../../../../../common/field_maps/field_names'; import type { ConfigType } from '../../../../../config'; -import type { CompleteRule, RuleParams } from '../../../schemas/rule_schemas'; +import type { CompleteRule, RuleParams } from '../../../rule_schema'; import { buildReasonMessageForNewTermsAlert } from '../../../signals/reason_formatters'; import type { SignalSource } from '../../../signals/types'; import { buildBulkBody } from './build_bulk_body'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_hits_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_hits_factory.ts index bf4c3a8aa46e3..75d55a5756680 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_hits_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_hits_factory.ts @@ -10,7 +10,7 @@ import { ALERT_UUID } from '@kbn/rule-data-utils'; import type { ConfigType } from '../../../../config'; import type { SignalSource, SimpleHit } from '../../signals/types'; -import type { CompleteRule, RuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, RuleParams } from '../../rule_schema'; import { generateId } from '../../signals/utils'; import { buildBulkBody } from './utils/build_bulk_body'; import type { BuildReasonMessage } from '../../signals/reason_formatters'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_sequences_factory.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_sequences_factory.ts index ccf959daa9e7a..b700c31cf7c72 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_sequences_factory.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/factories/wrap_sequences_factory.ts @@ -10,7 +10,7 @@ import type { Logger } from '@kbn/core/server'; import type { WrapSequences } from '../../signals/types'; import { buildAlertGroupFromSequence } from './utils/build_alert_group_from_sequence'; import type { ConfigType } from '../../../../config'; -import type { CompleteRule, RuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, RuleParams } from '../../rule_schema'; import type { BaseFieldsLatest, WrappedFieldsLatest, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts index fe0bc6fe77a7c..796900829d6ea 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/indicator_match/create_indicator_match_alert_type.ts @@ -9,8 +9,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { INDICATOR_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { ThreatRuleParams } from '../../schemas/rule_schemas'; -import { threatRuleParams } from '../../schemas/rule_schemas'; +import type { ThreatRuleParams } from '../../rule_schema'; +import { threatRuleParams } from '../../rule_schema'; import { threatMatchExecutor } from '../../signals/executors/threat_match'; import type { CreateRuleOptions, SecurityAlertType } from '../types'; import { validateIndexPatterns } from '../utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts index f70d6d82087c9..c652de348484f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/ml/create_ml_alert_type.ts @@ -9,8 +9,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { ML_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { MachineLearningRuleParams } from '../../schemas/rule_schemas'; -import { machineLearningRuleParams } from '../../schemas/rule_schemas'; +import type { MachineLearningRuleParams } from '../../rule_schema'; +import { machineLearningRuleParams } from '../../rule_schema'; import { mlExecutor } from '../../signals/executors/ml'; import type { CreateRuleOptions, SecurityAlertType } from '../types'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts index 2e22d3a5798bf..630553bc4d78c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/new_terms/create_new_terms_alert_type.ts @@ -10,8 +10,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { NEW_TERMS_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { NewTermsRuleParams } from '../../schemas/rule_schemas'; -import { newTermsRuleParams } from '../../schemas/rule_schemas'; +import type { NewTermsRuleParams } from '../../rule_schema'; +import { newTermsRuleParams } from '../../rule_schema'; import type { CreateRuleOptions, SecurityAlertType } from '../types'; import { singleSearchAfter } from '../../signals/single_search_after'; import { getFilter } from '../../signals/get_filter'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts index dfd0ffc6c4353..c2ecb5a88df8e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts @@ -15,7 +15,7 @@ import { createMockConfig } from '../../routes/__mocks__'; import { createMockTelemetryEventsSender } from '../../../telemetry/__mocks__'; import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; import { sampleDocNoSortId } from '../../signals/__mocks__/es_results'; -import { getQueryRuleParams } from '../../schemas/rule_schemas.mock'; +import { getQueryRuleParams } from '../../rule_schema/mocks'; import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; jest.mock('../../signals/utils', () => ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts index 4ce8a1dacabf7..4f246e5ada204 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.ts @@ -9,8 +9,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { QUERY_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { UnifiedQueryRuleParams } from '../../schemas/rule_schemas'; -import { unifiedQueryRuleParams } from '../../schemas/rule_schemas'; +import type { UnifiedQueryRuleParams } from '../../rule_schema'; +import { unifiedQueryRuleParams } from '../../rule_schema'; import { queryExecutor } from '../../signals/executors/query'; import type { CreateQueryRuleOptions, SecurityAlertType } from '../types'; import { validateIndexPatterns } from '../utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/saved_query/create_saved_query_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/saved_query/create_saved_query_alert_type.ts index 6565e6e14cfea..6e761bb6a51a0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/saved_query/create_saved_query_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/saved_query/create_saved_query_alert_type.ts @@ -9,8 +9,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { SAVED_QUERY_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { CompleteRule, UnifiedQueryRuleParams } from '../../schemas/rule_schemas'; -import { unifiedQueryRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, UnifiedQueryRuleParams } from '../../rule_schema'; +import { unifiedQueryRuleParams } from '../../rule_schema'; import { queryExecutor } from '../../signals/executors/query'; import type { CreateQueryRuleOptions, SecurityAlertType } from '../types'; import { validateIndexPatterns } from '../utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts index 1541b08c5938c..b465abed15977 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/create_threshold_alert_type.ts @@ -9,8 +9,8 @@ import { validateNonExact } from '@kbn/securitysolution-io-ts-utils'; import { THRESHOLD_RULE_TYPE_ID } from '@kbn/securitysolution-rules'; import { SERVER_APP_ID } from '../../../../../common/constants'; -import type { ThresholdRuleParams } from '../../schemas/rule_schemas'; -import { thresholdRuleParams } from '../../schemas/rule_schemas'; +import type { ThresholdRuleParams } from '../../rule_schema'; +import { thresholdRuleParams } from '../../rule_schema'; import { thresholdExecutor } from '../../signals/executors/threshold'; import type { ThresholdAlertState } from '../../signals/types'; import type { CreateRuleOptions, SecurityAlertType } from '../types'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts index e1af3077ec3e3..03634c19b0ba0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/types.ts @@ -29,7 +29,7 @@ import type { LicensingPluginSetup } from '@kbn/licensing-plugin/server'; import type { Filter } from '@kbn/es-query'; import type { ConfigType } from '../../../config'; import type { SetupPlugins } from '../../../plugin'; -import type { CompleteRule, RuleParams } from '../schemas/rule_schemas'; +import type { CompleteRule, RuleParams } from '../rule_schema'; import type { BulkCreate, SearchAfterAndBulkCreateReturnType, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts deleted file mode 100644 index 0075b091d58a4..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/get_prepackaged_rules.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getPrepackagedRules } from './get_prepackaged_rules'; -import { isEmpty } from 'lodash/fp'; -import type { AddPrepackagedRulesSchema } from '../../../../common/detection_engine/schemas/request/add_prepackaged_rules_schema'; - -describe('get_existing_prepackaged_rules', () => { - test('should not throw any errors with the existing checked in pre-packaged rules', () => { - expect(() => getPrepackagedRules()).not.toThrow(); - }); - - test('no rule should have the same rule_id as another rule_id', () => { - const prePackagedRules = getPrepackagedRules(); - let existingRuleIds: AddPrepackagedRulesSchema[] = []; - prePackagedRules.forEach((rule) => { - const foundDuplicate = existingRuleIds.reduce((accum, existingRule) => { - if (existingRule.rule_id === rule.rule_id) { - return `Found duplicate rule_id of ${rule.rule_id} between these two rule names of "${rule.name}" and "${existingRule.name}"`; - } else { - return accum; - } - }, ''); - if (!isEmpty(foundDuplicate)) { - expect(foundDuplicate).toEqual(''); - } else { - existingRuleIds = [...existingRuleIds, rule]; - } - }); - }); - - test('should throw an exception if a pre-packaged rule is not valid', () => { - // @ts-expect-error intentionally invalid argument - expect(() => getPrepackagedRules([{ not_valid_made_up_key: true }])).toThrow(); - }); - - test('should throw an exception with a message having rule_id and name in it', () => { - expect(() => - // @ts-expect-error intentionally invalid argument - getPrepackagedRules([{ name: 'rule name', rule_id: 'id-123' }]) - ).toThrow(); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts deleted file mode 100644 index e1b55ca9124b1..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/types.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Readable } from 'stream'; - -import type { SavedObjectsClientContract } from '@kbn/core/server'; -import type { SanitizedRule } from '@kbn/alerting-plugin/common'; -import type { RulesClient, PartialRule } from '@kbn/alerting-plugin/server'; -import { ruleTypeMappings } from '@kbn/securitysolution-rules'; - -import type { - FieldsOrUndefined, - Id, - IdOrUndefined, - PageOrUndefined, - PerPageOrUndefined, - QueryFilterOrUndefined, - RuleIdOrUndefined, - SortFieldOrUndefined, - SortOrderOrUndefined, -} from '../../../../common/detection_engine/schemas/common'; - -import type { CreateRulesSchema } from '../../../../common/detection_engine/schemas/request/rule_schemas'; -import type { PatchRulesSchema } from '../../../../common/detection_engine/schemas/request/patch_rules_schema'; -import type { UpdateRulesSchema } from '../../../../common/detection_engine/schemas/request'; - -import type { RuleParams } from '../schemas/rule_schemas'; -import type { IRuleExecutionLogForRoutes } from '../rule_monitoring'; - -export type RuleAlertType = SanitizedRule; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export interface IRuleAssetSOAttributes extends Record { - rule_id: string | null | undefined; - version: string | null | undefined; - name: string | null | undefined; -} - -export interface IRuleAssetSavedObject { - type: string; - id: string; - attributes: IRuleAssetSOAttributes; -} - -export interface HapiReadableStream extends Readable { - hapi: { - filename: string; - }; -} - -export interface Clients { - rulesClient: RulesClient; -} - -export const isAlertType = ( - partialAlert: PartialRule -): partialAlert is RuleAlertType => { - const ruleTypeValues = Object.values(ruleTypeMappings) as unknown as string[]; - return ruleTypeValues.includes(partialAlert.alertTypeId as string); -}; - -export interface CreateRulesOptions { - rulesClient: RulesClient; - params: T; - id?: string; - immutable?: boolean; - defaultEnabled?: boolean; -} - -export interface UpdateRulesOptions { - rulesClient: RulesClient; - existingRule: RuleAlertType | null | undefined; - ruleUpdate: UpdateRulesSchema; -} - -export interface PatchRulesOptions { - rulesClient: RulesClient; - nextParams: PatchRulesSchema; - existingRule: RuleAlertType | null | undefined; -} - -export interface ReadRuleOptions { - rulesClient: RulesClient; - id: IdOrUndefined; - ruleId: RuleIdOrUndefined; -} - -export interface DeleteRuleOptions { - ruleId: Id; - rulesClient: RulesClient; - ruleExecutionLog: IRuleExecutionLogForRoutes; -} - -export interface FindRuleOptions { - rulesClient: RulesClient; - filter: QueryFilterOrUndefined; - fields: FieldsOrUndefined; - sortField: SortFieldOrUndefined; - sortOrder: SortOrderOrUndefined; - page: PageOrUndefined; - perPage: PerPageOrUndefined; -} - -export interface LegacyMigrateParams { - rulesClient: RulesClient; - savedObjectsClient: SavedObjectsClientContract; - rule: SanitizedRule | null | undefined; -} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rules/utils.ts deleted file mode 100644 index dc35948bafe8a..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rules/utils.ts +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { RuleAction, RuleNotifyWhenType, SanitizedRule } from '@kbn/alerting-plugin/common'; -import type { RulesClient } from '@kbn/alerting-plugin/server'; -import type { SavedObjectReference } from '@kbn/core/server'; -import { isEmpty } from 'lodash/fp'; -import { - NOTIFICATION_THROTTLE_NO_ACTIONS, - NOTIFICATION_THROTTLE_RULE, -} from '../../../../common/constants'; -import type { - AddPrepackagedRulesSchema, - FullResponseSchema, -} from '../../../../common/detection_engine/schemas/request'; -import { transformAlertToRuleAction } from '../../../../common/detection_engine/transform_actions'; -import { withSecuritySpan } from '../../../utils/with_security_span'; -// eslint-disable-next-line no-restricted-imports -import { legacyRuleActionsSavedObjectType } from '../rule_actions/legacy_saved_object_mappings'; -// eslint-disable-next-line no-restricted-imports -import type { - LegacyIRuleActionsAttributes, - LegacyRuleActions, - LegacyRuleAlertSavedObjectAction, -} from '../rule_actions/legacy_types'; -import type { RuleParams } from '../schemas/rule_schemas'; -import type { LegacyMigrateParams, RuleAlertType } from './types'; - -/** - * Given a throttle from a "security_solution" rule this will transform it into an "alerting" notifyWhen - * on their saved object. - * @params throttle The throttle from a "security_solution" rule - * @returns The correct "NotifyWhen" for a Kibana alerting. - */ -export const transformToNotifyWhen = ( - throttle: string | null | undefined -): RuleNotifyWhenType | null => { - if (throttle == null || throttle === NOTIFICATION_THROTTLE_NO_ACTIONS) { - return null; // Although I return null, this does not change the value of the "notifyWhen" and it keeps the current value of "notifyWhen" - } else if (throttle === NOTIFICATION_THROTTLE_RULE) { - return 'onActiveAlert'; - } else { - return 'onThrottleInterval'; - } -}; - -/** - * Given a throttle from a "security_solution" rule this will transform it into an "alerting" "throttle" - * on their saved object. - * @params throttle The throttle from a "security_solution" rule - * @returns The "alerting" throttle - */ -export const transformToAlertThrottle = (throttle: string | null | undefined): string | null => { - if ( - throttle == null || - throttle === NOTIFICATION_THROTTLE_RULE || - throttle === NOTIFICATION_THROTTLE_NO_ACTIONS - ) { - return null; - } else { - return throttle; - } -}; - -/** - * Given a set of actions from an "alerting" Saved Object (SO) this will transform it into a "security_solution" alert action. - * If this detects any legacy rule actions it will transform it. If both are sent in which is not typical but possible due to - * the split nature of the API's this will prefer the usage of the non-legacy version. Eventually the "legacyRuleActions" should - * be removed. - * @param alertAction The alert action form a "alerting" Saved Object (SO). - * @param legacyRuleActions Legacy "side car" rule actions that if it detects it being passed it in will transform using it. - * @returns The actions of the FullResponseSchema - */ -export const transformActions = ( - alertAction: RuleAction[] | undefined, - legacyRuleActions: LegacyRuleActions | null | undefined -): FullResponseSchema['actions'] => { - if (alertAction != null && alertAction.length !== 0) { - return alertAction.map((action) => transformAlertToRuleAction(action)); - } else if (legacyRuleActions != null) { - return legacyRuleActions.actions; - } else { - return []; - } -}; - -/** - * Given a throttle from an "alerting" Saved Object (SO) this will transform it into a "security_solution" - * throttle type. If given the "legacyRuleActions" but we detect that the rule for an unknown reason has actions - * on it to which should not be typical but possible due to the split nature of the API's, this will prefer the - * usage of the non-legacy version. Eventually the "legacyRuleActions" should be removed. - * @param throttle The throttle from a "alerting" Saved Object (SO) - * @param legacyRuleActions Legacy "side car" rule actions that if it detects it being passed it in will transform using it. - * @returns The "security_solution" throttle - */ -export const transformFromAlertThrottle = ( - rule: SanitizedRule, - legacyRuleActions: LegacyRuleActions | null | undefined -): string => { - if (legacyRuleActions == null || (rule.actions != null && rule.actions.length > 0)) { - if (rule.muteAll || rule.actions.length === 0) { - return NOTIFICATION_THROTTLE_NO_ACTIONS; - } else if ( - rule.notifyWhen === 'onActiveAlert' || - (rule.throttle == null && rule.notifyWhen == null) - ) { - return NOTIFICATION_THROTTLE_RULE; - } else if (rule.throttle == null) { - return NOTIFICATION_THROTTLE_NO_ACTIONS; - } else { - return rule.throttle; - } - } else { - return legacyRuleActions.ruleThrottle; - } -}; - -/** - * Mutes, unmutes, or does nothing to the alert if no changed is detected - * @param id The id of the alert to (un)mute - * @param rulesClient the rules client - * @param muteAll If the existing alert has all actions muted - * @param throttle If the existing alert has a throttle set - */ -export const maybeMute = async ({ - id, - rulesClient, - muteAll, - throttle, -}: { - id: SanitizedRule['id']; - rulesClient: RulesClient; - muteAll: SanitizedRule['muteAll']; - throttle: string | null | undefined; -}): Promise => { - if (muteAll && throttle !== NOTIFICATION_THROTTLE_NO_ACTIONS) { - await rulesClient.unmuteAll({ id }); - } else if (!muteAll && throttle === NOTIFICATION_THROTTLE_NO_ACTIONS) { - await rulesClient.muteAll({ id }); - } else { - // Do nothing, no-operation - } -}; - -/** - * Translate legacy action sidecar action to rule action - */ -export const getUpdatedActionsParams = ({ - rule, - ruleThrottle, - actions, - references, -}: { - rule: SanitizedRule; - ruleThrottle: string | null; - actions: LegacyRuleAlertSavedObjectAction[]; - references: SavedObjectReference[]; -}): Omit, 'id'> => { - const { id, ...restOfRule } = rule; - - const actionReference = references.reduce>( - (acc, reference) => { - acc[reference.name] = reference; - return acc; - }, - {} - ); - - if (isEmpty(actionReference)) { - throw new Error( - `An error occurred migrating legacy action for rule with id:${id}. Connector reference id not found.` - ); - } - // If rule has an action on any other interval (other than on every - // rule run), need to move the action info from the sidecar/legacy action - // into the rule itself - return { - ...restOfRule, - actions: actions.reduce((acc, action) => { - const { actionRef, action_type_id: actionTypeId, ...resOfAction } = action; - if (!actionReference[actionRef]) { - return acc; - } - return [ - ...acc, - { - ...resOfAction, - id: actionReference[actionRef].id, - actionTypeId, - }, - ]; - }, []), - throttle: transformToAlertThrottle(ruleThrottle), - notifyWhen: transformToNotifyWhen(ruleThrottle), - }; -}; - -/** - * Determines if rule needs to be migrated from legacy actions - * and returns necessary pieces for the updated rule - */ -export const legacyMigrate = async ({ - rulesClient, - savedObjectsClient, - rule, -}: LegacyMigrateParams): Promise | null | undefined> => - withSecuritySpan('legacyMigrate', async () => { - if (rule == null || rule.id == null) { - return rule; - } - /** - * On update / patch I'm going to take the actions as they are, better off taking rules client.find (siem.notification) result - * and putting that into the actions array of the rule, then set the rules onThrottle property, notifyWhen and throttle from null -> actual value (1hr etc..) - * Then use the rules client to delete the siem.notification - * Then with the legacy Rule Actions saved object type, just delete it. - */ - // find it using the references array, not params.ruleAlertId - const [siemNotification, legacyRuleActionsSO] = await Promise.all([ - rulesClient.find({ - options: { - filter: 'alert.attributes.alertTypeId:(siem.notifications)', - hasReference: { - type: 'alert', - id: rule.id, - }, - }, - }), - savedObjectsClient.find({ - type: legacyRuleActionsSavedObjectType, - hasReference: { - type: 'alert', - id: rule.id, - }, - }), - ]); - - const siemNotificationsExist = siemNotification != null && siemNotification.data.length > 0; - const legacyRuleNotificationSOsExist = - legacyRuleActionsSO != null && legacyRuleActionsSO.saved_objects.length > 0; - - // Assumption: if no legacy sidecar SO or notification rule types exist - // that reference the rule in question, assume rule actions are not legacy - if (!siemNotificationsExist && !legacyRuleNotificationSOsExist) { - return rule; - } - // If the legacy notification rule type ("siem.notification") exist, - // migration and cleanup are needed - if (siemNotificationsExist) { - await rulesClient.delete({ id: siemNotification.data[0].id }); - } - // If legacy notification sidecar ("siem-detection-engine-rule-actions") - // exist, migration and cleanup are needed - if (legacyRuleNotificationSOsExist) { - // Delete the legacy sidecar SO - await savedObjectsClient.delete( - legacyRuleActionsSavedObjectType, - legacyRuleActionsSO.saved_objects[0].id - ); - - // If "siem-detection-engine-rule-actions" notes that `ruleThrottle` is - // "no_actions" or "rule", rule has no actions or rule is set to run - // action on every rule run. In these cases, sidecar deletion is the only - // cleanup needed and updates to the "throttle" and "notifyWhen". "siem.notification" are - // not created for these action types - if ( - legacyRuleActionsSO.saved_objects[0].attributes.ruleThrottle === 'no_actions' || - legacyRuleActionsSO.saved_objects[0].attributes.ruleThrottle === 'rule' - ) { - return rule; - } - - // Use "legacyRuleActionsSO" instead of "siemNotification" as "siemNotification" is not created - // until a rule is run and added to task manager. That means that if by chance a user has a rule - // with actions which they have yet to enable, the actions would be lost. Instead, - // "legacyRuleActionsSO" is created on rule creation (pre 7.15) and we can rely on it to be there - const migratedRule = getUpdatedActionsParams({ - rule, - ruleThrottle: legacyRuleActionsSO.saved_objects[0].attributes.ruleThrottle, - actions: legacyRuleActionsSO.saved_objects[0].attributes.actions, - references: legacyRuleActionsSO.saved_objects[0].references, - }); - - await rulesClient.update({ - id: rule.id, - data: migratedRule, - }); - - return { id: rule.id, ...migratedRule }; - } - }); - -/** - * Converts an array of prepackaged rules to a Map with rule IDs as keys - * - * @param rules Array of prepackaged rules - * @returns Map - */ -export const prepackagedRulesToMap = (rules: AddPrepackagedRulesSchema[]) => - new Map(rules.map((rule) => [rule.rule_id, rule])); - -/** - * Converts an array of rules to a Map with rule IDs as keys - * - * @param rules Array of rules - * @returns Map - */ -export const rulesToMap = (rules: RuleAlertType[]) => - new Map(rules.map((rule) => [rule.params.ruleId, rule])); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/create_ndjson_prepackaged_rules.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/create_ndjson_prepackaged_rules.sh index 2c983fd7c9824..c69916770086c 100755 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/create_ndjson_prepackaged_rules.sh +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/create_ndjson_prepackaged_rules.sh @@ -8,10 +8,10 @@ # i=0; -for f in ../rules/prepackaged_rules/*.json ; do +for f in ../prebuilt_rules/content/prepackaged_rules/*.json ; do ((i++)); echo "converting $f" - cat ../rules/prepackaged_rules/windows_msxsl_network.json | tr -d '\n' | tr -d ' ' >> pre_packaged_rules.ndjson + cat ../prebuilt_rules/content/prepackaged_rules/windows_msxsl_network.json | tr -d '\n' | tr -d ' ' >> pre_packaged_rules.ndjson echo "" >> pre_packaged_rules.ndjson done echo "{\"exported_count\":$i,\"missing_rules\":[],\"missing_rules_count\":0}" >> pre_packaged_rules.ndjson diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/regen_prepackage_rules_index.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/regen_prepackage_rules_index.sh index 507e9815c4c74..6eb1b28dc8c2e 100755 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/regen_prepackage_rules_index.sh +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/regen_prepackage_rules_index.sh @@ -4,7 +4,7 @@ set -e # Regenerates the index.ts that contains all of the rules that are read in from json -PREPACKAGED_RULES_INDEX=../rules/prepackaged_rules/index.ts +PREPACKAGED_RULES_INDEX=../prebuilt_rules/content/prepackaged_rules/index.ts echo "/* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one @@ -18,7 +18,7 @@ echo "/* " > ${PREPACKAGED_RULES_INDEX} RULE_NUMBER=1 -for f in ../rules/prepackaged_rules/*.json ; do +for f in ../prebuilt_rules/content/prepackaged_rules/*.json ; do echo "import rule${RULE_NUMBER} from './$(basename -- "$f")';" >> ${PREPACKAGED_RULES_INDEX} RULE_NUMBER=$[$RULE_NUMBER +1] done @@ -26,7 +26,7 @@ done echo "export const rawRules = [" >> ${PREPACKAGED_RULES_INDEX} RULE_NUMBER=1 -for f in ../rules/prepackaged_rules/*.json ; do +for f in ../prebuilt_rules/content/prepackaged_rules/*.json ; do echo " rule${RULE_NUMBER}," >> ${PREPACKAGED_RULES_INDEX} RULE_NUMBER=$[$RULE_NUMBER +1] done diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/add_prepackaged_timelines.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/add_prepackaged_timelines.sh index 6de63e5910a37..48bd884294611 100755 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/add_prepackaged_timelines.sh +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/add_prepackaged_timelines.sh @@ -11,9 +11,9 @@ set -e ./check_env_variables.sh # Uses a defaults if no argument is specified -TIMELINES=${1:-../../rules/prepackaged_timelines/index.ndjson} +TIMELINES=${1:-../../prebuilt_rules/content/prepackaged_timelines/index.ndjson} -# Example to import and overwrite everything from ../rules/prepackaged_timelines/index.ndjson +# Example to import and overwrite everything from ../prebuilt_rules/content/prepackaged_timelines/index.ndjson # ./timelines/add_prepackaged_timelines.sh curl -s -k \ -H 'kbn-xsrf: 123' \ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/regen_prepackage_timelines_index.sh b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/regen_prepackage_timelines_index.sh index 8bd6101dfcc9a..a643a7bbcf838 100755 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/regen_prepackage_timelines_index.sh +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/timelines/regen_prepackage_timelines_index.sh @@ -4,7 +4,7 @@ set -e ./check_env_variables.sh # Regenerates the index.ts that contains all of the timelines that are read in from json -PREPACKAGED_TIMELINES_INDEX=../rules/prepackaged_timelines/index.ndjson +PREPACKAGED_TIMELINES_INDEX=../prebuilt_rules/content/prepackaged_timelines/index.ndjson # Clear existing content echo "" > ${PREPACKAGED_TIMELINES_INDEX} @@ -20,7 +20,7 @@ echo "/* // Do not hand edit. Run that script to regenerate package information instead " > ${PREPACKAGED_TIMELINES_INDEX} -for f in ../rules/prepackaged_timelines/*.json ; do +for f in ../prebuilt_rules/content/prepackaged_timelines/*.json ; do echo "converting $f" sed ':a;N;$!ba;s/\n/ /g' $f >> ${PREPACKAGED_TIMELINES_INDEX} done diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_events_query.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_events_query.ts index e3b05756709cc..a5a8c4963f227 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_events_query.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/build_events_query.ts @@ -8,10 +8,9 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { isEmpty } from 'lodash'; import type { Filter } from '@kbn/es-query'; import type { - FiltersOrUndefined, - TimestampOverrideOrUndefined, + RuleFilterArray, TimestampOverride, -} from '../../../../common/detection_engine/schemas/common/schemas'; +} from '../../../../common/detection_engine/rule_schema'; import { getQueryFilter } from './get_query_filter'; interface BuildEventsSearchQuery { @@ -25,7 +24,7 @@ interface BuildEventsSearchQuery { sortOrder?: estypes.SortOrder; searchAfterSortIds: estypes.SortResults | undefined; primaryTimestamp: TimestampOverride; - secondaryTimestamp: TimestampOverrideOrUndefined; + secondaryTimestamp: TimestampOverride | undefined; trackTotalHits?: boolean; } @@ -35,9 +34,9 @@ interface BuildEqlSearchRequestParams { from: string; to: string; size: number; - filters: FiltersOrUndefined; + filters: RuleFilterArray | undefined; primaryTimestamp: TimestampOverride; - secondaryTimestamp: TimestampOverrideOrUndefined; + secondaryTimestamp: TimestampOverride | undefined; runtimeMappings: estypes.MappingRuntimeFields | undefined; eventCategoryOverride?: string; timestampField?: string; @@ -54,7 +53,7 @@ const buildTimeRangeFilter = ({ to: string; from: string; primaryTimestamp: TimestampOverride; - secondaryTimestamp: TimestampOverrideOrUndefined; + secondaryTimestamp: TimestampOverride | undefined; }): estypes.QueryDslQueryContainer => { // The primaryTimestamp is always provided and will contain either the timestamp override field or `@timestamp` otherwise. // The secondaryTimestamp is `undefined` if diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts index f9a4c21898b09..7f565036abe3f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/bulk_create_ml_signals.ts @@ -16,7 +16,7 @@ import type { import type { GenericBulkCreateResponse } from '../rule_types/factories'; import type { Anomaly } from '../../machine_learning'; import type { BulkCreate, WrapHits } from './types'; -import type { CompleteRule, MachineLearningRuleParams } from '../schemas/rule_schemas'; +import type { CompleteRule, MachineLearningRuleParams } from '../rule_schema'; import { buildReasonMessageForMlAlert } from './reason_formatters'; import type { BaseFieldsLatest } from '../../../../common/detection_engine/schemas/alerts'; import type { IRuleExecutionLogForExecutors } from '../rule_monitoring'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts index 93e37c41c8ab3..fb0920bef9ade 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.test.ts @@ -12,8 +12,8 @@ import { getExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas import { DEFAULT_INDEX_PATTERN } from '../../../../../common/constants'; import { getIndexVersion } from '../../routes/index/get_index_version'; import { SIGNALS_TEMPLATE_VERSION } from '../../routes/index/get_signals_template'; -import type { EqlRuleParams } from '../../schemas/rule_schemas'; -import { getCompleteRuleMock, getEqlRuleParams } from '../../schemas/rule_schemas.mock'; +import type { EqlRuleParams } from '../../rule_schema'; +import { getCompleteRuleMock, getEqlRuleParams } from '../../rule_schema/mocks'; import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; import { eqlExecutor } from './eql'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts index 436ebec9c27c1..a67a404478b18 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/eql.ts @@ -32,7 +32,7 @@ import { getUnprocessedExceptionsWarnings, } from '../utils'; import { buildReasonMessageForEqlAlert } from '../reason_formatters'; -import type { CompleteRule, EqlRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, EqlRuleParams } from '../../rule_schema'; import { withSecuritySpan } from '../../../../utils/with_security_span'; import type { BaseFieldsLatest, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.test.ts index 49e2ef43282a2..ac6865554b36a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.test.ts @@ -9,12 +9,12 @@ import dateMath from '@kbn/datemath'; import type { RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; import { mlExecutor } from './ml'; -import { getCompleteRuleMock, getMlRuleParams } from '../../schemas/rule_schemas.mock'; +import { getCompleteRuleMock, getMlRuleParams } from '../../rule_schema/mocks'; import { getListClientMock } from '@kbn/lists-plugin/server/services/lists/list_client.mock'; import { findMlSignals } from '../find_ml_signals'; import { bulkCreateMlSignals } from '../bulk_create_ml_signals'; import { mlPluginServerMock } from '@kbn/ml-plugin/server/mocks'; -import type { MachineLearningRuleParams } from '../../schemas/rule_schemas'; +import type { MachineLearningRuleParams } from '../../rule_schema'; import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; jest.mock('../find_ml_signals'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts index ad49900078c4c..b7cb97f906bf0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/ml.ts @@ -15,7 +15,7 @@ import type { import type { ListClient } from '@kbn/lists-plugin/server'; import type { Filter } from '@kbn/es-query'; import { isJobStarted } from '../../../../../common/machine_learning/helpers'; -import type { CompleteRule, MachineLearningRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, MachineLearningRuleParams } from '../../rule_schema'; import { bulkCreateMlSignals } from '../bulk_create_ml_signals'; import { filterEventsAgainstList } from '../filters/filter_events_against_list'; import { findMlSignals } from '../find_ml_signals'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts index b2309bee8ad0a..52c0247b950db 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/query.ts @@ -21,7 +21,7 @@ import { getFilter } from '../get_filter'; import { searchAfterAndBulkCreate } from '../search_after_bulk_create'; import type { RuleRangeTuple, BulkCreate, WrapHits } from '../types'; import type { ITelemetryEventsSender } from '../../../telemetry/sender'; -import type { CompleteRule, UnifiedQueryRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, UnifiedQueryRuleParams } from '../../rule_schema'; import type { ExperimentalFeatures } from '../../../../../common/experimental_features'; import { buildReasonMessageForQueryAlert } from '../reason_formatters'; import { withSecuritySpan } from '../../../../utils/with_security_span'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threat_match.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threat_match.ts index 4f99412acb5c2..8ebf39867dea4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threat_match.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threat_match.ts @@ -18,7 +18,7 @@ import type { Filter } from '@kbn/es-query'; import type { RuleRangeTuple, BulkCreate, WrapHits } from '../types'; import type { ITelemetryEventsSender } from '../../../telemetry/sender'; import { createThreatSignals } from '../threat_mapping/create_threat_signals'; -import type { CompleteRule, ThreatRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, ThreatRuleParams } from '../../rule_schema'; import { withSecuritySpan } from '../../../../utils/with_security_span'; import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../common/constants'; import type { IRuleExecutionLogForExecutors } from '../../rule_monitoring'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts index 832ffa1e5b5c4..0e780d9709ab8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.test.ts @@ -11,10 +11,10 @@ import { getExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas import type { RuleExecutorServicesMock } from '@kbn/alerting-plugin/server/mocks'; import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; import { thresholdExecutor } from './threshold'; -import { getThresholdRuleParams, getCompleteRuleMock } from '../../schemas/rule_schemas.mock'; +import { getThresholdRuleParams, getCompleteRuleMock } from '../../rule_schema/mocks'; import { sampleEmptyAggsSearchResults } from '../__mocks__/es_results'; import { getThresholdTermsHash } from '../utils'; -import type { ThresholdRuleParams } from '../../schemas/rule_schemas'; +import type { ThresholdRuleParams } from '../../rule_schema'; import { createRuleDataClientMock } from '@kbn/rule-registry-plugin/server/rule_data_client/rule_data_client.mock'; import { TIMESTAMP } from '@kbn/rule-data-utils'; import { ruleExecutionLogMock } from '../../rule_monitoring/mocks'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts index ed82f7cdb1f8a..7a148e80282dc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/executors/threshold.ts @@ -16,7 +16,7 @@ import type { } from '@kbn/alerting-plugin/server'; import type { IRuleDataReader } from '@kbn/rule-registry-plugin/server'; import type { Filter } from '@kbn/es-query'; -import type { CompleteRule, ThresholdRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, ThresholdRuleParams } from '../../rule_schema'; import { getFilter } from '../get_filter'; import { bulkCreateThresholdSignals, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts index 521fdf1e5a595..33d710ed2ffa4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_filter.ts @@ -18,11 +18,8 @@ import type { } from '@kbn/alerting-plugin/server'; import type { Filter } from '@kbn/es-query'; import { assertUnreachable } from '../../../../common/utility_types'; -import type { - QueryOrUndefined, - SavedIdOrUndefined, - IndexOrUndefined, -} from '../../../../common/detection_engine/schemas/common/schemas'; +import type { IndexPatternArray, RuleQuery } from '../../../../common/detection_engine/rule_schema'; +import type { SavedIdOrUndefined } from '../../../../common/detection_engine/schemas/common/schemas'; import type { PartialFilter } from '../types'; import { withSecuritySpan } from '../../../utils/with_security_span'; import type { ESBoolQuery } from '../../../../common/typed_json'; @@ -32,10 +29,10 @@ interface GetFilterArgs { type: Type; filters: unknown | undefined; language: LanguageOrUndefined; - query: QueryOrUndefined; + query: RuleQuery | undefined; savedId: SavedIdOrUndefined; services: RuleExecutorServices; - index: IndexOrUndefined; + index: IndexPatternArray | undefined; exceptionFilter: Filter | undefined; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_query_filter.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_query_filter.ts index 58b13152bb64a..15477388839e4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_query_filter.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/get_query_filter.ts @@ -9,7 +9,7 @@ import type { Language } from '@kbn/securitysolution-io-ts-alerting-types'; import type { Filter, EsQueryConfig, DataViewBase } from '@kbn/es-query'; import { buildEsQuery } from '@kbn/es-query'; import type { ESBoolQuery } from '../../../../common/typed_json'; -import type { Index, Query } from '../../../../common/detection_engine/schemas/common'; +import type { IndexPatternArray, RuleQuery } from '../../../../common/detection_engine/rule_schema'; export const getQueryFilter = ({ query, @@ -18,10 +18,10 @@ export const getQueryFilter = ({ index, exceptionFilter, }: { - query: Query; + query: RuleQuery; language: Language; filters: unknown; - index: Index; + index: IndexPatternArray; exceptionFilter: Filter | undefined; }): ESBoolQuery => { const indexPattern: DataViewBase = { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts index ffd9e2b46d48f..5ae4aff3a6687 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.test.ts @@ -5,10 +5,7 @@ * 2.0. */ -import type { - RiskScore, - RiskScoreMappingOrUndefined, -} from '@kbn/securitysolution-io-ts-alerting-types'; +import type { RiskScore, RiskScoreMapping } from '@kbn/securitysolution-io-ts-alerting-types'; import { sampleDocRiskScore } from '../__mocks__/es_results'; import type { BuildRiskScoreFromMappingReturn } from './build_risk_score_from_mapping'; import { buildRiskScoreFromMapping } from './build_risk_score_from_mapping'; @@ -187,7 +184,7 @@ describe('buildRiskScoreFromMapping', () => { interface TestCase { fieldValue: unknown; scoreDefault: RiskScore; - scoreMapping: RiskScoreMappingOrUndefined; + scoreMapping: RiskScoreMapping | undefined; expected: BuildRiskScoreFromMappingReturn; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts index 9e875165cf469..e17c5b941cbb5 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_risk_score_from_mapping.ts @@ -5,23 +5,21 @@ * 2.0. */ -import type { - RiskScore, - RiskScoreMappingOrUndefined, -} from '@kbn/securitysolution-io-ts-alerting-types'; import { get } from 'lodash/fp'; -import type { Meta } from '../../../../../common/detection_engine/schemas/common/schemas'; + +import type { RiskScore, RiskScoreMapping } from '@kbn/securitysolution-io-ts-alerting-types'; +import type { RuleMetadata } from '../../../../../common/detection_engine/rule_schema'; import type { SignalSource } from '../types'; export interface BuildRiskScoreFromMappingProps { eventSource: SignalSource; riskScore: RiskScore; - riskScoreMapping: RiskScoreMappingOrUndefined; + riskScoreMapping: RiskScoreMapping | undefined; } export interface BuildRiskScoreFromMappingReturn { riskScore: RiskScore; - riskScoreMeta: Meta; // TODO: Stricter types + riskScoreMeta: RuleMetadata; // TODO: Stricter types } /** diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts index ae7247c01b1af..933a330a77098 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_rule_name_from_mapping.ts @@ -7,22 +7,23 @@ import * as t from 'io-ts'; import { get } from 'lodash/fp'; + import type { - Meta, - Name, - RuleNameOverrideOrUndefined, -} from '../../../../../common/detection_engine/schemas/common/schemas'; + RuleMetadata, + RuleName, + RuleNameOverride, +} from '../../../../../common/detection_engine/rule_schema'; import type { SignalSource } from '../types'; interface BuildRuleNameFromMappingProps { eventSource: SignalSource; - ruleName: Name; - ruleNameMapping: RuleNameOverrideOrUndefined; + ruleName: RuleName; + ruleNameMapping: RuleNameOverride | undefined; } interface BuildRuleNameFromMappingReturn { - ruleName: Name; - ruleNameMeta: Meta; // TODO: Stricter types + ruleName: RuleName; + ruleNameMeta: RuleMetadata; // TODO: Stricter types } export const buildRuleNameFromMapping = ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts index 75e53cdf0ae4c..875da0124b42f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.test.ts @@ -5,11 +5,7 @@ * 2.0. */ -import type { - Severity, - SeverityMappingOrUndefined, -} from '@kbn/securitysolution-io-ts-alerting-types'; - +import type { Severity, SeverityMapping } from '@kbn/securitysolution-io-ts-alerting-types'; import { sampleDocSeverity } from '../__mocks__/es_results'; import type { BuildSeverityFromMappingReturn } from './build_severity_from_mapping'; import { buildSeverityFromMapping } from './build_severity_from_mapping'; @@ -141,7 +137,7 @@ interface TestCase { fieldName?: string; fieldValue: unknown; severityDefault: Severity; - severityMapping: SeverityMappingOrUndefined; + severityMapping: SeverityMapping | undefined; expected: BuildSeverityFromMappingReturn; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts index 4a57467040b5e..53691eeb98814 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/mappings/build_severity_from_mapping.ts @@ -7,25 +7,25 @@ import { get } from 'lodash/fp'; +import { Severity } from '@kbn/securitysolution-io-ts-alerting-types'; import type { - Severity, + SeverityMapping, SeverityMappingItem, - SeverityMappingOrUndefined, } from '@kbn/securitysolution-io-ts-alerting-types'; -import { severity as SeverityIOTS } from '@kbn/securitysolution-io-ts-alerting-types'; -import type { Meta } from '../../../../../common/detection_engine/schemas/common/schemas'; + +import type { RuleMetadata } from '../../../../../common/detection_engine/rule_schema'; import type { SearchTypes } from '../../../../../common/detection_engine/types'; import type { SignalSource } from '../types'; export interface BuildSeverityFromMappingProps { eventSource: SignalSource; severity: Severity; - severityMapping: SeverityMappingOrUndefined; + severityMapping: SeverityMapping | undefined; } export interface BuildSeverityFromMappingReturn { severity: Severity; - severityMeta: Meta; // TODO: Stricter types + severityMeta: RuleMetadata; // TODO: Stricter types } const severitySortMapping = { @@ -66,7 +66,7 @@ export const buildSeverityFromMapping = ({ } }); - if (severityMatch != null && SeverityIOTS.is(severityMatch.severity)) { + if (severityMatch != null && Severity.is(severityMatch.severity)) { return overriddenSeverity(severityMatch.severity, severityMatch.field); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/preview/alert_instance_factory_stub.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/preview/alert_instance_factory_stub.ts index a3cf4ebc95d7c..1b947b1be08a2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/preview/alert_instance_factory_stub.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/preview/alert_instance_factory_stub.ts @@ -11,7 +11,7 @@ import type { RuleTypeState, } from '@kbn/alerting-plugin/common'; import { Alert } from '@kbn/alerting-plugin/server/alert'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleParams } from '../../rule_schema'; export const alertInstanceFactoryStub = < TParams extends RuleParams, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_data_view.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_data_view.ts index 3cbe4d4b1c980..293d853f1d2ad 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_data_view.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_data_view.ts @@ -12,7 +12,7 @@ import type { QueryRuleParams, ThreatRuleParams, ThresholdRuleParams, -} from '../../schemas/rule_schemas'; +} from '../../rule_schema'; /** * This extracts the "dataViewId" and returns it as a saved object reference. diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.test.ts index 68d262961bfa1..db86d90598be7 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.test.ts @@ -5,13 +5,14 @@ * 2.0. */ -import { extractExceptionsList } from './extract_exceptions_list'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import type { RuleParams } from '../../schemas/rule_schemas'; import { EXCEPTION_LIST_NAMESPACE, EXCEPTION_LIST_NAMESPACE_AGNOSTIC, } from '@kbn/securitysolution-list-constants'; + +import type { RuleParams } from '../../rule_schema'; +import { extractExceptionsList } from './extract_exceptions_list'; import { EXCEPTIONS_SAVED_OBJECT_REFERENCE_NAME } from './utils/constants'; describe('extract_exceptions_list', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.ts index 87e607bb3b9a1..010fd04923159 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_exceptions_list.ts @@ -7,7 +7,7 @@ import type { Logger, SavedObjectReference } from '@kbn/core/server'; import { getSavedObjectType } from '@kbn/securitysolution-list-utils'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleParams } from '../../rule_schema'; import { getSavedObjectNamePatternForExceptionsList } from './utils'; /** diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.test.ts index 76325e187b005..5d27540773641 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.test.ts @@ -6,12 +6,13 @@ */ import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { extractReferences } from './extract_references'; -import type { RuleParams } from '../../schemas/rule_schemas'; import { EXCEPTION_LIST_NAMESPACE, EXCEPTION_LIST_NAMESPACE_AGNOSTIC, } from '@kbn/securitysolution-list-constants'; + +import type { RuleParams } from '../../rule_schema'; +import { extractReferences } from './extract_references'; import { EXCEPTIONS_SAVED_OBJECT_REFERENCE_NAME } from './utils/constants'; describe('extract_references', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.ts index 9843223b37e89..91ceb32edfe35 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/extract_references.ts @@ -8,7 +8,7 @@ import type { Logger } from '@kbn/core/server'; import type { RuleParamsAndRefs } from '@kbn/alerting-plugin/server'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleParams } from '../../rule_schema'; import { isMachineLearningParams } from '../utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.test.ts index 4d086970e458e..d653591493a3a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.test.ts @@ -8,8 +8,9 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import type { SavedObjectReference } from '@kbn/core/server'; import { EXCEPTION_LIST_NAMESPACE } from '@kbn/securitysolution-list-constants'; + +import type { RuleParams } from '../../rule_schema'; import { injectExceptionsReferences } from './inject_exceptions_list'; -import type { RuleParams } from '../../schemas/rule_schemas'; import { EXCEPTIONS_SAVED_OBJECT_REFERENCE_NAME } from './utils/constants'; describe('inject_exceptions_list', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.ts index 84a2c30c2e7ee..3baab73f1e50f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_exceptions_list.ts @@ -6,7 +6,7 @@ */ import type { Logger, SavedObjectReference } from '@kbn/core/server'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleParams } from '../../rule_schema'; import { getSavedObjectReferenceForExceptionsList, logMissingSavedObjectError } from './utils'; /** diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.test.ts index 3d7b17e5b6e89..f0dba726c712c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.test.ts @@ -8,8 +8,9 @@ import { loggingSystemMock } from '@kbn/core/server/mocks'; import type { SavedObjectReference } from '@kbn/core/server'; import { EXCEPTION_LIST_NAMESPACE } from '@kbn/securitysolution-list-constants'; + +import type { RuleParams } from '../../rule_schema'; import { injectReferences } from './inject_references'; -import type { RuleParams } from '../../schemas/rule_schemas'; import { EXCEPTIONS_SAVED_OBJECT_REFERENCE_NAME } from './utils/constants'; describe('inject_references', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.ts index bae0e0749a62b..40ad3cf3678a9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/inject_references.ts @@ -6,7 +6,7 @@ */ import type { Logger, SavedObjectReference } from '@kbn/core/server'; -import type { RuleParams } from '../../schemas/rule_schemas'; +import type { RuleParams } from '../../rule_schema'; import { isMachineLearningParams } from '../utils'; import { injectExceptionsReferences } from './inject_exceptions_list'; import { injectDataViewReferences } from './inject_data_view'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/utils/log_missing_saved_object_error.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/utils/log_missing_saved_object_error.ts index 203d6ce342d4c..3293508e035c4 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/utils/log_missing_saved_object_error.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/saved_object_references/utils/log_missing_saved_object_error.ts @@ -6,7 +6,7 @@ */ import type { Logger } from '@kbn/core/server'; -import type { RuleParams } from '../../../schemas/rule_schemas'; +import type { RuleParams } from '../../../rule_schema'; type Keys = keyof RuleParams; type PossibleRuleParamValues = RuleParams[Keys]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts index 613104bc7604b..489237ea1b2c9 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/search_after_bulk_create.test.ts @@ -23,12 +23,12 @@ import type { SearchListItemArraySchema } from '@kbn/securitysolution-io-ts-list import { getSearchListItemResponseMock } from '@kbn/lists-plugin/common/schemas/response/search_list_item_schema.mock'; import { getRuleRangeTuples } from './utils'; import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; -import { getCompleteRuleMock, getQueryRuleParams } from '../schemas/rule_schemas.mock'; +import { getCompleteRuleMock, getQueryRuleParams } from '../rule_schema/mocks'; import { bulkCreateFactory } from '../rule_types/factories/bulk_create_factory'; import { wrapHitsFactory } from '../rule_types/factories/wrap_hits_factory'; import { ruleExecutionLogMock } from '../rule_monitoring/mocks'; import type { BuildReasonMessage } from './reason_formatters'; -import type { QueryRuleParams } from '../schemas/rule_schemas'; +import type { QueryRuleParams } from '../rule_schema'; import { createPersistenceServicesMock } from '@kbn/rule-registry-plugin/server/utils/create_persistence_rule_type_wrapper.mock'; import type { PersistenceServices } from '@kbn/rule-registry-plugin/server'; import { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_search_after.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_search_after.ts index 0a0534e887c5e..04fec0e21a467 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_search_after.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/single_search_after.ts @@ -14,10 +14,7 @@ import type { import type { SignalSearchResponse, SignalSource } from './types'; import { buildEventsSearchQuery } from './build_events_query'; import { createErrorsFromShard, makeFloatString } from './utils'; -import type { - TimestampOverride, - TimestampOverrideOrUndefined, -} from '../../../../common/detection_engine/schemas/common/schemas'; +import type { TimestampOverride } from '../../../../common/detection_engine/rule_schema'; import { withSecuritySpan } from '../../../utils/with_security_span'; import type { IRuleExecutionLogForExecutors } from '../rule_monitoring'; @@ -33,7 +30,7 @@ interface SingleSearchAfterParams { sortOrder?: estypes.SortOrder; filter: estypes.QueryDslQueryContainer; primaryTimestamp: TimestampOverride; - secondaryTimestamp: TimestampOverrideOrUndefined; + secondaryTimestamp: TimestampOverride | undefined; trackTotalHits?: boolean; runtimeMappings: estypes.MappingRuntimeFields | undefined; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts index f9ce4479dc3ac..03175fa0dda11 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threat_mapping/types.ts @@ -35,7 +35,7 @@ import type { SignalsEnrichment, WrapHits, } from '../types'; -import type { CompleteRule, ThreatRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, ThreatRuleParams } from '../../rule_schema'; import type { IRuleExecutionLogForExecutors } from '../../rule_monitoring'; export type SortOrderOrUndefined = 'asc' | 'desc' | undefined; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/build_threshold_aggregation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/build_threshold_aggregation.ts index f0b808e743772..1bc2b18860722 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/build_threshold_aggregation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/build_threshold_aggregation.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { ThresholdNormalized } from '../../../../../common/detection_engine/schemas/common'; +import type { ThresholdNormalized } from '../../../../../common/detection_engine/rule_schema'; import { shouldFilterByCardinality } from './utils'; export const buildThresholdMultiBucketAggregation = ({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.test.ts index d92bd5b360b2d..1fa0baaedfa13 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { ThresholdNormalized } from '../../../../../common/detection_engine/schemas/common/schemas'; +import type { ThresholdNormalized } from '../../../../../common/detection_engine/rule_schema'; import { calculateThresholdSignalUuid } from '../utils'; import { getTransformedHits } from './bulk_create_threshold_signals'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts index 758e69553bb4b..22ebcf8c1ced0 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/bulk_create_threshold_signals.ts @@ -12,12 +12,12 @@ import type { AlertInstanceState, RuleExecutorServices, } from '@kbn/alerting-plugin/server'; -import type { ThresholdNormalized } from '../../../../../common/detection_engine/schemas/common/schemas'; +import type { ThresholdNormalized } from '../../../../../common/detection_engine/rule_schema'; import type { GenericBulkCreateResponse } from '../../rule_types/factories/bulk_create_factory'; import { calculateThresholdSignalUuid } from '../utils'; import { buildReasonMessageForThresholdAlert } from '../reason_formatters'; import type { ThresholdSignalHistory, BulkCreate, WrapHits } from '../types'; -import type { CompleteRule, ThresholdRuleParams } from '../../schemas/rule_schemas'; +import type { CompleteRule, ThresholdRuleParams } from '../../rule_schema'; import type { BaseFieldsLatest } from '../../../../../common/detection_engine/schemas/alerts'; import type { ThresholdBucket } from './types'; import { createEnrichEventsFunction } from '../enrichments'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/find_threshold_signals.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/find_threshold_signals.ts index 63e293401a77a..dba72e0560734 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/find_threshold_signals.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/find_threshold_signals.ts @@ -17,8 +17,7 @@ import type { ESBoolQuery } from '../../../../../common/typed_json'; import type { ThresholdNormalized, TimestampOverride, - TimestampOverrideOrUndefined, -} from '../../../../../common/detection_engine/schemas/common/schemas'; +} from '../../../../../common/detection_engine/rule_schema'; import { singleSearchAfter } from '../single_search_after'; import { buildThresholdMultiBucketAggregation, @@ -43,7 +42,7 @@ interface FindThresholdSignalsParams { threshold: ThresholdNormalized; runtimeMappings: estypes.MappingRuntimeFields | undefined; primaryTimestamp: TimestampOverride; - secondaryTimestamp: TimestampOverrideOrUndefined; + secondaryTimestamp: TimestampOverride | undefined; aggregatableTimestampField: string; } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/utils.ts index bcb61f04cda0d..1e1ecbc12b444 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/threshold/utils.ts @@ -8,7 +8,7 @@ import type { ThresholdNormalized, ThresholdWithCardinality, -} from '../../../../../common/detection_engine/schemas/common'; +} from '../../../../../common/detection_engine/rule_schema'; export const shouldFilterByCardinality = ( threshold: ThresholdNormalized diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts index f786a28b50044..e8dd19fd2ff8e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/types.ts @@ -26,7 +26,7 @@ import type { EqlSequence, } from '../../../../common/detection_engine/types'; import type { ITelemetryEventsSender } from '../../telemetry/sender'; -import type { RuleParams } from '../schemas/rule_schemas'; +import type { RuleParams } from '../rule_schema'; import type { GenericBulkCreateResponse } from '../rule_types/factories'; import type { BuildReasonMessage } from './reason_formatters'; import type { @@ -35,7 +35,7 @@ import type { WrappedFieldsLatest, } from '../../../../common/detection_engine/schemas/alerts'; import type { IRuleExecutionLogForExecutors } from '../rule_monitoring'; -import type { FullResponseSchema } from '../../../../common/detection_engine/schemas/request'; +import type { RuleResponse } from '../../../../common/detection_engine/rule_schema'; import type { EnrichEvents } from './enrichments/types'; export interface ThresholdResult { @@ -187,7 +187,7 @@ export interface Signal { _meta?: { version: number; }; - rule: FullResponseSchema; + rule: RuleResponse; /** * @deprecated Use "parents" instead of "parent" */ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts index 24b5b068d5689..c8a98aeabd82a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/signals/utils.ts @@ -31,10 +31,8 @@ import type { } from '@kbn/alerting-plugin/server'; import { parseDuration } from '@kbn/alerting-plugin/server'; import type { ExceptionListClient, ListClient, ListPluginSetup } from '@kbn/lists-plugin/server'; -import type { - TimestampOverride, - Privilege, -} from '../../../../common/detection_engine/schemas/common'; +import type { TimestampOverride } from '../../../../common/detection_engine/rule_schema'; +import type { Privilege } from '../../../../common/detection_engine/schemas/common'; import { RuleExecutionStatus } from '../../../../common/detection_engine/rule_monitoring'; import type { BulkResponseErrorAggregation, @@ -57,7 +55,7 @@ import type { RuleParams, ThreatRuleParams, ThresholdRuleParams, -} from '../schemas/rule_schemas'; +} from '../rule_schema'; import type { BaseHit, SearchTypes } from '../../../../common/detection_engine/types'; import type { IRuleExecutionLogForExecutors } from '../rule_monitoring'; import { withSecuritySpan } from '../../../utils/with_security_span'; diff --git a/x-pack/plugins/security_solution/server/lib/machine_learning/__mocks__/authz.ts b/x-pack/plugins/security_solution/server/lib/machine_learning/__mocks__/authz.ts new file mode 100644 index 0000000000000..33ab06ba67a8f --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/machine_learning/__mocks__/authz.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mlPluginServerMock } from '@kbn/ml-plugin/server/mocks'; + +export const mlServicesMock = mlPluginServerMock; + +const mockValidateRuleType = jest.fn().mockResolvedValue({ valid: true, message: undefined }); + +export const buildMlAuthz = jest.fn().mockReturnValue({ validateRuleType: mockValidateRuleType }); diff --git a/x-pack/plugins/security_solution/server/lib/machine_learning/mocks.ts b/x-pack/plugins/security_solution/server/lib/machine_learning/mocks.ts index b76dba6d072ef..2a46163515958 100644 --- a/x-pack/plugins/security_solution/server/lib/machine_learning/mocks.ts +++ b/x-pack/plugins/security_solution/server/lib/machine_learning/mocks.ts @@ -8,13 +8,3 @@ import { mlPluginServerMock } from '@kbn/ml-plugin/server/mocks'; export const mlServicesMock = mlPluginServerMock; - -const mockValidateRuleType = jest.fn().mockResolvedValue({ valid: true, message: undefined }); -const createBuildMlAuthzMock = () => - jest.fn().mockReturnValue({ validateRuleType: mockValidateRuleType }); - -export const mlAuthzMock = { - create: () => ({ - buildMlAuthz: createBuildMlAuthzMock(), - }), -}; diff --git a/x-pack/plugins/security_solution/server/lib/timeline/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/timeline/__mocks__/request_responses.ts index 64bee51ae8965..9d32145717de6 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/__mocks__/request_responses.ts @@ -41,7 +41,9 @@ export const getExportTimelinesRequest = () => }); export const getImportTimelinesRequest = async (fileName?: string) => { - const dir = resolve(join(__dirname, '../../detection_engine/rules/prepackaged_timelines')); + const dir = resolve( + join(__dirname, '../../detection_engine/prebuilt_rules/content/prepackaged_timelines') + ); const file = fileName ?? 'index.ndjson'; const dataPath = path.join(dir, file); const readable = await getReadables(dataPath); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.ts b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.ts index 69d1b672ddcf4..b003a54657feb 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines/helpers.ts @@ -25,7 +25,10 @@ export const installPrepackagedTimelines = async ( ): Promise => { let readStream; const dir = resolve( - join(__dirname, filePath ?? '../../../../detection_engine/rules/prepackaged_timelines') + join( + __dirname, + filePath ?? '../../../../detection_engine/prebuilt_rules/content/prepackaged_timelines' + ) ); const file = fileName ?? 'index.ndjson'; const dataPath = path.join(dir, file); diff --git a/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts b/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts index f742a5c6171c0..bf260085b5a75 100644 --- a/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts +++ b/x-pack/plugins/security_solution/server/lib/timeline/utils/check_timelines_status.ts @@ -66,7 +66,10 @@ export const checkTimelinesStatus = async ( timeline: TimelineSavedObject[]; }; const dir = resolve( - join(__dirname, filePath ?? '../../detection_engine/rules/prepackaged_timelines') + join( + __dirname, + filePath ?? '../../detection_engine/prebuilt_rules/content/prepackaged_timelines' + ) ); const file = fileName ?? 'index.ndjson'; const dataPath = path.join(dir, file); diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index a71048462b5e6..df584c8d64e96 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -80,9 +80,10 @@ import type { CreateQueryRuleAdditionalOptions, } from './lib/detection_engine/rule_types/types'; // eslint-disable-next-line no-restricted-imports -import { legacyRulesNotificationAlertType } from './lib/detection_engine/notifications/legacy_rules_notification_alert_type'; -// eslint-disable-next-line no-restricted-imports -import { legacyIsNotificationAlertExecutor } from './lib/detection_engine/notifications/legacy_types'; +import { + legacyRulesNotificationAlertType, + legacyIsNotificationAlertExecutor, +} from './lib/detection_engine/rule_actions_legacy'; import { createSecurityRuleTypeWrapper } from './lib/detection_engine/rule_types/create_security_rule_type_wrapper'; import { RequestContextFactory } from './request_context_factory'; diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index f9d2177aa9e10..df67c6ddce423 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -10,14 +10,17 @@ import type { IRuleDataClient, RuleDataPluginService } from '@kbn/rule-registry- import type { SecuritySolutionPluginRouter } from '../types'; -import { createRulesRoute } from '../lib/detection_engine/routes/rules/create_rules_route'; +import { registerFleetIntegrationsRoutes } from '../lib/detection_engine/fleet_integrations'; +import { registerPrebuiltRulesRoutes } from '../lib/detection_engine/prebuilt_rules'; +// eslint-disable-next-line no-restricted-imports +import { registerLegacyRuleActionsRoutes } from '../lib/detection_engine/rule_actions_legacy'; +import { registerRuleExceptionsRoutes } from '../lib/detection_engine/rule_exceptions'; +import { registerRuleManagementRoutes } from '../lib/detection_engine/rule_management'; +import { registerRuleMonitoringRoutes } from '../lib/detection_engine/rule_monitoring'; +import { registerRulePreviewRoutes } from '../lib/detection_engine/rule_preview'; + import { createIndexRoute } from '../lib/detection_engine/routes/index/create_index_route'; import { readIndexRoute } from '../lib/detection_engine/routes/index/read_index_route'; -import { readRulesRoute } from '../lib/detection_engine/routes/rules/read_rules_route'; -import { findRulesRoute } from '../lib/detection_engine/routes/rules/find_rules_route'; -import { deleteRulesRoute } from '../lib/detection_engine/routes/rules/delete_rules_route'; -import { updateRulesRoute } from '../lib/detection_engine/routes/rules/update_rules_route'; -import { patchRulesRoute } from '../lib/detection_engine/routes/rules/patch_rules_route'; import { createSignalsMigrationRoute } from '../lib/detection_engine/routes/signals/create_signals_migration_route'; import { deleteSignalsMigrationRoute } from '../lib/detection_engine/routes/signals/delete_signals_migration_route'; import { finalizeSignalsMigrationRoute } from '../lib/detection_engine/routes/signals/finalize_signals_migration_route'; @@ -25,18 +28,7 @@ import { getSignalsMigrationStatusRoute } from '../lib/detection_engine/routes/s import { querySignalsRoute } from '../lib/detection_engine/routes/signals/query_signals_route'; import { setSignalsStatusRoute } from '../lib/detection_engine/routes/signals/open_close_signals_route'; import { deleteIndexRoute } from '../lib/detection_engine/routes/index/delete_index_route'; -import { readTagsRoute } from '../lib/detection_engine/routes/tags/read_tags_route'; import { readPrivilegesRoute } from '../lib/detection_engine/routes/privileges/read_privileges_route'; -import { addPrepackedRulesRoute } from '../lib/detection_engine/routes/rules/add_prepackaged_rules_route'; -import { createRulesBulkRoute } from '../lib/detection_engine/routes/rules/create_rules_bulk_route'; -import { updateRulesBulkRoute } from '../lib/detection_engine/routes/rules/update_rules_bulk_route'; -import { patchRulesBulkRoute } from '../lib/detection_engine/routes/rules/patch_rules_bulk_route'; -import { deleteRulesBulkRoute } from '../lib/detection_engine/routes/rules/delete_rules_bulk_route'; -import { performBulkActionRoute } from '../lib/detection_engine/routes/rules/perform_bulk_action_route'; -import { importRulesRoute } from '../lib/detection_engine/routes/rules/import_rules_route'; -import { exportRulesRoute } from '../lib/detection_engine/routes/rules/export_rules_route'; -import { registerRuleMonitoringRoutes } from '../lib/detection_engine/rule_monitoring'; -import { getPrepackagedRulesStatusRoute } from '../lib/detection_engine/routes/rules/get_prepackaged_rules_status_route'; import { createTimelinesRoute, deleteTimelinesRoute, @@ -59,21 +51,15 @@ import type { SetupPlugins, StartPlugins } from '../plugin'; import type { ConfigType } from '../config'; import type { ITelemetryEventsSender } from '../lib/telemetry/sender'; import { installPrepackedTimelinesRoute } from '../lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; -import { previewRulesRoute } from '../lib/detection_engine/routes/rules/preview_rules_route'; import type { CreateRuleOptions, CreateSecurityRuleTypeWrapperProps, } from '../lib/detection_engine/rule_types/types'; -// eslint-disable-next-line no-restricted-imports -import { legacyCreateLegacyNotificationRoute } from '../lib/detection_engine/routes/rules/legacy_create_legacy_notification'; import { createSourcererDataViewRoute, getSourcererDataViewRoute } from '../lib/sourcerer/routes'; import type { ITelemetryReceiver } from '../lib/telemetry/receiver'; import { telemetryDetectionRulesPreviewRoute } from '../lib/detection_engine/routes/telemetry/telemetry_detection_rules_preview_route'; import { readAlertsIndexExistsRoute } from '../lib/detection_engine/routes/index/read_alerts_index_exists_route'; -import { getInstalledIntegrationsRoute } from '../lib/detection_engine/routes/fleet/get_installed_integrations/get_installed_integrations_route'; import { registerResolverRoutes } from '../endpoint/routes/resolver'; -import { findRuleExceptionReferencesRoute } from '../lib/detection_engine/routes/rules/find_rule_exceptions_route'; -import { createRuleExceptionsRoute } from '../lib/detection_engine/routes/rules/create_rule_exceptions_route'; import { createEsIndexRoute, createPrebuiltSavedObjectsRoute, @@ -86,6 +72,7 @@ import { readPrebuiltDevToolContentRoute, restartTransformRoute, } from '../lib/risk_score/routes'; + export const initRoutes = ( router: SecuritySolutionPluginRouter, config: ConfigType, @@ -102,15 +89,13 @@ export const initRoutes = ( previewRuleDataClient: IRuleDataClient, previewTelemetryReceiver: ITelemetryReceiver ) => { - // Detection Engine Rule routes that have the REST endpoints of /api/detection_engine/rules - // All REST rule creation, deletion, updating, etc - createRulesRoute(router, ml); - readRulesRoute(router, logger); - updateRulesRoute(router, ml); - patchRulesRoute(router, ml); - deleteRulesRoute(router); - findRulesRoute(router, logger); - previewRulesRoute( + registerFleetIntegrationsRoutes(router, logger); + registerLegacyRuleActionsRoutes(router, logger); + registerPrebuiltRulesRoutes(router, config, security); + registerRuleExceptionsRoutes(router); + registerRuleManagementRoutes(router, config, ml, logger); + registerRuleMonitoringRoutes(router); + registerRulePreviewRoutes( router, config, ml, @@ -121,29 +106,11 @@ export const initRoutes = ( getStartServices, logger ); - createRuleExceptionsRoute(router); - - // Once we no longer have the legacy notifications system/"side car actions" this should be removed. - legacyCreateLegacyNotificationRoute(router, logger); - - addPrepackedRulesRoute(router); - getPrepackagedRulesStatusRoute(router, config, security); - createRulesBulkRoute(router, ml, logger); - updateRulesBulkRoute(router, ml, logger); - patchRulesBulkRoute(router, ml, logger); - deleteRulesBulkRoute(router, logger); - performBulkActionRoute(router, ml, logger); - registerResolverRoutes(router, getStartServices, config); - - registerRuleMonitoringRoutes(router); - getInstalledIntegrationsRoute(router, logger); + registerResolverRoutes(router, getStartServices, config); createTimelinesRoute(router, config, security); patchTimelinesRoute(router, config, security); - importRulesRoute(router, config, ml); - exportRulesRoute(router, config, logger); - findRuleExceptionReferencesRoute(router); importTimelinesRoute(router, config, security); exportTimelinesRoute(router, config, security); @@ -177,9 +144,6 @@ export const initRoutes = ( readAlertsIndexExistsRoute(router); deleteIndexRoute(router); - // Detection Engine tags routes that have the REST endpoints of /api/detection_engine/tags - readTagsRoute(router); - // Privileges API to get the generic user privileges readPrivilegesRoute(router, hasEncryptionKey); diff --git a/x-pack/plugins/security_solution/server/saved_objects.ts b/x-pack/plugins/security_solution/server/saved_objects.ts index 225c0ad453a3d..bc1d86add3767 100644 --- a/x-pack/plugins/security_solution/server/saved_objects.ts +++ b/x-pack/plugins/security_solution/server/saved_objects.ts @@ -9,9 +9,9 @@ import type { CoreSetup } from '@kbn/core/server'; import { noteType, pinnedEventType, timelineType } from './lib/timeline/saved_object_mappings'; // eslint-disable-next-line no-restricted-imports -import { legacyType as legacyRuleActionsType } from './lib/detection_engine/rule_actions/legacy_saved_object_mappings'; +import { legacyType as legacyRuleActionsType } from './lib/detection_engine/rule_actions_legacy'; import { ruleExecutionType } from './lib/detection_engine/rule_monitoring'; -import { ruleAssetType } from './lib/detection_engine/rules/rule_asset/rule_asset_saved_object_mappings'; +import { ruleAssetType } from './lib/detection_engine/prebuilt_rules/logic/rule_asset/rule_asset_saved_object_mappings'; import { type as signalsMigrationType } from './lib/detection_engine/migrations/saved_objects'; import { exceptionsArtifactType, diff --git a/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_id_to_enabled_map.ts b/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_id_to_enabled_map.ts index cffe536549e9c..2a6a1e0b090c7 100644 --- a/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_id_to_enabled_map.ts +++ b/x-pack/plugins/security_solution/server/usage/detections/rules/transform_utils/get_rule_id_to_enabled_map.ts @@ -7,7 +7,7 @@ import type { SavedObjectsFindResult } from '@kbn/core/server'; // eslint-disable-next-line no-restricted-imports -import type { LegacyIRuleActionsAttributesSavedObjectAttributes } from '../../../../lib/detection_engine/rule_actions/legacy_types'; +import type { LegacyIRuleActionsAttributesSavedObjectAttributes } from '../../../../lib/detection_engine/rule_actions_legacy'; export const getRuleIdToEnabledMap = ( legacyRuleActions: Array< diff --git a/x-pack/plugins/security_solution/server/usage/get_internal_saved_objects_client.ts b/x-pack/plugins/security_solution/server/usage/get_internal_saved_objects_client.ts index 85fe139aa36c9..bb39b9c320b20 100644 --- a/x-pack/plugins/security_solution/server/usage/get_internal_saved_objects_client.ts +++ b/x-pack/plugins/security_solution/server/usage/get_internal_saved_objects_client.ts @@ -9,7 +9,7 @@ import type { CoreSetup, SavedObjectsClientContract } from '@kbn/core/server'; import { SAVED_OBJECT_TYPES } from '@kbn/cases-plugin/common/constants'; // eslint-disable-next-line no-restricted-imports -import { legacyRuleActionsSavedObjectType } from '../lib/detection_engine/rule_actions/legacy_saved_object_mappings'; +import { legacyRuleActionsSavedObjectType } from '../lib/detection_engine/rule_actions_legacy'; export async function getInternalSavedObjectsClient( core: CoreSetup diff --git a/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts b/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts index 8a3eba441d269..9b7140d734d16 100644 --- a/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts +++ b/x-pack/plugins/security_solution/server/usage/queries/legacy_get_rule_actions.ts @@ -12,10 +12,10 @@ import type { SavedObjectsCreatePointInTimeFinderOptions, } from '@kbn/core/server'; // eslint-disable-next-line no-restricted-imports -import type { LegacyIRuleActionsAttributesSavedObjectAttributes } from '../../lib/detection_engine/rule_actions/legacy_types'; +import type { LegacyIRuleActionsAttributesSavedObjectAttributes } from '../../lib/detection_engine/rule_actions_legacy'; // eslint-disable-next-line no-restricted-imports -import { legacyRuleActionsSavedObjectType } from '../../lib/detection_engine/rule_actions/legacy_saved_object_mappings'; +import { legacyRuleActionsSavedObjectType } from '../../lib/detection_engine/rule_actions_legacy'; export interface LegacyGetRuleActionsOptions { savedObjectsClient: SavedObjectsClientContract; diff --git a/x-pack/plugins/security_solution/server/usage/types.ts b/x-pack/plugins/security_solution/server/usage/types.ts index a6db2e3d71e91..1c97dffab5bb1 100644 --- a/x-pack/plugins/security_solution/server/usage/types.ts +++ b/x-pack/plugins/security_solution/server/usage/types.ts @@ -7,7 +7,7 @@ import type { CoreSetup, Logger } from '@kbn/core/server'; import type { SanitizedRule } from '@kbn/alerting-plugin/common'; -import type { RuleParams } from '../lib/detection_engine/schemas/rule_schemas'; +import type { RuleParams } from '../lib/detection_engine/rule_schema'; import type { SetupPlugins } from '../plugin'; export type CollectorDependencies = { diff --git a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts index cd1914df38561..e04ecd40ef04a 100644 --- a/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts +++ b/x-pack/plugins/security_solution/server/utils/read_stream/create_stream_from_ndjson.ts @@ -9,7 +9,7 @@ import { Transform } from 'stream'; import { has, isString } from 'lodash/fp'; import { createMapStream, createFilterStream } from '@kbn/utils'; -import type { ImportRulesSchema } from '../../../common/detection_engine/schemas/request/import_rules_schema'; +import type { RuleToImport } from '../../../common/detection_engine/rule_management'; export interface RulesObjectsExportResultDetails { /** number of successfully exported objects */ @@ -29,7 +29,7 @@ export const parseNdjsonStrings = (): Transform => { }; export const filterExportedCounts = (): Transform => { - return createFilterStream( + return createFilterStream( (obj) => obj != null && !has('exported_count', obj) ); }; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index e42dd37ccb292..ead29476ba7f2 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -25600,7 +25600,7 @@ "xpack.securitySolution.eventFilters.showingTotal": "Affichage de {total} {total, plural, one {filtre d'événement} other {filtres d'événement}}", "xpack.securitySolution.eventsTab.unit": "{totalCount, plural, =1 {alerte externe} other {alertes externes}}", "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, =1 {événement} other {événements}}", - "xpack.securitySolution.exceptions.dissasociateListSuccessText": "La liste d'exceptions ({id}) a été retirée avec succès", + "xpack.securitySolution.exceptions.disassociateListSuccessText": "La liste d'exceptions ({id}) a été retirée avec succès", "xpack.securitySolution.exceptions.failedLoadPolicies": "Une erreur s'est produite lors du chargement des politiques : \"{error}\"", "xpack.securitySolution.exceptions.fetch404Error": "La liste d'exceptions associée ({listId}) n'existe plus. Veuillez retirer la liste d'exceptions manquante pour ajouter des exceptions supplémentaires à la règle de détection.", "xpack.securitySolution.exceptions.hideCommentsLabel": "Masquer ({comments}) {comments, plural, =1 {commentaire} other {commentaires}}", @@ -28141,7 +28141,7 @@ "xpack.securitySolution.exceptions.cancelLabel": "Annuler", "xpack.securitySolution.exceptions.clearExceptionsLabel": "Retirer la liste d'exceptions", "xpack.securitySolution.exceptions.commentEventLabel": "a ajouté un commentaire", - "xpack.securitySolution.exceptions.dissasociateExceptionListError": "Impossible de retirer la liste d'exceptions", + "xpack.securitySolution.exceptions.disassociateExceptionListError": "Impossible de retirer la liste d'exceptions", "xpack.securitySolution.exceptions.errorLabel": "Erreur", "xpack.securitySolution.exceptions.fetchError": "Erreur lors de la récupération de la liste d'exceptions", "xpack.securitySolution.exceptions.modalErrorAccordionText": "Afficher les informations de référence de la règle :", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1dafac2a81c7f..5f867500f94b7 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -25575,7 +25575,7 @@ "xpack.securitySolution.eventFilters.showingTotal": "{total} {total, plural, other {個のイベントフィルター}}を表示中", "xpack.securitySolution.eventsTab.unit": "外部{totalCount, plural, other {アラート}}", "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, other {イベント}}", - "xpack.securitySolution.exceptions.dissasociateListSuccessText": "例外リスト({id})が正常に削除されました", + "xpack.securitySolution.exceptions.disassociateListSuccessText": "例外リスト({id})が正常に削除されました", "xpack.securitySolution.exceptions.failedLoadPolicies": "ポリシーの読み込みエラーが発生しました:\"{error}\"", "xpack.securitySolution.exceptions.fetch404Error": "関連付けられた例外リスト({listId})は存在しません。その他の例外を検出ルールに追加するには、見つからない例外リストを削除してください。", "xpack.securitySolution.exceptions.hideCommentsLabel": "({comments}){comments, plural, other {件のコメント}}を非表示", @@ -28116,7 +28116,7 @@ "xpack.securitySolution.exceptions.cancelLabel": "キャンセル", "xpack.securitySolution.exceptions.clearExceptionsLabel": "例外リストを削除", "xpack.securitySolution.exceptions.commentEventLabel": "コメントを追加しました", - "xpack.securitySolution.exceptions.dissasociateExceptionListError": "例外リストを削除できませんでした", + "xpack.securitySolution.exceptions.disassociateExceptionListError": "例外リストを削除できませんでした", "xpack.securitySolution.exceptions.errorLabel": "エラー", "xpack.securitySolution.exceptions.fetchError": "例外リストの取得エラー", "xpack.securitySolution.exceptions.modalErrorAccordionText": "ルール参照情報を表示:", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index afa9e88f36811..002fdcf382100 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25609,7 +25609,7 @@ "xpack.securitySolution.eventFilters.showingTotal": "正在显示 {total} 个{total, plural, other {事件筛选}}", "xpack.securitySolution.eventsTab.unit": "个外部{totalCount, plural, other {告警}}", "xpack.securitySolution.eventsViewer.unit": "{totalCount, plural, other {个事件}}", - "xpack.securitySolution.exceptions.dissasociateListSuccessText": "例外列表 ({id}) 已成功移除", + "xpack.securitySolution.exceptions.disassociateListSuccessText": "例外列表 ({id}) 已成功移除", "xpack.securitySolution.exceptions.failedLoadPolicies": "加载策略时出错:“{error}”", "xpack.securitySolution.exceptions.fetch404Error": "关联的例外列表 ({listId}) 已不存在。请移除缺少的例外列表,以将其他例外添加到检测规则。", "xpack.securitySolution.exceptions.hideCommentsLabel": "隐藏 ({comments}) 个{comments, plural, other {注释}}", @@ -28150,7 +28150,7 @@ "xpack.securitySolution.exceptions.cancelLabel": "取消", "xpack.securitySolution.exceptions.clearExceptionsLabel": "移除例外列表", "xpack.securitySolution.exceptions.commentEventLabel": "已添加注释", - "xpack.securitySolution.exceptions.dissasociateExceptionListError": "无法移除例外列表", + "xpack.securitySolution.exceptions.disassociateExceptionListError": "无法移除例外列表", "xpack.securitySolution.exceptions.errorLabel": "错误", "xpack.securitySolution.exceptions.fetchError": "提取例外列表时出错", "xpack.securitySolution.exceptions.modalErrorAccordionText": "显示规则引用信息:", diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts b/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts index 70ee954bd9166..7f7d023fe2727 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/add_prepackaged_rules.ts @@ -6,9 +6,12 @@ */ import expect from '@kbn/expect'; -import { PrePackagedRulesAndTimelinesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/response'; +import { + PREBUILT_RULES_STATUS_URL, + PREBUILT_RULES_URL, + InstallPrebuiltRulesAndTimelinesResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/prebuilt_rules'; -import { DETECTION_ENGINE_PREPACKAGED_URL } from '@kbn/security-solution-plugin/common/constants'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -43,7 +46,7 @@ export default ({ getService }: FtrProviderContext): void => { await waitFor( async () => { const { body, status } = await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) + .put(PREBUILT_RULES_URL) .set('kbn-xsrf', 'true') .send(); if (status === 200) { @@ -51,11 +54,11 @@ export default ({ getService }: FtrProviderContext): void => { } return status === 200; }, - DETECTION_ENGINE_PREPACKAGED_URL, + PREBUILT_RULES_URL, log ); - const prepackagedRules = responseBody as PrePackagedRulesAndTimelinesSchema; + const prepackagedRules = responseBody as InstallPrebuiltRulesAndTimelinesResponse; expect(prepackagedRules.rules_installed).to.be.greaterThan(0); expect(prepackagedRules.rules_updated).to.eql(0); expect(Object.keys(prepackagedRules)).to.eql([ @@ -74,12 +77,12 @@ export default ({ getService }: FtrProviderContext): void => { await waitFor( async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .expect(200); return body.rules_not_installed === 0; }, - `${DETECTION_ENGINE_PREPACKAGED_URL}/_status`, + PREBUILT_RULES_STATUS_URL, log ); @@ -87,7 +90,7 @@ export default ({ getService }: FtrProviderContext): void => { await waitFor( async () => { const { body, status } = await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) + .put(PREBUILT_RULES_URL) .set('kbn-xsrf', 'true') .send(); if (status === 200) { @@ -95,11 +98,11 @@ export default ({ getService }: FtrProviderContext): void => { } return status === 200; }, - DETECTION_ENGINE_PREPACKAGED_URL, + PREBUILT_RULES_URL, log ); - const prepackagedRules = responseBody as PrePackagedRulesAndTimelinesSchema; + const prepackagedRules = responseBody as InstallPrebuiltRulesAndTimelinesResponse; expect(prepackagedRules.rules_installed).to.eql(0); expect(prepackagedRules.timelines_installed).to.eql(0); }); diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts b/x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts index 6c4f73285e64f..55183b48d78f9 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { FtrProviderContext } from '../../common/ftr_provider_context'; @@ -60,7 +60,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should create a single rule without an input index', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { name: 'Simple Rule Query', description: 'Simple Rule Query', enabled: true, diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/get_prepackaged_rules_status.ts b/x-pack/test/detection_engine_api_integration/basic/tests/get_prepackaged_rules_status.ts index c3b2eb3568ccb..ce75086a2deea 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/get_prepackaged_rules_status.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/get_prepackaged_rules_status.ts @@ -7,10 +7,12 @@ import expect from '@kbn/expect'; +import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { - DETECTION_ENGINE_PREPACKAGED_URL, - DETECTION_ENGINE_RULES_URL, -} from '@kbn/security-solution-plugin/common/constants'; + PREBUILT_RULES_STATUS_URL, + PREBUILT_RULES_URL, +} from '@kbn/security-solution-plugin/common/detection_engine/prebuilt_rules'; + import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -40,7 +42,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return expected JSON keys of the pre-packaged rules and pre-packaged timelines status', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -58,7 +60,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that rules_not_installed are greater than zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -67,7 +69,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that timelines_not_installed are greater than zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -76,7 +78,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that rules_custom_installed, rules_installed, and rules_not_updated are zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -87,7 +89,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that timelines_installed, and timelines_not_updated are zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -103,7 +105,7 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -115,14 +117,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should show rules and timelines are installed when adding pre-packaged rules', async () => { - await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) - .set('kbn-xsrf', 'true') - .send() - .expect(200); + await supertest.put(PREBUILT_RULES_URL).set('kbn-xsrf', 'true').send().expect(200); const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_actions.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_actions.ts index 90c80c172fcfa..94a8b58ff70a0 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_actions.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_actions.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -86,7 +86,7 @@ export default ({ getService }: FtrProviderContext) => { .expect(200); // create a rule with the action attached and a meta field - const ruleWithAction: CreateRulesSchema = { + const ruleWithAction: RuleCreateProps = { ...getRuleWithWebHookAction(hookAction.id, true), meta: {}, }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_prepackaged_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_prepackaged_rules.ts index 512863e039e3a..f90b1f8c8949b 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_prepackaged_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/add_prepackaged_rules.ts @@ -6,9 +6,12 @@ */ import expect from '@kbn/expect'; -import { PrePackagedRulesAndTimelinesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/response'; +import { + PREBUILT_RULES_STATUS_URL, + PREBUILT_RULES_URL, + InstallPrebuiltRulesAndTimelinesResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/prebuilt_rules'; -import { DETECTION_ENGINE_PREPACKAGED_URL } from '@kbn/security-solution-plugin/common/constants'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -42,7 +45,7 @@ export default ({ getService }: FtrProviderContext): void => { await waitFor( async () => { const { body, status } = await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) + .put(PREBUILT_RULES_URL) .set('kbn-xsrf', 'true') .send(); if (status === 200) { @@ -50,11 +53,11 @@ export default ({ getService }: FtrProviderContext): void => { } return status === 200; }, - DETECTION_ENGINE_PREPACKAGED_URL, + PREBUILT_RULES_URL, log ); - const prepackagedRules = responseBody as PrePackagedRulesAndTimelinesSchema; + const prepackagedRules = responseBody as InstallPrebuiltRulesAndTimelinesResponse; expect(prepackagedRules.rules_installed).to.be.greaterThan(0); expect(prepackagedRules.rules_updated).to.eql(0); expect(Object.keys(prepackagedRules)).to.eql([ @@ -73,12 +76,12 @@ export default ({ getService }: FtrProviderContext): void => { await waitFor( async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .expect(200); return body.rules_not_installed === 0; }, - `${DETECTION_ENGINE_PREPACKAGED_URL}/_status`, + PREBUILT_RULES_STATUS_URL, log ); @@ -86,7 +89,7 @@ export default ({ getService }: FtrProviderContext): void => { await waitFor( async () => { const { body, status } = await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) + .put(PREBUILT_RULES_URL) .set('kbn-xsrf', 'true') .send(); if (status === 200) { @@ -94,11 +97,11 @@ export default ({ getService }: FtrProviderContext): void => { } return status === 200; }, - DETECTION_ENGINE_PREPACKAGED_URL, + PREBUILT_RULES_URL, log ); - const prepackagedRules = responseBody as PrePackagedRulesAndTimelinesSchema; + const prepackagedRules = responseBody as InstallPrebuiltRulesAndTimelinesResponse; expect(prepackagedRules.rules_installed).to.eql(0); expect(prepackagedRules.timelines_installed).to.eql(0); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts index d208b522a1d44..0b7de71969a7b 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/check_privileges.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { ROLES } from '@kbn/security-solution-plugin/common/test'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; -import { ThresholdCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { ThresholdRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -86,7 +86,7 @@ export default ({ getService }: FtrProviderContext) => { }); it(`for threshold rule with index param: ${index}`, async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(index), threshold: { field: [], diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_ml.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_ml.ts index a29963ec3b6cb..e1a3d4f0796c4 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_ml.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_ml.ts @@ -17,7 +17,7 @@ import { SPACE_IDS, VERSION, } from '@kbn/rule-data-utils'; -import { MachineLearningCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { MachineLearningRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { ALERT_ANCESTORS, ALERT_DEPTH, @@ -47,7 +47,7 @@ export default ({ getService }: FtrProviderContext) => { const siemModule = 'security_linux_v3'; const mlJobId = 'v3_linux_anomalous_network_activity'; - const testRule: MachineLearningCreateSchema = { + const testRule: MachineLearningRuleCreateProps = { name: 'Test ML rule', description: 'Test ML rule description', risk_score: 50, @@ -185,7 +185,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should create 7 alerts from ML rule when records meet anomaly_threshold', async () => { - const rule: MachineLearningCreateSchema = { + const rule: MachineLearningRuleCreateProps = { ...testRule, anomaly_threshold: 20, }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_new_terms.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_new_terms.ts index 7c97505307cd0..bfb369e0091b5 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_new_terms.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_new_terms.ts @@ -8,10 +8,10 @@ import { orderBy } from 'lodash'; import expect from '@kbn/expect'; -import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; -import { NewTermsCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; -import { getCreateNewTermsRulesSchemaMock } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request/rule_schemas.mock'; +import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; +import { NewTermsRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; +import { getCreateNewTermsRulesSchemaMock } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema/mocks'; import { DetectionAlert } from '@kbn/security-solution-plugin/common/detection_engine/schemas/alerts'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { @@ -114,7 +114,7 @@ export default ({ getService }: FtrProviderContext) => { // suricata-sensor-san-francisco appears in a document at 2019-02-19T20:42:08.230Z, but also appears // in earlier documents so is not new. An alert should not be generated for that term. it('should generate 1 alert with 1 selected field', async () => { - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), new_terms_fields: ['host.name'], from: '2019-02-19T20:42:00.000Z', @@ -258,7 +258,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate 3 alerts when 1 document has 3 new values', async () => { - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), new_terms_fields: ['host.ip'], from: '2019-02-19T20:42:00.000Z', @@ -289,7 +289,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate alerts for every term when history window is small', async () => { - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), new_terms_fields: ['host.name'], from: '2019-02-19T20:42:00.000Z', @@ -337,7 +337,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate the correct alerts', async () => { - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), // myfakeindex-3 does not have event.ingested mapped so we can test if the runtime field // 'kibana.combined_timestamp' handles unmapped fields properly @@ -364,7 +364,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should apply exceptions', async () => { - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), new_terms_fields: ['host.name'], from: '2019-02-19T20:42:00.000Z', @@ -402,7 +402,7 @@ export default ({ getService }: FtrProviderContext) => { it('should work for max signals > 100', async () => { const maxSignals = 200; - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), new_terms_fields: ['process.pid'], from: '2018-02-19T20:42:00.000Z', @@ -445,7 +445,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be enriched with host risk score', async () => { - const rule: NewTermsCreateSchema = { + const rule: NewTermsRuleCreateProps = { ...getCreateNewTermsRulesSchemaMock('rule-1', true), new_terms_fields: ['host.name'], from: '2019-02-19T20:42:00.000Z', diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts index 082d8afab9dd1..a1da5d5697b1e 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_rules.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { ROLES } from '@kbn/security-solution-plugin/common/test'; @@ -161,7 +161,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should create a single rule without an input index', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { name: 'Simple Rule Query', description: 'Simple Rule Query', enabled: true, @@ -273,7 +273,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should not create a rule if trying to add more than one default rule exception list', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { name: 'Simple Rule Query', description: 'Simple Rule Query', enabled: true, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_threat_matching.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_threat_matching.ts index 906cc94f224d8..b18f716d17d4e 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_threat_matching.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_threat_matching.ts @@ -22,10 +22,11 @@ import { flattenWithPrefix } from '@kbn/securitysolution-rules'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; - -import { getCreateThreatMatchRulesSchemaMock } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request/rule_schemas.mock'; -import { getThreatMatchingSchemaPartialMock } from '@kbn/security-solution-plugin/common/detection_engine/schemas/response/rules_schema.mocks'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; +import { + getCreateThreatMatchRulesSchemaMock, + getThreatMatchingSchemaPartialMock, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema/mocks'; import { ENRICHMENT_TYPES } from '@kbn/security-solution-plugin/common/cti/constants'; import { Ancestor } from '@kbn/security-solution-plugin/server/lib/detection_engine/signals/types'; import { @@ -146,7 +147,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able to execute and get 10 signals when doing a specific query', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -332,7 +333,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should return 0 matches if the mapping does not match against anything in the mapping', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -367,7 +368,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should return 0 signals when using an AND and one of the clauses does not have data', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -406,7 +407,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should return 0 signals when using an AND and one of the clauses has a made up value that does not exist', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -447,7 +448,7 @@ export default ({ getService }: FtrProviderContext) => { describe('timeout behavior', () => { // Flaky it.skip('will return an error if a rule execution exceeds the rule interval', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a short interval', severity: 'high', @@ -503,7 +504,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('enriches signals with the single indicator that matched', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -594,7 +595,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('enriches signals with multiple indicators if several matched', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -674,7 +675,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('adds a single indicator that matched multiple fields', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -786,7 +787,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates multiple signals with multiple matches', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -936,7 +937,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('enriches signals with the single indicator that matched', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -1027,7 +1028,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('enriches signals with multiple indicators if several matched', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -1107,7 +1108,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('adds a single indicator that matched multiple fields', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -1219,7 +1220,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates multiple signals with multiple matches', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -1369,7 +1370,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be enriched with host risk score', async () => { - const rule: CreateRulesSchema = { + const rule: RuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/find_rule_exception_references.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/find_rule_exception_references.ts index 173aaa86c4328..6ddc5dafaafa1 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/find_rule_exception_references.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/find_rule_exception_references.ts @@ -9,13 +9,17 @@ import expect from '@kbn/expect'; -import { DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL } from '@kbn/security-solution-plugin/common/constants'; import { CreateExceptionListSchema, ExceptionListTypeEnum, } from '@kbn/securitysolution-io-ts-list-types'; + import { getCreateExceptionListMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_schema.mock'; -import { RuleReferencesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/response'; +import { + DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL, + RuleReferencesSchema, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_exceptions'; + import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createRule, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/generating_signals.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/generating_signals.ts index b71cd23063550..60e4cef77c896 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/generating_signals.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/generating_signals.ts @@ -25,11 +25,11 @@ import { orderBy, get } from 'lodash'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; import { - EqlCreateSchema, - QueryCreateSchema, - SavedQueryCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + EqlRuleCreateProps, + QueryRuleCreateProps, + SavedQueryRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { Ancestor } from '@kbn/security-solution-plugin/server/lib/detection_engine/signals/types'; import { ALERT_ANCESTORS, @@ -92,7 +92,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should have the specific audit record for _id or none of these tests below will pass', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; @@ -105,7 +105,7 @@ export default ({ getService }: FtrProviderContext) => { it('should abide by max_signals > 100', async () => { const maxSignals = 500; - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), max_signals: maxSignals, }; @@ -117,7 +117,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should have recorded the rule_id within the signal', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; @@ -129,7 +129,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should query and get back expected signal structure using a basic KQL query', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; @@ -162,7 +162,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should query and get back expected signal structure using a saved query rule', async () => { - const rule: SavedQueryCreateSchema = { + const rule: SavedQueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), type: 'saved_query', query: `_id:${ID}`, @@ -196,7 +196,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should query and get back expected signal structure when it is a signal on a signal', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; @@ -205,7 +205,7 @@ export default ({ getService }: FtrProviderContext) => { await waitForSignalsToBePresent(supertest, log, 1, [createdId]); // Run signals on top of that 1 signal which should create a single signal (on top of) a signal - const ruleForSignals: QueryCreateSchema = { + const ruleForSignals: QueryRuleCreateProps = { ...getRuleForSignalTesting([`.alerts-security.alerts-default*`]), rule_id: 'signal-on-signal', }; @@ -260,7 +260,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates a correctly formatted signal from EQL non-sequence queries', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', }; @@ -364,7 +364,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates up to max_signals for non-sequence EQL queries', async () => { - const rule: EqlCreateSchema = getEqlRuleForSignalTesting(['auditbeat-*']); + const rule: EqlRuleCreateProps = getEqlRuleForSignalTesting(['auditbeat-*']); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccessOrStatus(supertest, log, id); await waitForSignalsToBePresent(supertest, log, 100, [id]); @@ -376,7 +376,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('uses the provided event_category_override', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'config_change where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', event_category_override: 'auditd.message_type', @@ -449,7 +449,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('uses the provided timestamp_field', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['fake.index.1']), query: 'any where true', timestamp_field: 'created_at', @@ -465,7 +465,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('uses the provided tiebreaker_field', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['fake.index.1']), query: 'any where true', tiebreaker_field: 'locale', @@ -481,7 +481,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates building block signals from EQL sequences in the expected form', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'sequence by host.name [anomoly where true] [any where true]', // TODO: spelling }; @@ -629,7 +629,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates shell signals from EQL sequences in the expected form', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'sequence by host.name [anomoly where true] [any where true]', }; @@ -715,7 +715,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates up to max_signals with an EQL rule', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'sequence by host.name [any where true] [any where true]', max_signals: 200, @@ -739,7 +739,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates signals when an index name contains special characters to encode', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*', '']), query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', }; @@ -751,7 +751,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('uses the provided filters', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'any where true', filters: [ @@ -808,7 +808,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be enriched with host risk score', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', }; @@ -829,7 +829,7 @@ export default ({ getService }: FtrProviderContext) => { describe('Threshold Rules', () => { it('generates 1 signal from Threshold rules when threshold is met', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: ['host.id'], @@ -877,7 +877,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates 2 signals from Threshold rules when threshold is met', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: 'host.id', @@ -892,7 +892,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('applies the provided query before bucketing ', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), query: 'host.id:"2ab45fc1c41e4c84bbd02202a7e5761f"', threshold: { @@ -908,7 +908,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no signals from Threshold rules when threshold is met and cardinality is not met', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: 'host.id', @@ -927,7 +927,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no signals from Threshold rules when cardinality is met and threshold is not met', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: 'host.id', @@ -946,7 +946,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates signals from Threshold rules when threshold and cardinality are both met', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: 'host.id', @@ -1004,7 +1004,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should not generate signals if only one field meets the threshold requirement', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: ['host.id', 'process.name'], @@ -1017,7 +1017,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates signals from Threshold rules when bucketing by multiple fields', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: ['host.id', 'process.name', 'event.module'], @@ -1086,7 +1086,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('applies timestamp override when using single field', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['timestamp-fallback-test']), threshold: { field: 'host.name', @@ -1116,7 +1116,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('applies timestamp override when using multiple fields', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['timestamp-fallback-test']), threshold: { field: ['host.name', 'source.ip'], @@ -1156,7 +1156,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be enriched with host risk score', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: 'host.name', @@ -1181,7 +1181,7 @@ export default ({ getService }: FtrProviderContext) => { describe('Enrich alerts: query rule', () => { describe('without index avalable', () => { it('should do not have risk score fields', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; @@ -1206,7 +1206,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should host have risk score field and do not have user risk score', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID} or _id:GBbXBmkBR346wHgn5_eR or _id:x10zJ2oE9v5HJNSHhyxi`, }; @@ -1247,7 +1247,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should have host and user risk score fields', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; @@ -1282,7 +1282,7 @@ export default ({ getService }: FtrProviderContext) => { ); }); - const executeRuleAndGetSignals = async (rule: QueryCreateSchema) => { + const executeRuleAndGetSignals = async (rule: QueryRuleCreateProps) => { const { id } = await createRule(supertest, log, rule); await waitForRuleSuccessOrStatus(supertest, log, id); await waitForSignalsToBePresent(supertest, log, 4, [id]); @@ -1293,7 +1293,7 @@ export default ({ getService }: FtrProviderContext) => { }; it('should get default severity and risk score if there is no mapping', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['signal_overrides']), severity: 'medium', risk_score: 75, @@ -1312,7 +1312,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should get overridden severity if the rule has a mapping for it', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['signal_overrides']), severity: 'medium', severity_mapping: [ @@ -1347,7 +1347,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should get overridden risk score if the rule has a mapping for it', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['signal_overrides']), severity: 'medium', risk_score: 75, @@ -1380,7 +1380,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should get overridden severity and risk score if the rule has both mappings', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['signal_overrides']), severity: 'medium', severity_mapping: [ @@ -1440,7 +1440,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate signals with name_override field', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), rule_name_override: 'event.action', }; @@ -1503,7 +1503,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should not generate duplicate signals', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prepackaged_rules_status.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prepackaged_rules_status.ts index c3b2eb3568ccb..ce75086a2deea 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prepackaged_rules_status.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/get_prepackaged_rules_status.ts @@ -7,10 +7,12 @@ import expect from '@kbn/expect'; +import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { - DETECTION_ENGINE_PREPACKAGED_URL, - DETECTION_ENGINE_RULES_URL, -} from '@kbn/security-solution-plugin/common/constants'; + PREBUILT_RULES_STATUS_URL, + PREBUILT_RULES_URL, +} from '@kbn/security-solution-plugin/common/detection_engine/prebuilt_rules'; + import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -40,7 +42,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return expected JSON keys of the pre-packaged rules and pre-packaged timelines status', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -58,7 +60,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that rules_not_installed are greater than zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -67,7 +69,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that timelines_not_installed are greater than zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -76,7 +78,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that rules_custom_installed, rules_installed, and rules_not_updated are zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -87,7 +89,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should return that timelines_installed, and timelines_not_updated are zero', async () => { const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -103,7 +105,7 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); @@ -115,14 +117,10 @@ export default ({ getService }: FtrProviderContext): void => { }); it('should show rules and timelines are installed when adding pre-packaged rules', async () => { - await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) - .set('kbn-xsrf', 'true') - .send() - .expect(200); + await supertest.put(PREBUILT_RULES_URL).set('kbn-xsrf', 'true').send().expect(200); const { body } = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) + .get(PREBUILT_RULES_STATUS_URL) .set('kbn-xsrf', 'true') .send() .expect(200); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/update_actions.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/update_actions.ts index 8ee61c0705452..11ad72b505f1f 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/update_actions.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/update_actions.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { omit } from 'lodash'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createSignalsIndex, @@ -31,7 +31,7 @@ import { } from '../../utils'; // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: -// x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json +// x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json const RULE_ID = '9a1a2dae-0b5f-4c3d-8305-a268d404c306'; // eslint-disable-next-line import/no-default-export @@ -107,7 +107,7 @@ export default ({ getService }: FtrProviderContext) => { const hookAction = await createNewAction(supertest, log); const rule = getSimpleRule(); await createRule(supertest, log, rule); - const ruleToUpdate: CreateRulesSchema = { + const ruleToUpdate: RuleCreateProps = { ...getRuleWithWebHookAction(hookAction.id, true, rule), meta: {}, // create a rule with the action attached and a meta field }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/import_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/import_rules.ts index e2ee8395d98c6..d3739473a5985 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/import_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/import_rules.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { EXCEPTION_LIST_ITEM_URL, EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; import { getCreateExceptionListMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_schema.mock'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; @@ -230,7 +230,7 @@ export default ({ getService }: FtrProviderContext): void => { const { body } = await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') - .attach('file', ruleToNdjson(rule as CreateRulesSchema), 'rules.ndjson') + .attach('file', ruleToNdjson(rule as RuleCreateProps), 'rules.ndjson') .expect(200); expect(body.errors[0]).to.eql({ diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index 77655b8ba150b..30b378d2a7eea 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -6,35 +6,33 @@ */ import expect from '@kbn/expect'; - import { DETECTION_ENGINE_RULES_BULK_ACTION, DETECTION_ENGINE_RULES_URL, NOTIFICATION_THROTTLE_NO_ACTIONS, NOTIFICATION_THROTTLE_RULE, } from '@kbn/security-solution-plugin/common/constants'; - +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { BulkAction, BulkActionEditType, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request/perform_bulk_action_schema'; -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +} from '@kbn/security-solution-plugin/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { binaryToString, + createLegacyRuleAction, createRule, createSignalsIndex, deleteAllAlerts, deleteSignalsIndex, - getSimpleRule, - getSimpleRuleOutput, - removeServerGeneratedProperties, - createLegacyRuleAction, getLegacyActionSO, - installPrePackagedRules, getSimpleMlRule, - getWebHookAction, + getSimpleRule, + getSimpleRuleOutput, getSlackAction, + getWebHookAction, + installPrePackagedRules, + removeServerGeneratedProperties, } from '../../utils'; // eslint-disable-next-line import/no-default-export @@ -374,7 +372,7 @@ export default ({ getService }: FtrProviderContext): void => { expect(rulesResponse.total).to.eql(2); - rulesResponse.data.forEach((rule: FullResponseSchema) => { + rulesResponse.data.forEach((rule: RuleResponse) => { expect(rule.actions).to.eql([ { action_type_id: '.slack', diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action_dry_run.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action_dry_run.ts index e9c3b3b68487d..b893f38f20310 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action_dry_run.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action_dry_run.ts @@ -4,25 +4,24 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import expect from 'expect'; - import { DETECTION_ENGINE_RULES_BULK_ACTION, DETECTION_ENGINE_RULES_URL, } from '@kbn/security-solution-plugin/common/constants'; +import expect from 'expect'; import { BulkAction, BulkActionEditType, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request/perform_bulk_action_schema'; +} from '@kbn/security-solution-plugin/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { FtrProviderContext } from '../../common/ftr_provider_context'; import { createRule, createSignalsIndex, deleteAllAlerts, deleteSignalsIndex, + getSimpleMlRule, getSimpleRule, installPrePackagedRules, - getSimpleMlRule, } from '../../utils'; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts index 9a459b1ffb0e1..fc3dc32483ba4 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts @@ -7,7 +7,7 @@ import expect from '@kbn/expect'; -import { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL, NOTIFICATION_THROTTLE_NO_ACTIONS, @@ -73,7 +73,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and no actions, the rule should have its kibana alerting "mute_all" set to "true" and notify_when set to "onActiveAlert"', async () => { - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_NO_ACTIONS, }; @@ -93,7 +93,7 @@ export default ({ getService }: FtrProviderContext) => { .send(getWebHookAction()) .expect(200); - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getRuleWithWebHookAction(hookAction.id), throttle: NOTIFICATION_THROTTLE_NO_ACTIONS, }; @@ -106,7 +106,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_RULE, }; @@ -120,7 +120,7 @@ export default ({ getService }: FtrProviderContext) => { // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, since we do not have any actions, we should get back a throttle of "NOTIFICATION_THROTTLE_NO_ACTIONS"', async () => { - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_RULE, }; @@ -136,7 +136,7 @@ export default ({ getService }: FtrProviderContext) => { .send(getWebHookAction()) .expect(200); - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getRuleWithWebHookAction(hookAction.id), throttle: NOTIFICATION_THROTTLE_RULE, }; @@ -149,7 +149,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('When creating throttle with "1h" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onThrottleInterval"', async () => { - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: '1h', }; @@ -169,7 +169,7 @@ export default ({ getService }: FtrProviderContext) => { .send(getWebHookAction()) .expect(200); - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getRuleWithWebHookAction(hookAction.id), throttle: '1h', }; @@ -197,7 +197,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and no actions, we should return "NOTIFICATION_THROTTLE_NO_ACTIONS" when doing a read', async () => { - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_NO_ACTIONS, }; @@ -208,7 +208,7 @@ export default ({ getService }: FtrProviderContext) => { // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, since we do not have any actions, we should get back a throttle of "NOTIFICATION_THROTTLE_NO_ACTIONS" when doing a read', async () => { - const ruleWithThrottle: CreateRulesSchema = { + const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_RULE, }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/timestamps.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/timestamps.ts index db7ed86b97f71..df0d9fb17e47a 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/timestamps.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/timestamps.ts @@ -9,9 +9,9 @@ import expect from '@kbn/expect'; import { orderBy } from 'lodash'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; import { - EqlCreateSchema, - QueryCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + EqlRuleCreateProps, + QueryRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { ALERT_ORIGINAL_TIME } from '@kbn/security-solution-plugin/common/field_maps/field_names'; import { FtrProviderContext } from '../../common/ftr_provider_context'; @@ -77,7 +77,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should still use the @timestamp field even with an override field. It should never use the override field', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['myfakeindex-5']), timestamp_override: 'event.ingested', }; @@ -106,7 +106,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should still use the @timestamp field even with an override field. It should never use the override field', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['myfakeindex-5']), timestamp_override: 'event.ingested', }; @@ -165,7 +165,7 @@ export default ({ getService }: FtrProviderContext) => { describe('KQL', () => { it('should generate signals with event.ingested, @timestamp and (event.ingested + timestamp)', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['myfa*']), timestamp_override: 'event.ingested', }; @@ -187,7 +187,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate 2 signals with event.ingested when timestamp fallback is disabled', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['myfa*']), rule_id: 'rule-without-timestamp-fallback', timestamp_override: 'event.ingested', @@ -211,7 +211,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate 2 signals with @timestamp', async () => { - const rule: QueryCreateSchema = getRuleForSignalTesting(['myfa*']); + const rule: QueryRuleCreateProps = getRuleForSignalTesting(['myfa*']); const { id } = await createRule(supertest, log, rule); @@ -230,7 +230,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate 2 signals when timestamp override does not exist', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['myfa*']), timestamp_override: 'event.fakeingestfield', }; @@ -251,7 +251,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should not generate any signals when timestamp override does not exist and timestamp fallback is disabled', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['myfa*']), rule_id: 'rule-without-timestamp-fallback', timestamp_override: 'event.fakeingestfield', @@ -276,7 +276,7 @@ export default ({ getService }: FtrProviderContext) => { * and we add a new timestamp to the signal. */ it('should NOT use the timestamp override as the "original_time"', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['myfakeindex-2']), timestamp_override: 'event.ingested', }; @@ -294,7 +294,7 @@ export default ({ getService }: FtrProviderContext) => { describe('EQL', () => { it('should generate 2 signals with @timestamp', async () => { - const rule: EqlCreateSchema = getEqlRuleForSignalTesting(['myfa*']); + const rule: EqlRuleCreateProps = getEqlRuleForSignalTesting(['myfa*']); const { id } = await createRule(supertest, log, rule); @@ -313,7 +313,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate 2 signals when timestamp override does not exist', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['myfa*']), timestamp_override: 'event.fakeingestfield', }; @@ -334,7 +334,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should not generate any signals when timestamp override does not exist and timestamp fallback is disabled', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['myfa*']), timestamp_override: 'event.fakeingestfield', timestamp_override_fallback_disabled: true, @@ -383,7 +383,7 @@ export default ({ getService }: FtrProviderContext) => { * ref: https://github.com/elastic/elasticsearch/issues/28806#issuecomment-369303620 */ it('should generate 200 signals when timestamp override does not exist', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), timestamp_override: 'event.fakeingested', max_signals: 200, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts index 2f5fb63382552..a3f6812f6a0b0 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/update_rules_bulk.ts @@ -6,7 +6,7 @@ */ import expect from '@kbn/expect'; -import { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL, @@ -158,7 +158,7 @@ export default ({ getService }: FtrProviderContext) => { updatedRule2.throttle = '1d'; // update both rule names - const { body }: { body: FullResponseSchema[] } = await supertest + const { body }: { body: RuleResponse[] } = await supertest .put(DETECTION_ENGINE_RULES_BULK_UPDATE) .set('kbn-xsrf', 'true') .send([updatedRule1, updatedRule2]) @@ -220,7 +220,7 @@ export default ({ getService }: FtrProviderContext) => { updatedRule2.name = 'some other name'; // update both rule names - const { body }: { body: FullResponseSchema[] } = await supertest + const { body }: { body: RuleResponse[] } = await supertest .put(DETECTION_ENGINE_RULES_BULK_UPDATE) .set('kbn-xsrf', 'true') .send([updatedRule1, updatedRule2]) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group3/create_exceptions.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group3/create_exceptions.ts index cc97253bfaf67..f6ea0fc02747b 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group3/create_exceptions.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group3/create_exceptions.ts @@ -11,12 +11,12 @@ import expect from '@kbn/expect'; import type { CreateExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { EXCEPTION_LIST_ITEM_URL, EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; import type { - CreateRulesSchema, - EqlCreateSchema, - QueryCreateSchema, - ThreatMatchCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleCreateProps, + EqlRuleCreateProps, + QueryRuleCreateProps, + ThreatMatchRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getCreateExceptionListItemMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_item_schema.mock'; import { getCreateExceptionListMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_schema.mock'; @@ -92,7 +92,7 @@ export default ({ getService }: FtrProviderContext) => { .send(getCreateExceptionListMinimalSchemaMock()) .expect(200); - const ruleWithException: CreateRulesSchema = { + const ruleWithException: RuleCreateProps = { ...getSimpleRule(), exceptions_list: [ { @@ -129,7 +129,7 @@ export default ({ getService }: FtrProviderContext) => { .send(getCreateExceptionListMinimalSchemaMock()) .expect(200); - const ruleWithException: CreateRulesSchema = { + const ruleWithException: RuleCreateProps = { ...getSimpleRule(), enabled: true, exceptions_list: [ @@ -165,7 +165,7 @@ export default ({ getService }: FtrProviderContext) => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to use const immutableRule = await getRule( supertest, @@ -199,7 +199,7 @@ export default ({ getService }: FtrProviderContext) => { ); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to use const immutableRule = await getRule( supertest, @@ -239,7 +239,7 @@ export default ({ getService }: FtrProviderContext) => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to use const immutableRule = await getRule( supertest, @@ -277,7 +277,7 @@ export default ({ getService }: FtrProviderContext) => { ); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to ensure does not stomp on our existing rule const immutableRule = await getRule( supertest, @@ -326,7 +326,7 @@ export default ({ getService }: FtrProviderContext) => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to ensure does not stomp on our existing rule const immutableRule = await getRule( supertest, @@ -361,7 +361,7 @@ export default ({ getService }: FtrProviderContext) => { ); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to ensure does not stomp on our existing rule const immutableRule = await getRule( supertest, @@ -418,7 +418,7 @@ export default ({ getService }: FtrProviderContext) => { ); // Rule id of "eb079c62-4481-4d6e-9643-3ca499df7aaa" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/external_alerts.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/external_alerts.json // since this rule does not have existing exceptions_list that we are going to use for tests const immutableRule = await getRule( supertest, @@ -472,7 +472,7 @@ export default ({ getService }: FtrProviderContext) => { ); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to use const immutableRule = await getRule( supertest, @@ -522,7 +522,7 @@ export default ({ getService }: FtrProviderContext) => { ); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint.json // This rule has an existing exceptions_list that we are going to use const immutableRule = await getRule( supertest, @@ -623,7 +623,7 @@ export default ({ getService }: FtrProviderContext) => { }; await createExceptionListItem(supertest, log, exceptionListItem); - const ruleWithException: CreateRulesSchema = { + const ruleWithException: RuleCreateProps = { name: 'Simple Rule Query', description: 'Simple Rule Query', enabled: true, @@ -651,7 +651,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should be able to execute against an exception list that does include valid entries and get back 0 signals', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { name: 'Simple Rule Query', description: 'Simple Rule Query', enabled: true, @@ -678,7 +678,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no signals when an exception is added for an EQL rule', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'configuration where agent.id=="a1d7b39c-f898-4dbe-a761-efb61939302d"', }; @@ -697,7 +697,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no signals when an exception is added for a threshold rule', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['auditbeat-*']), threshold: { field: 'host.id', @@ -719,7 +719,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no signals when an exception is added for a threat match rule', async () => { - const rule: ThreatMatchCreateSchema = { + const rule: ThreatMatchRuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -772,7 +772,7 @@ export default ({ getService }: FtrProviderContext) => { it('generates no signals when a value list exception is added for a query rule', async () => { const valueListId = 'value-list-id'; await importFile(supertest, log, 'keyword', ['suricata-sensor-amsterdam'], valueListId); - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { name: 'Simple Rule Query', description: 'Simple Rule Query', enabled: true, @@ -804,7 +804,7 @@ export default ({ getService }: FtrProviderContext) => { it('generates no signals when a value list exception is added for a threat match rule', async () => { const valueListId = 'value-list-id'; await importFile(supertest, log, 'keyword', ['zeek-sensor-amsterdam'], valueListId); - const rule: ThreatMatchCreateSchema = { + const rule: ThreatMatchRuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -852,7 +852,7 @@ export default ({ getService }: FtrProviderContext) => { it('generates no signals when a value list exception is added for a threshold rule', async () => { const valueListId = 'value-list-id'; await importFile(supertest, log, 'keyword', ['zeek-sensor-amsterdam'], valueListId); - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', @@ -889,7 +889,7 @@ export default ({ getService }: FtrProviderContext) => { it('generates no signals when a value list exception is added for an EQL rule', async () => { const valueListId = 'value-list-id'; await importFile(supertest, log, 'keyword', ['zeek-sensor-amsterdam'], valueListId); - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['auditbeat-*']), query: 'configuration where host.name=="zeek-sensor-amsterdam"', }; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts index eb5f5c9a923bb..36f5b84a50c3d 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts @@ -33,7 +33,7 @@ export default ({ getService }: FtrProviderContext) => { const retry = getService('retry'); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json // This rule has an existing exceptions_list that we are going to use. const IMMUTABLE_RULE_ID = '9a1a2dae-0b5f-4c3d-8305-a268d404c306'; diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts index dea6703d2fef4..0581c97802f03 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rule_status.ts @@ -10,9 +10,9 @@ import type { MlJobUsageMetric } from '@kbn/security-solution-plugin/server/usag import type { RulesTypeUsage } from '@kbn/security-solution-plugin/server/usage/detections/rules/types'; import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types'; import type { - ThreatMatchCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + ThreatMatchRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getInitialMlJobUsage } from '@kbn/security-solution-plugin/server/usage/detections/ml_jobs/get_initial_usage'; import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage'; import { @@ -444,7 +444,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"threshold" rule type', () => { let stats: DetectionMetrics | undefined; before(async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry']), threshold: { field: 'keyword', @@ -644,7 +644,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"indicator_match/threat_match" rule type', () => { let stats: DetectionMetrics | undefined; before(async () => { - const rule: ThreatMatchCreateSchema = { + const rule: ThreatMatchRuleCreateProps = { ...getSimpleThreatMatch('rule-1', true), index: ['telemetry'], threat_index: ['telemetry'], diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts index 7f7b0d3d30788..1d059e02ed5cc 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/usage_collector/detection_rules.ts @@ -8,9 +8,9 @@ import expect from '@kbn/expect'; import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types'; import type { - ThreatMatchCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + ThreatMatchRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage'; import { getInitialEventLogUsage } from '@kbn/security-solution-plugin/server/usage/detections/rules/get_initial_usage'; import type { FtrProviderContext } from '../../../../common/ftr_provider_context'; @@ -512,7 +512,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"threshold" rule type', () => { it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false), threshold: { field: 'keyword', @@ -552,7 +552,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry']), threshold: { field: 'keyword', @@ -600,7 +600,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false), threshold: { field: 'keyword', @@ -641,7 +641,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry']), threshold: { field: 'keyword', @@ -686,7 +686,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false), threshold: { field: 'keyword', @@ -727,7 +727,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['telemetry']), threshold: { field: 'keyword', @@ -1029,7 +1029,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => { - const rule: ThreatMatchCreateSchema = { + const rule: ThreatMatchRuleCreateProps = { ...getSimpleThreatMatch('rule-1', true), index: ['telemetry'], threat_index: ['telemetry'], @@ -1121,7 +1121,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { - const rule: ThreatMatchCreateSchema = { + const rule: ThreatMatchRuleCreateProps = { ...getSimpleThreatMatch('rule-1', true), index: ['telemetry'], threat_index: ['telemetry'], @@ -1210,7 +1210,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => { - const rule: ThreatMatchCreateSchema = { + const rule: ThreatMatchRuleCreateProps = { ...getSimpleThreatMatch('rule-1', true), index: ['telemetry'], threat_index: ['telemetry'], @@ -1303,7 +1303,7 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getStats(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json // We have to search by "rule_name" since the "rule_id" it is storing is the Saved Object ID and not the rule_id const foundRule = stats.detection_rules.detection_rule_detail.find( (rule) => rule.rule_id === '9a1a2dae-0b5f-4c3d-8305-a268d404c306' @@ -1334,7 +1334,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_disabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json const immutableRule = await getRule(supertest, log, '9a1a2dae-0b5f-4c3d-8305-a268d404c306'); const hookAction = await createNewAction(supertest, log); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id); @@ -1388,7 +1388,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "notifications_enabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json const immutableRule = await getRule(supertest, log, '9a1a2dae-0b5f-4c3d-8305-a268d404c306'); const hookAction = await createNewAction(supertest, log); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id); @@ -1442,7 +1442,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json const immutableRule = await getRule(supertest, log, '9a1a2dae-0b5f-4c3d-8305-a268d404c306'); const hookAction = await createNewAction(supertest, log); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, false); @@ -1496,7 +1496,7 @@ export default ({ getService }: FtrProviderContext) => { it('should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => { await installPrePackagedRules(supertest, log); // Rule id of "9a1a2dae-0b5f-4c3d-8305-a268d404c306" is from the file: - // x-pack/plugins/security_solution/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json + // x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json const immutableRule = await getRule(supertest, log, '9a1a2dae-0b5f-4c3d-8305-a268d404c306'); const hookAction = await createNewAction(supertest, log); const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, true); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/const_keyword.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/const_keyword.ts index 011ed04376281..f0290b8258dd8 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/const_keyword.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/const_keyword.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { - EqlCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + EqlRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { ALERT_THRESHOLD_RESULT } from '@kbn/security-solution-plugin/common/field_maps/field_names'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -86,7 +86,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"eql" rule type', () => { it('should detect the "dataset_name_1" from "event.dataset" and have 4 signals', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['const_keyword']), query: 'any where event.dataset=="dataset_name_1"', }; @@ -99,7 +99,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should copy the "dataset_name_1" from "event.dataset"', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['const_keyword']), query: 'any where event.dataset=="dataset_name_1"', }; @@ -120,7 +120,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"threshold" rule type', async () => { it('should detect the "dataset_name_1" from "event.dataset"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['const_keyword']), threshold: { field: 'event.dataset', diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword.ts index c07f0efb1df98..ef8126015c758 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword.ts @@ -8,10 +8,10 @@ import expect from '@kbn/expect'; import { - EqlCreateSchema, - QueryCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + EqlRuleCreateProps, + QueryRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { ALERT_THRESHOLD_RESULT } from '@kbn/security-solution-plugin/common/field_maps/field_names'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { @@ -53,7 +53,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"kql" rule type', () => { it('should detect the "dataset_name_1" from "event.dataset"', async () => { - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['keyword']), query: 'event.dataset: "dataset_name_1"', }; @@ -73,7 +73,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"eql" rule type', () => { it('should detect the "dataset_name_1" from "event.dataset"', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['keyword']), query: 'any where event.dataset=="dataset_name_1"', }; @@ -94,7 +94,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"threshold" rule type', async () => { it('should detect the "dataset_name_1" from "event.dataset"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getThresholdRuleForSignalTesting(['keyword']), threshold: { field: 'event.dataset', diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword_mixed_with_const.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword_mixed_with_const.ts index 52c5ae615da95..5949770ef23f9 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword_mixed_with_const.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group5/keyword_family/keyword_mixed_with_const.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect'; import { - EqlCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + EqlRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { ALERT_THRESHOLD_RESULT } from '@kbn/security-solution-plugin/common/field_maps/field_names'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; @@ -91,7 +91,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"eql" rule type', () => { it('should detect the "dataset_name_1" from "event.dataset" and have 8 signals, 4 from each index', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['keyword', 'const_keyword']), query: 'any where event.dataset=="dataset_name_1"', }; @@ -104,7 +104,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should copy the "dataset_name_1" from "event.dataset"', async () => { - const rule: EqlCreateSchema = { + const rule: EqlRuleCreateProps = { ...getEqlRuleForSignalTesting(['keyword', 'const_keyword']), query: 'any where event.dataset=="dataset_name_1"', }; @@ -129,7 +129,7 @@ export default ({ getService }: FtrProviderContext) => { describe('"threshold" rule type', async () => { it('should detect the "dataset_name_1" from "event.dataset"', async () => { - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...getRuleForSignalTesting(['keyword', 'const_keyword']), rule_id: 'threshold-rule', type: 'threshold', diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts index ba8c9ea88cd17..343de21a3ebf5 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group6/alerts/alerts_compatibility.ts @@ -14,12 +14,12 @@ import { } from '@kbn/security-solution-plugin/common/constants'; import { ThreatEcs } from '@kbn/security-solution-plugin/common/ecs/threat'; import { - EqlCreateSchema, - QueryCreateSchema, - SavedQueryCreateSchema, - ThreatMatchCreateSchema, - ThresholdCreateSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + EqlRuleCreateProps, + QueryRuleCreateProps, + SavedQueryRuleCreateProps, + ThreatMatchRuleCreateProps, + ThresholdRuleCreateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { createRule, createSignalsIndex, @@ -181,7 +181,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const rule: ThreatMatchCreateSchema = getThreatMatchRuleForSignalTesting([ + const rule: ThreatMatchRuleCreateProps = getThreatMatchRuleForSignalTesting([ '.siem-signals-*', ]); const { id } = await createRule(supertest, log, rule); @@ -194,7 +194,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const rule: ThreatMatchCreateSchema = getThreatMatchRuleForSignalTesting([ + const rule: ThreatMatchRuleCreateProps = getThreatMatchRuleForSignalTesting([ `.alerts-security.alerts-default`, ]); const { id } = await createRule(supertest, log, rule); @@ -222,7 +222,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const rule: QueryCreateSchema = getRuleForSignalTesting([`.siem-signals-*`]); + const rule: QueryRuleCreateProps = getRuleForSignalTesting([`.siem-signals-*`]); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccessOrStatus(supertest, log, id); await waitForSignalsToBePresent(supertest, log, 1, [id]); @@ -389,7 +389,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const rule: QueryCreateSchema = getRuleForSignalTesting([ + const rule: QueryRuleCreateProps = getRuleForSignalTesting([ `.alerts-security.alerts-default`, ]); const { id } = await createRule(supertest, log, rule); @@ -573,7 +573,9 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const rule: SavedQueryCreateSchema = getSavedQueryRuleForSignalTesting([`.siem-signals-*`]); + const rule: SavedQueryRuleCreateProps = getSavedQueryRuleForSignalTesting([ + `.siem-signals-*`, + ]); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccessOrStatus(supertest, log, id); await waitForSignalsToBePresent(supertest, log, 1, [id]); @@ -584,7 +586,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const rule: SavedQueryCreateSchema = getSavedQueryRuleForSignalTesting([ + const rule: SavedQueryRuleCreateProps = getSavedQueryRuleForSignalTesting([ `.alerts-security.alerts-default`, ]); const { id } = await createRule(supertest, log, rule); @@ -612,7 +614,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const rule: EqlCreateSchema = getEqlRuleForSignalTesting(['.siem-signals-*']); + const rule: EqlRuleCreateProps = getEqlRuleForSignalTesting(['.siem-signals-*']); const { id } = await createRule(supertest, log, rule); await waitForRuleSuccessOrStatus(supertest, log, id); await waitForSignalsToBePresent(supertest, log, 1, [id]); @@ -623,7 +625,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const rule: EqlCreateSchema = getEqlRuleForSignalTesting([ + const rule: EqlRuleCreateProps = getEqlRuleForSignalTesting([ `.alerts-security.alerts-default`, ]); const { id } = await createRule(supertest, log, rule); @@ -651,10 +653,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with legacy index pattern', async () => { - const baseRule: ThresholdCreateSchema = getThresholdRuleForSignalTesting([ + const baseRule: ThresholdRuleCreateProps = getThresholdRuleForSignalTesting([ '.siem-signals-*', ]); - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...baseRule, threshold: { ...baseRule.threshold, @@ -672,10 +674,10 @@ export default ({ getService }: FtrProviderContext) => { }); it('should generate a signal-on-legacy-signal with AAD index pattern', async () => { - const baseRule: ThresholdCreateSchema = getThresholdRuleForSignalTesting([ + const baseRule: ThresholdRuleCreateProps = getThresholdRuleForSignalTesting([ `.alerts-security.alerts-default`, ]); - const rule: ThresholdCreateSchema = { + const rule: ThresholdRuleCreateProps = { ...baseRule, threshold: { ...baseRule.threshold, diff --git a/x-pack/test/detection_engine_api_integration/utils/create_rule.ts b/x-pack/test/detection_engine_api_integration/utils/create_rule.ts index ab162724ecb68..278bf0a92b40f 100644 --- a/x-pack/test/detection_engine_api_integration/utils/create_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/create_rule.ts @@ -8,9 +8,9 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; import type { - CreateRulesSchema, - FullResponseSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleCreateProps, + RuleResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { deleteRule } from './delete_rule'; @@ -27,8 +27,8 @@ import { deleteRule } from './delete_rule'; export const createRule = async ( supertest: SuperTest.SuperTest, log: ToolingLog, - rule: CreateRulesSchema -): Promise => { + rule: RuleCreateProps +): Promise => { const response = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/detection_engine_api_integration/utils/create_rule_with_auth.ts b/x-pack/test/detection_engine_api_integration/utils/create_rule_with_auth.ts index 266d01166d1b7..daa8ad420e4ca 100644 --- a/x-pack/test/detection_engine_api_integration/utils/create_rule_with_auth.ts +++ b/x-pack/test/detection_engine_api_integration/utils/create_rule_with_auth.ts @@ -9,9 +9,9 @@ import type SuperTest from 'supertest'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import type { - CreateRulesSchema, - FullResponseSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleCreateProps, + RuleResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * Helper to cut down on the noise in some of the tests. @@ -20,9 +20,9 @@ import type { */ export const createRuleWithAuth = async ( supertest: SuperTest.SuperTest, - rule: CreateRulesSchema, + rule: RuleCreateProps, auth: { user: string; pass: string } -): Promise => { +): Promise => { const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/detection_engine_api_integration/utils/create_rule_with_exception_entries.ts b/x-pack/test/detection_engine_api_integration/utils/create_rule_with_exception_entries.ts index 5b47de64d9c0f..d7f203eef82a4 100644 --- a/x-pack/test/detection_engine_api_integration/utils/create_rule_with_exception_entries.ts +++ b/x-pack/test/detection_engine_api_integration/utils/create_rule_with_exception_entries.ts @@ -9,9 +9,9 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; import type { NonEmptyEntriesArray, OsTypeArray } from '@kbn/securitysolution-io-ts-list-types'; import type { - CreateRulesSchema, - FullResponseSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleCreateProps, + RuleResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { createContainerWithEntries } from './create_container_with_entries'; @@ -31,13 +31,13 @@ import { createRule } from './create_rule'; export const createRuleWithExceptionEntries = async ( supertest: SuperTest.SuperTest, log: ToolingLog, - rule: CreateRulesSchema, + rule: RuleCreateProps, entries: NonEmptyEntriesArray[], endpointEntries?: Array<{ entries: NonEmptyEntriesArray; osTypes: OsTypeArray | undefined; }> -): Promise => { +): Promise => { const maybeExceptionList = await createContainerWithEntries(supertest, log, entries); const maybeEndpointList = await createContainerWithEndpointEntries( supertest, @@ -49,7 +49,7 @@ export const createRuleWithExceptionEntries = async ( // the rule to sometimes not filter correctly the first time with an exception list // or other timing issues. Then afterwards wait for the rule to have succeeded before // returning. - const ruleWithException: CreateRulesSchema = { + const ruleWithException: RuleCreateProps = { ...rule, enabled: false, exceptions_list: [...maybeExceptionList, ...maybeEndpointList], diff --git a/x-pack/test/detection_engine_api_integration/utils/delete_exception_list.ts b/x-pack/test/detection_engine_api_integration/utils/delete_exception_list.ts index 499f5b94a9752..fdb6975aae5de 100644 --- a/x-pack/test/detection_engine_api_integration/utils/delete_exception_list.ts +++ b/x-pack/test/detection_engine_api_integration/utils/delete_exception_list.ts @@ -8,7 +8,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; import { EXCEPTION_LIST_URL } from '@kbn/securitysolution-list-constants'; -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * Helper to cut down on the noise in some of the tests. Does a delete of an exception list. @@ -21,7 +21,7 @@ export const deleteExceptionList = async ( supertest: SuperTest.SuperTest, log: ToolingLog, listId: string -): Promise => { +): Promise => { const response = await supertest .delete(`${EXCEPTION_LIST_URL}?list_id=${listId}`) .set('kbn-xsrf', 'true'); diff --git a/x-pack/test/detection_engine_api_integration/utils/delete_rule.ts b/x-pack/test/detection_engine_api_integration/utils/delete_rule.ts index 2e01c61c33595..a1678464def71 100644 --- a/x-pack/test/detection_engine_api_integration/utils/delete_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/delete_rule.ts @@ -7,7 +7,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; @@ -22,7 +22,7 @@ export const deleteRule = async ( supertest: SuperTest.SuperTest, log: ToolingLog, ruleId: string -): Promise => { +): Promise => { const response = await supertest .delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleId}`) .set('kbn-xsrf', 'true'); diff --git a/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts b/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts index 0e6fe73685c48..40d3557bba6d4 100644 --- a/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts +++ b/x-pack/test/detection_engine_api_integration/utils/find_immutable_rule_by_id.ts @@ -7,7 +7,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; @@ -24,7 +24,7 @@ export const findImmutableRuleById = async ( page: number; perPage: number; total: number; - data: FullResponseSchema[]; + data: RuleResponse[]; }> => { const response = await supertest .get( diff --git a/x-pack/test/detection_engine_api_integration/utils/get_complex_rule.ts b/x-pack/test/detection_engine_api_integration/utils/get_complex_rule.ts index 4f5cfdcd3ba56..381f727f84585 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_complex_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_complex_rule.ts @@ -5,13 +5,13 @@ * 2.0. */ -import type { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This will return a complex rule with all the outputs possible * @param ruleId The ruleId to set which is optional and defaults to rule-1 */ -export const getComplexRule = (ruleId = 'rule-1'): CreateRulesSchema => ({ +export const getComplexRule = (ruleId = 'rule-1'): RuleCreateProps => ({ actions: [], author: [], name: 'Complex Rule Query', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_complex_rule_output.ts b/x-pack/test/detection_engine_api_integration/utils/get_complex_rule_output.ts index 1491829b33999..a8f5916c3598d 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_complex_rule_output.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_complex_rule_output.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; // TODO: Follow up https://github.com/elastic/kibana/pull/137628 and add an explicit type to this object // without using Partial @@ -13,7 +13,7 @@ import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/de * This will return a complex rule with all the outputs possible * @param ruleId The ruleId to set which is optional and defaults to rule-1 */ -export const getComplexRuleOutput = (ruleId = 'rule-1'): Partial => ({ +export const getComplexRuleOutput = (ruleId = 'rule-1'): Partial => ({ actions: [], author: [], created_by: 'elastic', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_eql_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_eql_rule_for_signal_testing.ts index 21a8509a16460..4e9d48916ff68 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_eql_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_eql_rule_for_signal_testing.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { EqlCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { EqlRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getRuleForSignalTesting } from './get_rule_for_signal_testing'; /** @@ -19,7 +19,7 @@ export const getEqlRuleForSignalTesting = ( index: string[], ruleId = 'eql-rule', enabled = true -): EqlCreateSchema => ({ +): EqlRuleCreateProps => ({ ...getRuleForSignalTesting(index, ruleId, enabled), type: 'eql', language: 'eql', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notification_so.ts b/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notification_so.ts index 9a084d800a2d8..836ad5390250e 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notification_so.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notification_so.ts @@ -6,9 +6,9 @@ */ import type { Client } from '@elastic/elasticsearch'; -import { SavedObjectReference } from '@kbn/core/server'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { LegacyRuleNotificationAlertTypeParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/notifications/legacy_types'; +import { SavedObjectReference } from '@kbn/core/server'; +import { LegacyRuleNotificationAlertTypeParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_actions_legacy'; interface LegacyActionNotificationSO extends LegacyRuleNotificationAlertTypeParams { references: SavedObjectReference[]; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notifications_so_by_id.ts b/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notifications_so_by_id.ts index 3120e85e899bf..2e104a454bf78 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notifications_so_by_id.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_notifications_so_by_id.ts @@ -6,9 +6,9 @@ */ import type { Client } from '@elastic/elasticsearch'; -import { SavedObjectReference } from '@kbn/core/server'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { LegacyRuleNotificationAlertTypeParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/notifications/legacy_types'; +import { SavedObjectReference } from '@kbn/core/server'; +import { LegacyRuleNotificationAlertTypeParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_actions_legacy'; interface LegacyActionNotificationSO extends LegacyRuleNotificationAlertTypeParams { references: SavedObjectReference[]; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_so.ts b/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_so.ts index 2c714614f9caa..57cf8b5efe71a 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_so.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_legacy_action_so.ts @@ -7,7 +7,7 @@ import type { Client } from '@elastic/elasticsearch'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { SavedObjectReference } from '@kbn/core/server'; -import type { LegacyRuleActions } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_actions/legacy_types'; +import type { LegacyRuleActions } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_actions_legacy'; interface LegacyActionSO extends LegacyRuleActions { references: SavedObjectReference[]; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_legacy_actions_so_by_id.ts b/x-pack/test/detection_engine_api_integration/utils/get_legacy_actions_so_by_id.ts index 48ea142aa28ca..1be0506359172 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_legacy_actions_so_by_id.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_legacy_actions_so_by_id.ts @@ -6,9 +6,9 @@ */ import type { Client } from '@elastic/elasticsearch'; -import { SavedObjectReference } from '@kbn/core/server'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import type { LegacyRuleActions } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_actions/legacy_types'; +import { SavedObjectReference } from '@kbn/core/server'; +import type { LegacyRuleActions } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_actions_legacy'; interface LegacyActionSO extends LegacyRuleActions { references: SavedObjectReference[]; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_open_signals.ts b/x-pack/test/detection_engine_api_integration/utils/get_open_signals.ts index f5d880cb3433e..ae370cb5886ea 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_open_signals.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_open_signals.ts @@ -9,7 +9,7 @@ import type SuperTest from 'supertest'; import type { Client } from '@elastic/elasticsearch'; import type { ToolingLog } from '@kbn/tooling-log'; import { RuleExecutionStatus } from '@kbn/security-solution-plugin/common/detection_engine/rule_monitoring'; -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { waitForRuleSuccessOrStatus } from './wait_for_rule_success_or_status'; import { refreshIndex } from './refresh_index'; @@ -19,7 +19,7 @@ export const getOpenSignals = async ( supertest: SuperTest.SuperTest, log: ToolingLog, es: Client, - rule: FullResponseSchema, + rule: RuleResponse, status: RuleExecutionStatus = RuleExecutionStatus.succeeded, size?: number ) => { diff --git a/x-pack/test/detection_engine_api_integration/utils/get_prepackaged_rule_status.ts b/x-pack/test/detection_engine_api_integration/utils/get_prepackaged_rule_status.ts index b6771cbb85f9c..df680cc12e9c8 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_prepackaged_rule_status.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_prepackaged_rule_status.ts @@ -7,9 +7,10 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; -import type { PrePackagedRulesAndTimelinesStatusSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/response'; - -import { DETECTION_ENGINE_PREPACKAGED_URL } from '@kbn/security-solution-plugin/common/constants'; +import { + PREBUILT_RULES_STATUS_URL, + GetPrebuiltRulesAndTimelinesStatusResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/prebuilt_rules'; /** * Helper to cut down on the noise in some of the tests. This @@ -19,11 +20,8 @@ import { DETECTION_ENGINE_PREPACKAGED_URL } from '@kbn/security-solution-plugin/ export const getPrePackagedRulesStatus = async ( supertest: SuperTest.SuperTest, log: ToolingLog -): Promise => { - const response = await supertest - .get(`${DETECTION_ENGINE_PREPACKAGED_URL}/_status`) - .set('kbn-xsrf', 'true') - .send(); +): Promise => { + const response = await supertest.get(PREBUILT_RULES_STATUS_URL).set('kbn-xsrf', 'true').send(); if (response.status !== 200) { log.error( diff --git a/x-pack/test/detection_engine_api_integration/utils/get_rule.ts b/x-pack/test/detection_engine_api_integration/utils/get_rule.ts index b1036e1f8b682..0c9e77179709e 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_rule.ts @@ -7,7 +7,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; @@ -21,7 +21,7 @@ export const getRule = async ( supertest: SuperTest.SuperTest, log: ToolingLog, ruleId: string -): Promise => { +): Promise => { const response = await supertest .get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleId}`) .set('kbn-xsrf', 'true'); diff --git a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts index ee07daad625c7..321e821682878 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { QueryCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { QueryRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a typical signal testing rule that is easy for most basic testing of output of signals. @@ -18,7 +18,7 @@ export const getRuleForSignalTesting = ( index: string[], ruleId = 'rule-1', enabled = true -): QueryCreateSchema => ({ +): QueryRuleCreateProps => ({ name: 'Signal Testing Query', description: 'Tests a simple query', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing_with_timestamp_override.ts b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing_with_timestamp_override.ts index d742e727137c5..24ac2298ab68f 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing_with_timestamp_override.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_rule_for_signal_testing_with_timestamp_override.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { QueryCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { QueryRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; export const getRuleForSignalTestingWithTimestampOverride = ( index: string[], ruleId = 'rule-1', enabled = true, timestampOverride = 'event.ingested' -): QueryCreateSchema => ({ +): QueryRuleCreateProps => ({ name: 'Signal Testing Query', description: 'Tests a simple query', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_rule_with_web_hook_action.ts b/x-pack/test/detection_engine_api_integration/utils/get_rule_with_web_hook_action.ts index 02aaf938b0003..838ef235638e6 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_rule_with_web_hook_action.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_rule_with_web_hook_action.ts @@ -6,16 +6,16 @@ */ import type { - CreateRulesSchema, - UpdateRulesSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleCreateProps, + RuleUpdateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getSimpleRule } from './get_simple_rule'; export const getRuleWithWebHookAction = ( id: string, enabled = false, - rule?: CreateRulesSchema -): CreateRulesSchema | UpdateRulesSchema => { + rule?: RuleCreateProps +): RuleCreateProps | RuleUpdateProps => { const finalRule = rule != null ? { ...rule, enabled } : getSimpleRule('rule-1', enabled); return { ...finalRule, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_saved_query_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_saved_query_rule_for_signal_testing.ts index da6c17d5a4026..12bca0207d4d6 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_saved_query_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_saved_query_rule_for_signal_testing.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { SavedQueryCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { SavedQueryRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getRuleForSignalTesting } from './get_rule_for_signal_testing'; /** @@ -19,7 +19,7 @@ export const getSavedQueryRuleForSignalTesting = ( index: string[], ruleId = 'saved-query-rule', enabled = true -): SavedQueryCreateSchema => ({ +): SavedQueryRuleCreateProps => ({ ...getRuleForSignalTesting(index, ruleId, enabled), type: 'saved_query', saved_id: 'abcd', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule.ts index 5cf6c1c41aff4..7c70774847c87 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a representative ML rule payload as expected by the server * @param ruleId The rule id * @param enabled Set to tru to enable it, by default it is off */ -export const getSimpleMlRule = (ruleId = 'rule-1', enabled = false): CreateRulesSchema => ({ +export const getSimpleMlRule = (ruleId = 'rule-1', enabled = false): RuleCreateProps => ({ name: 'Simple ML Rule', description: 'Simple Machine Learning Rule', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_output.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_output.ts index 56afa355b0482..754dbb1cd1149 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_output.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_output.ts @@ -5,11 +5,11 @@ * 2.0. */ -import type { MachineLearningResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { MachineLearningRule } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getMockSharedResponseSchema } from './get_simple_rule_output'; import { removeServerGeneratedProperties } from './remove_server_generated_properties'; -const getBaseMlRuleOutput = (ruleId = 'rule-1'): MachineLearningResponseSchema => { +const getBaseMlRuleOutput = (ruleId = 'rule-1'): MachineLearningRule => { return { ...getMockSharedResponseSchema(ruleId), name: 'Simple ML Rule', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_update.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_update.ts index b5200ddd86357..219fb3e425255 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_update.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_ml_rule_update.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { UpdateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleUpdateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a representative ML rule payload as expected by the server for an update * @param ruleId The rule id * @param enabled Set to tru to enable it, by default it is off */ -export const getSimpleMlRuleUpdate = (ruleId = 'rule-1', enabled = false): UpdateRulesSchema => ({ +export const getSimpleMlRuleUpdate = (ruleId = 'rule-1', enabled = false): RuleUpdateProps => ({ name: 'Simple ML Rule', description: 'Simple Machine Learning Rule', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_preview_rule.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_preview_rule.ts index fa67ae3eeba80..985728e9bec80 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_preview_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_preview_rule.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { PreviewRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { PreviewRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a typical simple preview rule for testing that is easy for most basic testing diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule.ts index a7e53a368b93c..e630ba9859e2f 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { QueryCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { QueryRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a typical simple rule for testing that is easy for most basic testing * @param ruleId * @param enabled Enables the rule on creation or not. Defaulted to true. */ -export const getSimpleRule = (ruleId = 'rule-1', enabled = false): QueryCreateSchema => ({ +export const getSimpleRule = (ruleId = 'rule-1', enabled = false): QueryRuleCreateProps => ({ name: 'Simple Rule Query', description: 'Simple Rule Query', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_output.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_output.ts index 8d8cca2e71133..9e869a91bf0b1 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_output.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_output.ts @@ -6,15 +6,15 @@ */ import type { - FullResponseSchema, - SharedResponseSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleResponse, + SharedResponseProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { removeServerGeneratedProperties } from './remove_server_generated_properties'; export const getMockSharedResponseSchema = ( ruleId = 'rule-1', enabled = false -): SharedResponseSchema => ({ +): SharedResponseProps => ({ actions: [], author: [], created_by: 'elastic', @@ -61,7 +61,7 @@ export const getMockSharedResponseSchema = ( namespace: undefined, }); -const getQueryRuleOutput = (ruleId = 'rule-1', enabled = false): FullResponseSchema => ({ +const getQueryRuleOutput = (ruleId = 'rule-1', enabled = false): RuleResponse => ({ ...getMockSharedResponseSchema(ruleId, enabled), index: ['auditbeat-*'], language: 'kuery', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_preview_output.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_preview_output.ts index 26fe0eafd1456..88f1efad4239e 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_preview_output.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_preview_output.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { RulePreviewLogs } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RulePreviewLogs } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is the typical output of a simple rule preview, with errors and warnings coming up from the rule diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_update.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_update.ts index f4365386a8328..43da256b4e793 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_update.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_update.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { UpdateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleUpdateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a typical simple rule for testing that is easy for most basic testing * @param ruleId The rule id * @param enabled Set to true to enable it, by default it is off */ -export const getSimpleRuleUpdate = (ruleId = 'rule-1', enabled = false): UpdateRulesSchema => ({ +export const getSimpleRuleUpdate = (ruleId = 'rule-1', enabled = false): RuleUpdateProps => ({ name: 'Simple Rule Query', description: 'Simple Rule Query', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_without_rule_id.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_without_rule_id.ts index 25994c8e6e14b..254cc044cbbe0 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_without_rule_id.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_rule_without_rule_id.ts @@ -5,13 +5,13 @@ * 2.0. */ -import type { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getSimpleRule } from './get_simple_rule'; /** * This is a typical simple rule for testing that is easy for most basic testing */ -export const getSimpleRuleWithoutRuleId = (): CreateRulesSchema => { +export const getSimpleRuleWithoutRuleId = (): RuleCreateProps => { const simpleRule = getSimpleRule(); // eslint-disable-next-line @typescript-eslint/naming-convention const { rule_id, ...ruleWithoutId } = simpleRule; diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_saved_query_rule.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_saved_query_rule.ts index 2fdd157c9c0d4..56571463f85e3 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_saved_query_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_saved_query_rule.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { SavedQueryCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { SavedQueryRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a typical simple saved_query rule for e2e testing @@ -15,7 +15,7 @@ import type { SavedQueryCreateSchema } from '@kbn/security-solution-plugin/commo export const getSimpleSavedQueryRule = ( ruleId = 'rule-1', enabled = false -): SavedQueryCreateSchema => ({ +): SavedQueryRuleCreateProps => ({ name: 'Simple Saved Query Rule', description: 'Simple Saved Query Rule', enabled, diff --git a/x-pack/test/detection_engine_api_integration/utils/get_simple_threat_match.ts b/x-pack/test/detection_engine_api_integration/utils/get_simple_threat_match.ts index 57cca015d2c4b..d3013be402377 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_simple_threat_match.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_simple_threat_match.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { ThreatMatchCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { ThreatMatchRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * This is a typical simple indicator match/threat match for testing that is easy for most basic testing @@ -15,7 +15,7 @@ import { ThreatMatchCreateSchema } from '@kbn/security-solution-plugin/common/de export const getSimpleThreatMatch = ( ruleId = 'rule-1', enabled = false -): ThreatMatchCreateSchema => ({ +): ThreatMatchRuleCreateProps => ({ description: 'Detecting root and admin users', name: 'Query with a rule id', severity: 'high', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_threat_match_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_threat_match_rule_for_signal_testing.ts index 3e663607c1186..24fa49c72cd09 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_threat_match_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_threat_match_rule_for_signal_testing.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { ThreatMatchCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { ThreatMatchRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getRuleForSignalTesting } from './get_rule_for_signal_testing'; /** @@ -19,7 +19,7 @@ export const getThreatMatchRuleForSignalTesting = ( index: string[], ruleId = 'threat-match-rule', enabled = true -): ThreatMatchCreateSchema => ({ +): ThreatMatchRuleCreateProps => ({ ...getRuleForSignalTesting(index, ruleId, enabled), type: 'threat_match', language: 'kuery', diff --git a/x-pack/test/detection_engine_api_integration/utils/get_threshold_rule_for_signal_testing.ts b/x-pack/test/detection_engine_api_integration/utils/get_threshold_rule_for_signal_testing.ts index aea1a5746bf78..d37ec2084d5a0 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_threshold_rule_for_signal_testing.ts +++ b/x-pack/test/detection_engine_api_integration/utils/get_threshold_rule_for_signal_testing.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { ThresholdCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { ThresholdRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { getRuleForSignalTesting } from './get_rule_for_signal_testing'; /** @@ -19,7 +19,7 @@ export const getThresholdRuleForSignalTesting = ( index: string[], ruleId = 'threshold-rule', enabled = true -): ThresholdCreateSchema => ({ +): ThresholdRuleCreateProps => ({ ...getRuleForSignalTesting(index, ruleId, enabled), type: 'threshold', language: 'kuery', diff --git a/x-pack/test/detection_engine_api_integration/utils/install_prepackaged_rules.ts b/x-pack/test/detection_engine_api_integration/utils/install_prepackaged_rules.ts index c75e8203bf6cd..53fb592e84d13 100644 --- a/x-pack/test/detection_engine_api_integration/utils/install_prepackaged_rules.ts +++ b/x-pack/test/detection_engine_api_integration/utils/install_prepackaged_rules.ts @@ -8,7 +8,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import type SuperTest from 'supertest'; -import { DETECTION_ENGINE_PREPACKAGED_URL } from '@kbn/security-solution-plugin/common/constants'; +import { PREBUILT_RULES_URL } from '@kbn/security-solution-plugin/common/detection_engine/prebuilt_rules'; import { countDownTest } from './count_down_test'; export const installPrePackagedRules = async ( @@ -18,7 +18,7 @@ export const installPrePackagedRules = async ( await countDownTest( async () => { const { status, body } = await supertest - .put(DETECTION_ENGINE_PREPACKAGED_URL) + .put(PREBUILT_RULES_URL) .set('kbn-xsrf', 'true') .send(); if (status !== 200) { diff --git a/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties.ts b/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties.ts index 8d8a34bba8b79..b5c0bd1864ca8 100644 --- a/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties.ts +++ b/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties.ts @@ -5,23 +5,20 @@ * 2.0. */ -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { omit, pickBy } from 'lodash'; const serverGeneratedProperties = ['id', 'created_at', 'updated_at', 'execution_summary'] as const; type ServerGeneratedProperties = typeof serverGeneratedProperties[number]; -export type RuleWithoutServerGeneratedProperties = Omit< - FullResponseSchema, - ServerGeneratedProperties ->; +export type RuleWithoutServerGeneratedProperties = Omit; /** * This will remove server generated properties such as date times, etc... * @param rule Rule to pass in to remove typical server generated properties */ export const removeServerGeneratedProperties = ( - rule: FullResponseSchema + rule: RuleResponse ): RuleWithoutServerGeneratedProperties => { const removedProperties = omit(rule, serverGeneratedProperties); diff --git a/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties_including_rule_id.ts b/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties_including_rule_id.ts index e8e7e1900afb7..2a37c1b659093 100644 --- a/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties_including_rule_id.ts +++ b/x-pack/test/detection_engine_api_integration/utils/remove_server_generated_properties_including_rule_id.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { FullResponseSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleResponse } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { removeServerGeneratedProperties } from './remove_server_generated_properties'; @@ -14,8 +14,8 @@ import { removeServerGeneratedProperties } from './remove_server_generated_prope * @param rule Rule to pass in to remove typical server generated properties */ export const removeServerGeneratedPropertiesIncludingRuleId = ( - rule: FullResponseSchema -): Partial => { + rule: RuleResponse +): Partial => { const ruleWithRemovedProperties = removeServerGeneratedProperties(rule); // eslint-disable-next-line @typescript-eslint/naming-convention const { rule_id, ...additionalRuledIdRemoved } = ruleWithRemovedProperties; diff --git a/x-pack/test/detection_engine_api_integration/utils/rule_to_ndjson.ts b/x-pack/test/detection_engine_api_integration/utils/rule_to_ndjson.ts index 1082212432c01..03e6d266a3deb 100644 --- a/x-pack/test/detection_engine_api_integration/utils/rule_to_ndjson.ts +++ b/x-pack/test/detection_engine_api_integration/utils/rule_to_ndjson.ts @@ -5,14 +5,14 @@ * 2.0. */ -import type { CreateRulesSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import type { RuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * Given a rule this will convert it to an ndjson buffer which is useful for * testing upload features. * @param rule The rule to convert to ndjson */ -export const ruleToNdjson = (rule: CreateRulesSchema): Buffer => { +export const ruleToNdjson = (rule: RuleCreateProps): Buffer => { const stringified = JSON.stringify(rule); return Buffer.from(`${stringified}\n`); }; diff --git a/x-pack/test/detection_engine_api_integration/utils/rule_to_update_schema.ts b/x-pack/test/detection_engine_api_integration/utils/rule_to_update_schema.ts index 32766c88978cd..7c10c98c105d6 100644 --- a/x-pack/test/detection_engine_api_integration/utils/rule_to_update_schema.ts +++ b/x-pack/test/detection_engine_api_integration/utils/rule_to_update_schema.ts @@ -6,9 +6,9 @@ */ import type { - FullResponseSchema, - UpdateRulesSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleResponse, + RuleUpdateProps, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { omit, pickBy } from 'lodash'; const propertiesToRemove = [ @@ -25,12 +25,12 @@ const propertiesToRemove = [ ]; /** - * transforms FullResponseSchema rule to UpdateRulesSchema + * transforms RuleResponse rule to RuleUpdateProps * returned result can be used in rule update API calls */ -export const ruleToUpdateSchema = (rule: FullResponseSchema): UpdateRulesSchema => { +export const ruleToUpdateSchema = (rule: RuleResponse): RuleUpdateProps => { const removedProperties = omit(rule, propertiesToRemove); // We're only removing undefined values, so this cast correctly narrows the type - return pickBy(removedProperties, (value) => value !== undefined) as UpdateRulesSchema; + return pickBy(removedProperties, (value) => value !== undefined) as RuleUpdateProps; }; diff --git a/x-pack/test/detection_engine_api_integration/utils/update_rule.ts b/x-pack/test/detection_engine_api_integration/utils/update_rule.ts index c66d86c5594d0..cee09bc80a6c0 100644 --- a/x-pack/test/detection_engine_api_integration/utils/update_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/update_rule.ts @@ -10,9 +10,9 @@ import type SuperTest from 'supertest'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { - UpdateRulesSchema, - FullResponseSchema, -} from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; + RuleUpdateProps, + RuleResponse, +} from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; /** * Helper to cut down on the noise in some of the tests. This checks for @@ -23,8 +23,8 @@ import { export const updateRule = async ( supertest: SuperTest.SuperTest, log: ToolingLog, - updatedRule: UpdateRulesSchema -): Promise => { + updatedRule: RuleUpdateProps +): Promise => { const response = await supertest .put(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts index 11982a8b51425..2785fece6d90a 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/search_strategy.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { AlertConsumers } from '@kbn/rule-data-utils'; import { RuleRegistrySearchResponse } from '@kbn/rule-registry-plugin/common/search_strategy'; -import { QueryCreateSchema } from '@kbn/security-solution-plugin/common/detection_engine/schemas/request'; +import { QueryRuleCreateProps } from '@kbn/security-solution-plugin/common/detection_engine/rule_schema'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { deleteSignalsIndex, @@ -118,7 +118,7 @@ export default ({ getService }: FtrProviderContext) => { await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'); await esArchiver.load('x-pack/test/functional/es_archives/observability/alerts'); - const rule: QueryCreateSchema = { + const rule: QueryRuleCreateProps = { ...getRuleForSignalTesting(['auditbeat-*']), query: `_id:${ID}`, }; diff --git a/x-pack/test/security_solution_ftr/services/detections/index.ts b/x-pack/test/security_solution_ftr/services/detections/index.ts index 1d3e18f1ab43d..024dede892be5 100644 --- a/x-pack/test/security_solution_ftr/services/detections/index.ts +++ b/x-pack/test/security_solution_ftr/services/detections/index.ts @@ -13,8 +13,8 @@ import { DETECTION_ENGINE_RULES_URL, } from '@kbn/security-solution-plugin/common/constants'; import { estypes } from '@elastic/elasticsearch'; -import endpointPrePackagedRule from '@kbn/security-solution-plugin/server/lib/detection_engine/rules/prepackaged_rules/elastic_endpoint_security.json'; -import { Rule } from '@kbn/security-solution-plugin/public/detections/containers/detection_engine/rules'; +import endpointPrePackagedRule from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/elastic_endpoint_security.json'; +import { Rule } from '@kbn/security-solution-plugin/public/detection_engine/rule_management/logic/types'; import { FtrService } from '../../../functional/ftr_provider_context'; export class DetectionsTestService extends FtrService {