From 63ecace17d7d38ae2ef7519fe15d2d205a200550 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Thu, 6 Jun 2024 17:57:38 +0200 Subject: [PATCH 1/4] Refactor DetectionRulesClient --- .../rule_objects/create_prebuilt_rules.ts | 2 +- .../rule_objects/upgrade_prebuilt_rules.ts | 2 +- .../routes/__mocks__/request_context.ts | 2 +- .../api/create_rule_exceptions/route.ts | 4 +- .../fetch_rules_by_query_or_ids.ts | 2 +- .../api/rules/bulk_actions/route.test.ts | 4 +- .../api/rules/bulk_create_rules/route.ts | 2 +- .../api/rules/bulk_delete_rules/route.ts | 2 +- .../api/rules/bulk_patch_rules/route.ts | 2 +- .../api/rules/bulk_update_rules/route.ts | 2 +- .../api/rules/create_rule/route.ts | 2 +- .../api/rules/delete_rule/route.ts | 2 +- .../api/rules/patch_rule/route.ts | 2 +- .../api/rules/read_rule/route.ts | 2 +- .../api/rules/update_rule/route.ts | 2 +- .../__mocks__/detection_rules_client.ts | 2 +- .../__mocks__/read_rules.ts | 0 ...delete_rule.detection_rules_client.test.ts | 2 +- ...n_rules_client.create_custom_rule.test.ts} | 2 +- ...rules_client.create_prebuilt_rule.test.ts} | 2 +- ...etection_rules_client.import_rule.test.ts} | 12 +-- ...detection_rules_client.patch_rule.test.ts} | 2 +- .../detection_rules_client.ts | 78 ++++++++++++++++ ...etection_rules_client.update_rule.test.ts} | 24 ++--- ...ules_client.upgrade_prebuilt_rule.test.ts} | 2 +- .../detection_rules_client_interface.ts | 58 ++++++++++++ .../methods/create_custom_rule.ts | 30 +++++++ .../methods/create_prebuilt_rule.ts | 35 ++++++++ .../methods/delete_rule.ts | 14 +++ .../methods/import_rule.ts | 63 +++++++++++++ .../methods/patch_rule.ts | 54 +++++++++++ .../methods/update_rule.ts | 53 +++++++++++ .../methods/upgrade_prebuilt_rule.ts | 84 +++++++++++++++++ .../read_rules.test.ts | 0 .../read_rules.ts | 0 .../utils.ts | 0 .../logic/import/import_rules_utils.ts | 6 +- .../rule_management/create_custom_rule.ts | 36 -------- .../rule_management/create_prebuilt_rule.ts | 41 --------- .../logic/rule_management/delete_rule.ts | 23 ----- .../rule_management/detection_rules_client.ts | 80 ----------------- .../logic/rule_management/import_rule.ts | 75 ---------------- .../logic/rule_management/patch_rule.ts | 60 ------------- .../logic/rule_management/update_rule.ts | 59 ------------ .../rule_management/upgrade_prebuilt_rule.ts | 90 ------------------- .../rule_objects/fetch_rule_by_id.ts | 2 +- .../server/request_context_factory.ts | 6 +- .../plugins/security_solution/server/types.ts | 2 +- 48 files changed, 519 insertions(+), 512 deletions(-) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management => detection_rules_client}/__mocks__/detection_rules_client.ts (97%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management => detection_rules_client}/__mocks__/read_rules.ts (100%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management => detection_rules_client}/delete_rule.detection_rules_client.test.ts (98%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management/create_custom_rule.detection_rules_client.test.ts => detection_rules_client/detection_rules_client.create_custom_rule.test.ts} (99%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management/create_prebuilt_rule.detection_rules_client.test.ts => detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts} (99%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management/import_rule.detection_rules_client.test.ts => detection_rules_client/detection_rules_client.import_rule.test.ts} (95%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management/patch_rule.detection_rules_client.test.ts => detection_rules_client/detection_rules_client.patch_rule.test.ts} (99%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management/update_rule.detection_rules_client.test.ts => detection_rules_client/detection_rules_client.update_rule.test.ts} (89%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts => detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts} (99%) create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_custom_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_prebuilt_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/delete_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts create mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management => detection_rules_client}/read_rules.test.ts (100%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management => detection_rules_client}/read_rules.ts (100%) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/{rule_management => detection_rules_client}/utils.ts (100%) delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/create_prebuilt_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/create_prebuilt_rules.ts index ef3d34b657505..8da1055156d3d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/create_prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/create_prebuilt_rules.ts @@ -9,7 +9,7 @@ import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../../common/consta import { initPromisePool } from '../../../../../utils/promise_pool'; import { withSecuritySpan } from '../../../../../utils/with_security_span'; import type { PrebuiltRuleAsset } from '../../model/rule_assets/prebuilt_rule_asset'; -import type { IDetectionRulesClient } from '../../../rule_management/logic/rule_management/detection_rules_client'; +import type { IDetectionRulesClient } from '../../../rule_management/logic/detection_rules_client/detection_rules_client_interface'; export const createPrebuiltRules = ( detectionRulesClient: IDetectionRulesClient, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts index 4ae595cca16b0..2c9a81a7af6ce 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts @@ -9,7 +9,7 @@ import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../../common/consta import { initPromisePool } from '../../../../../utils/promise_pool'; import { withSecuritySpan } from '../../../../../utils/with_security_span'; import type { PrebuiltRuleAsset } from '../../model/rule_assets/prebuilt_rule_asset'; -import type { IDetectionRulesClient } from '../../../rule_management/logic/rule_management/detection_rules_client'; +import type { IDetectionRulesClient } from '../../../rule_management/logic/detection_rules_client/detection_rules_client_interface'; /** * Upgrades existing prebuilt rules given a set of rules and output index. diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts index a2e6f2f038546..fa9fcc1fa5e22 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts @@ -38,7 +38,7 @@ import { riskEngineDataClientMock } from '../../../entity_analytics/risk_engine/ import { riskScoreDataClientMock } from '../../../entity_analytics/risk_score/risk_score_data_client.mock'; import { assetCriticalityDataClientMock } from '../../../entity_analytics/asset_criticality/asset_criticality_data_client.mock'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; -import { detectionRulesClientMock } from '../../rule_management/logic/rule_management/__mocks__/detection_rules_client'; +import { detectionRulesClientMock } from '../../rule_management/logic/detection_rules_client/__mocks__/detection_rules_client'; export const createMockClients = () => { const core = coreMock.createRequestHandlerContext(); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts index c5dfc3a0d847e..c8c257770e26a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_exceptions/api/create_rule_exceptions/route.ts @@ -37,13 +37,13 @@ import { CreateRuleExceptionsRequestParams, } from '../../../../../../common/api/detection_engine/rule_exceptions'; -import { readRules } from '../../../rule_management/logic/rule_management/read_rules'; +import { readRules } from '../../../rule_management/logic/detection_rules_client/read_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'; -import type { IDetectionRulesClient } from '../../../rule_management/logic/rule_management/detection_rules_client'; +import type { IDetectionRulesClient } from '../../../rule_management/logic/detection_rules_client/detection_rules_client_interface'; export const createRuleExceptionsRoute = (router: SecuritySolutionPluginRouter) => { router.versioned diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/fetch_rules_by_query_or_ids.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/fetch_rules_by_query_or_ids.ts index 1ef231bb0b5ad..d59ba5676b607 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/fetch_rules_by_query_or_ids.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/fetch_rules_by_query_or_ids.ts @@ -11,7 +11,7 @@ import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../../../common/con import type { PromisePoolOutcome } from '../../../../../../utils/promise_pool'; import { initPromisePool } from '../../../../../../utils/promise_pool'; import type { RuleAlertType } from '../../../../rule_schema'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { findRules } from '../../../logic/search/find_rules'; import { MAX_RULES_TO_PROCESS_TOTAL } from './route'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts index d74afe0bea65e..37ad3dc7d8487 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_actions/route.test.ts @@ -30,10 +30,10 @@ import { getBulkDisableRuleActionSchemaMock, } from '../../../../../../../common/api/detection_engine/rule_management/mocks'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; jest.mock('../../../../../machine_learning/authz'); -jest.mock('../../../logic/rule_management/read_rules', () => ({ readRules: jest.fn() })); +jest.mock('../../../logic/detection_rules_client/read_rules', () => ({ readRules: jest.fn() })); describe('Perform bulk action route', () => { const readRulesMock = readRules as jest.Mock; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts index e4373e1563532..a8e5a0446c6e3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_create_rules/route.ts @@ -16,7 +16,7 @@ import { } from '../../../../../../../common/api/detection_engine/rule_management'; import type { SecuritySolutionPluginRouter } from '../../../../../../types'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { getDuplicates } from './get_duplicates'; import { transformValidateBulkError } from '../../../utils/validate'; import { buildRouteValidationWithZod } from '../../../../../../utils/build_validation/route_validation'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts index 2ac6fb3340bab..234439eb49052 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_delete_rules/route.ts @@ -24,7 +24,7 @@ import { createBulkErrorObject, transformBulkError, } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { getIdBulkError } from '../../../utils/utils'; import { transformValidateBulkError } from '../../../utils/validate'; import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts index 1ed5f529b2014..a3752d421380b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_patch_rules/route.ts @@ -19,7 +19,7 @@ import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { transformBulkError, buildSiemResponse } from '../../../../routes/utils'; import { getIdBulkError } from '../../../utils/utils'; import { transformValidateBulkError } from '../../../utils/validate'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; import { validateRuleDefaultExceptionList } from '../../../logic/exceptions/validate_rule_default_exception_list'; import { validateRulesWithDuplicatedDefaultExceptionsList } from '../../../logic/exceptions/validate_rules_with_duplicated_default_exceptions_list'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts index 2b3ee7c2f751a..e08d781cd74d8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/bulk_update_rules/route.ts @@ -24,7 +24,7 @@ import { buildSiemResponse, createBulkErrorObject, } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { getDeprecatedBulkEndpointHeader, logDeprecatedBulkEndpoint } from '../../deprecation'; import { validateRuleDefaultExceptionList } from '../../../logic/exceptions/validate_rule_default_exception_list'; import { validateRulesWithDuplicatedDefaultExceptionsList } from '../../../logic/exceptions/validate_rules_with_duplicated_default_exceptions_list'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts index db01f1f783892..03642aa12266b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/create_rule/route.ts @@ -16,7 +16,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constant import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { buildRouteValidationWithZod } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { checkDefaultRuleExceptionListReferences } from '../../../logic/exceptions/check_for_default_rule_exception_list'; import { validateRuleDefaultExceptionList } from '../../../logic/exceptions/validate_rule_default_exception_list'; import { transformValidate, validateResponseActionsPermissions } from '../../../utils/validate'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts index 31b72c76daaa6..3cf9aa6a2fb55 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/delete_rule/route.ts @@ -16,7 +16,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constant import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { buildRouteValidationWithZod } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { getIdError, transform } from '../../../utils/utils'; export const deleteRuleRoute = (router: SecuritySolutionPluginRouter) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts index 78c5a15ef0581..38b283b2c5fb6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/patch_rule/route.ts @@ -16,7 +16,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constant import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { buildRouteValidationWithZod } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { checkDefaultRuleExceptionListReferences } from '../../../logic/exceptions/check_for_default_rule_exception_list'; import { validateRuleDefaultExceptionList } from '../../../logic/exceptions/validate_rule_default_exception_list'; import { getIdError } from '../../../utils/utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts index aabf538367930..95992618b0625 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/read_rule/route.ts @@ -16,7 +16,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constant import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { buildRouteValidationWithZod } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { getIdError, transform } from '../../../utils/utils'; export const readRuleRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts index 8c46e1979a43d..5ac2df600908c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/api/rules/update_rule/route.ts @@ -16,7 +16,7 @@ import { DETECTION_ENGINE_RULES_URL } from '../../../../../../../common/constant import type { SecuritySolutionPluginRouter } from '../../../../../../types'; import { buildRouteValidationWithZod } from '../../../../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../../../routes/utils'; -import { readRules } from '../../../logic/rule_management/read_rules'; +import { readRules } from '../../../logic/detection_rules_client/read_rules'; import { checkDefaultRuleExceptionListReferences } from '../../../logic/exceptions/check_for_default_rule_exception_list'; import { validateRuleDefaultExceptionList } from '../../../logic/exceptions/validate_rule_default_exception_list'; import { getIdError } from '../../../utils/utils'; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/__mocks__/detection_rules_client.ts similarity index 97% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/__mocks__/detection_rules_client.ts index 2411de933fb1f..b6d14a307801e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/detection_rules_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/__mocks__/detection_rules_client.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { IDetectionRulesClient } from '../detection_rules_client'; +import type { IDetectionRulesClient } from '../detection_rules_client_interface'; export type DetectionRulesClientMock = jest.Mocked; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/read_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/__mocks__/read_rules.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/__mocks__/read_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/__mocks__/read_rules.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/delete_rule.detection_rules_client.test.ts similarity index 98% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/delete_rule.detection_rules_client.test.ts index 2182927a373df..37cb8e0aa709e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/delete_rule.detection_rules_client.test.ts @@ -8,7 +8,7 @@ import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { createDetectionRulesClient } from './detection_rules_client'; -import type { IDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts index 6053d5109676c..a8335108d7cbe 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_custom_rule.test.ts @@ -16,7 +16,7 @@ import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../../common/constant import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; import { createDetectionRulesClient } from './detection_rules_client'; -import type { IDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts index c6d80ad412dc5..d2a61dcc65e45 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.create_prebuilt_rule.test.ts @@ -16,7 +16,7 @@ import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../../../../common/constant import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; import { createDetectionRulesClient } from './detection_rules_client'; -import type { IDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts similarity index 95% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts index f783c5963c2be..4d2cb0ee65519 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.import_rule.test.ts @@ -13,7 +13,7 @@ import { getQueryRuleParams } from '../../../rule_schema/mocks'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; import { createDetectionRulesClient } from './detection_rules_client'; -import type { IDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); @@ -50,7 +50,7 @@ describe('DetectionRulesClient.importRule', () => { await detectionRulesClient.importRule({ ruleToImport, overwriteRules: true, - options: { allowMissingConnectorSecrets }, + allowMissingConnectorSecrets, }); expect(rulesClient.create).toHaveBeenCalledWith( @@ -78,7 +78,7 @@ describe('DetectionRulesClient.importRule', () => { detectionRulesClient.importRule({ ruleToImport, overwriteRules: true, - options: { allowMissingConnectorSecrets }, + allowMissingConnectorSecrets, }) ).rejects.toThrow('mocked MLAuth error'); @@ -92,7 +92,7 @@ describe('DetectionRulesClient.importRule', () => { await detectionRulesClient.importRule({ ruleToImport, overwriteRules: true, - options: { allowMissingConnectorSecrets }, + allowMissingConnectorSecrets, }); expect(rulesClient.update).toHaveBeenCalledWith( @@ -133,7 +133,7 @@ describe('DetectionRulesClient.importRule', () => { timestamp_override: undefined, }, overwriteRules: true, - options: { allowMissingConnectorSecrets }, + allowMissingConnectorSecrets, }); expect(rulesClient.create).not.toHaveBeenCalled(); @@ -154,7 +154,7 @@ describe('DetectionRulesClient.importRule', () => { detectionRulesClient.importRule({ ruleToImport, overwriteRules: false, - options: { allowMissingConnectorSecrets }, + allowMissingConnectorSecrets, }) ).rejects.toMatchObject({ error: { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts index 59d250606e285..7f1c219888636 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.patch_rule.test.ts @@ -17,7 +17,7 @@ import { readRules } from './read_rules'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; import { createDetectionRulesClient } from './detection_rules_client'; -import type { IDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts new file mode 100644 index 0000000000000..73477cbbadf3b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts @@ -0,0 +1,78 @@ +/* + * 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 type { MlAuthz } from '../../../../machine_learning/authz'; + +import type { RuleAlertType } from '../../../rule_schema'; +import type { + IDetectionRulesClient, + CreateCustomRuleArgs, + CreatePrebuiltRuleArgs, + UpdateRuleArgs, + PatchRuleArgs, + DeleteRuleArgs, + UpgradePrebuiltRuleArgs, + ImportRuleArgs, +} from './detection_rules_client_interface'; + +import { createCustomRule } from './methods/create_custom_rule'; +import { createPrebuiltRule } from './methods/create_prebuilt_rule'; +import { updateRule } from './methods/update_rule'; +import { patchRule } from './methods/patch_rule'; +import { deleteRule } from './methods/delete_rule'; +import { upgradePrebuiltRule } from './methods/upgrade_prebuilt_rule'; +import { importRule } from './methods/import_rule'; + +import { withSecuritySpan } from '../../../../../utils/with_security_span'; + +export const createDetectionRulesClient = ( + rulesClient: RulesClient, + mlAuthz: MlAuthz +): IDetectionRulesClient => ({ + async createCustomRule(args: CreateCustomRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.createCustomRule', async () => { + return createCustomRule(rulesClient, args, mlAuthz); + }); + }, + + async createPrebuiltRule(args: CreatePrebuiltRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.createPrebuiltRule', async () => { + return createPrebuiltRule(rulesClient, args, mlAuthz); + }); + }, + + async updateRule(args: UpdateRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.updateRule', async () => { + return updateRule(rulesClient, args, mlAuthz); + }); + }, + + async patchRule(args: PatchRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.createCustomRule', async () => { + return patchRule(rulesClient, args, mlAuthz); + }); + }, + + async deleteRule(args: DeleteRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.deleteRule', async () => { + return deleteRule(rulesClient, args); + }); + }, + + async upgradePrebuiltRule(args: UpgradePrebuiltRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.upgradePrebuiltRule', async () => { + return upgradePrebuiltRule(rulesClient, args, mlAuthz); + }); + }, + + async importRule(args: ImportRuleArgs): Promise { + return withSecuritySpan('DetectionRulesClient.importRule', async () => { + return importRule(rulesClient, args, mlAuthz); + }); + }, +}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts similarity index 89% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts index f538672444b0e..671460b046fea 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.update_rule.test.ts @@ -13,10 +13,11 @@ import { getCreateMachineLearningRulesSchemaMock, getCreateRulesSchemaMock, } from '../../../../../../common/api/detection_engine/model/rule_schema/mocks'; -import { updateRule } from './update_rule'; import { readRules } from './read_rules'; import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; +import { createDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); @@ -25,10 +26,13 @@ jest.mock('./read_rules'); describe('DetectionRulesClient.updateRule', () => { let rulesClient: ReturnType; + let detectionRulesClient: IDetectionRulesClient; + const mlAuthz = (buildMlAuthz as jest.Mock)(); beforeEach(() => { rulesClient = rulesClientMock.create(); + detectionRulesClient = createDetectionRulesClient(rulesClient, mlAuthz); }); it('calls the rulesClient with expected params', async () => { @@ -37,7 +41,7 @@ describe('DetectionRulesClient.updateRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -58,7 +62,7 @@ describe('DetectionRulesClient.updateRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - const rule = await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + const rule = await detectionRulesClient.updateRule({ ruleUpdate }); expect(rule.enabled).toBe(true); }); @@ -69,7 +73,7 @@ describe('DetectionRulesClient.updateRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getMlRuleParams())); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -92,7 +96,7 @@ describe('DetectionRulesClient.updateRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getMlRuleParams())); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -118,7 +122,7 @@ describe('DetectionRulesClient.updateRule', () => { rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); (readRules as jest.Mock).mockResolvedValueOnce(existingRule); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.disable).toHaveBeenCalledWith( expect.objectContaining({ @@ -139,7 +143,7 @@ describe('DetectionRulesClient.updateRule', () => { rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); (readRules as jest.Mock).mockResolvedValueOnce(existingRule); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.enable).toHaveBeenCalledWith( expect.objectContaining({ @@ -158,7 +162,7 @@ describe('DetectionRulesClient.updateRule', () => { enabled: true, }; - await expect(updateRule(rulesClient, { ruleUpdate }, mlAuthz)).rejects.toThrow( + await expect(detectionRulesClient.updateRule({ ruleUpdate })).rejects.toThrow( 'mocked MLAuth error' ); @@ -184,7 +188,7 @@ describe('DetectionRulesClient.updateRule', () => { (readRules as jest.Mock).mockResolvedValueOnce(existingRule); rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ @@ -222,7 +226,7 @@ describe('DetectionRulesClient.updateRule', () => { rulesClient.update.mockResolvedValue(getRuleMock(getQueryRuleParams())); (readRules as jest.Mock).mockResolvedValueOnce(existingRule); - await updateRule(rulesClient, { ruleUpdate }, mlAuthz); + await detectionRulesClient.updateRule({ ruleUpdate }); expect(rulesClient.update).toHaveBeenCalledWith( expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts similarity index 99% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts index 50dc69b660c0f..97a564cbf86e6 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.detection_rules_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.upgrade_prebuilt_rule.test.ts @@ -20,7 +20,7 @@ import { getEqlRuleParams, getQueryRuleParams } from '../../../rule_schema/mocks import { buildMlAuthz } from '../../../../machine_learning/authz'; import { throwAuthzError } from '../../../../machine_learning/validation'; import { createDetectionRulesClient } from './detection_rules_client'; -import type { IDetectionRulesClient } from './detection_rules_client'; +import type { IDetectionRulesClient } from './detection_rules_client_interface'; jest.mock('../../../../machine_learning/authz'); jest.mock('../../../../machine_learning/validation'); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface.ts new file mode 100644 index 0000000000000..d99b0b9c2cbd0 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface.ts @@ -0,0 +1,58 @@ +/* + * 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 '../../../../../../common/api/detection_engine/model/rule_schema'; +import type { PrebuiltRuleAsset } from '../../../prebuilt_rules'; +import type { + RuleUpdateProps, + RulePatchProps, + RuleObjectId, + RuleToImport, +} from '../../../../../../common/api/detection_engine'; +import type { RuleAlertType } from '../../../rule_schema'; + +export interface IDetectionRulesClient { + createCustomRule: (createCustomRulePayload: CreateCustomRuleArgs) => Promise; + createPrebuiltRule: (createPrebuiltRulePayload: CreatePrebuiltRuleArgs) => Promise; + updateRule: (updateRulePayload: UpdateRuleArgs) => Promise; + patchRule: (patchRulePayload: PatchRuleArgs) => Promise; + deleteRule: (deleteRulePayload: DeleteRuleArgs) => Promise; + upgradePrebuiltRule: ( + upgradePrebuiltRulePayload: UpgradePrebuiltRuleArgs + ) => Promise; + importRule: (importRulePayload: ImportRuleArgs) => Promise; +} + +export interface CreateCustomRuleArgs { + params: RuleCreateProps; +} + +export interface CreatePrebuiltRuleArgs { + ruleAsset: PrebuiltRuleAsset; +} + +export interface UpdateRuleArgs { + ruleUpdate: RuleUpdateProps; +} + +export interface PatchRuleArgs { + nextParams: RulePatchProps; +} + +export interface DeleteRuleArgs { + ruleId: RuleObjectId; +} + +export interface UpgradePrebuiltRuleArgs { + ruleAsset: PrebuiltRuleAsset; +} + +export interface ImportRuleArgs { + ruleToImport: RuleToImport; + overwriteRules?: boolean; + allowMissingConnectorSecrets?: boolean; +} diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_custom_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_custom_rule.ts new file mode 100644 index 0000000000000..c9b3b7b542a17 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_custom_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { CreateCustomRuleArgs } from '../detection_rules_client_interface'; +import type { MlAuthz } from '../../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../../rule_schema'; +import { convertCreateAPIToInternalSchema } from '../../../normalization/rule_converters'; + +import { validateMlAuth } from '../utils'; + +export const createCustomRule = async ( + rulesClient: RulesClient, + args: CreateCustomRuleArgs, + mlAuthz: MlAuthz +): Promise => { + const { params } = args; + await validateMlAuth(mlAuthz, params.type); + + const internalRule = convertCreateAPIToInternalSchema(params, { immutable: false }); + const rule = await rulesClient.create({ + data: internalRule, + }); + + return rule; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_prebuilt_rule.ts new file mode 100644 index 0000000000000..0ada0197137a4 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/create_prebuilt_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { CreatePrebuiltRuleArgs } from '../detection_rules_client_interface'; +import type { MlAuthz } from '../../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../../rule_schema'; +import { convertCreateAPIToInternalSchema } from '../../../normalization/rule_converters'; + +import { validateMlAuth } from '../utils'; + +export const createPrebuiltRule = async ( + rulesClient: RulesClient, + args: CreatePrebuiltRuleArgs, + mlAuthz: MlAuthz +): Promise => { + const { ruleAsset } = args; + + await validateMlAuth(mlAuthz, ruleAsset.type); + + const internalRule = convertCreateAPIToInternalSchema(ruleAsset, { + immutable: true, + defaultEnabled: false, + }); + + const rule = await rulesClient.create({ + data: internalRule, + }); + + return rule; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/delete_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/delete_rule.ts new file mode 100644 index 0000000000000..ec1491e8159d7 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/delete_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { DeleteRuleArgs } from '../detection_rules_client_interface'; + +export const deleteRule = async (rulesClient: RulesClient, args: DeleteRuleArgs): Promise => { + const { ruleId } = args; + await rulesClient.delete({ id: ruleId }); +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.ts new file mode 100644 index 0000000000000..8761478e30eda --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/import_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { MlAuthz } from '../../../../../machine_learning/authz'; +import type { ImportRuleArgs } from '../detection_rules_client_interface'; +import type { RuleAlertType, RuleParams } from '../../../../rule_schema'; +import { createBulkErrorObject } from '../../../../routes/utils'; +import { + convertCreateAPIToInternalSchema, + convertUpdateAPIToInternalSchema, +} from '../../../normalization/rule_converters'; + +import { validateMlAuth } from '../utils'; + +import { readRules } from '../read_rules'; + +export const importRule = async ( + rulesClient: RulesClient, + importRulePayload: ImportRuleArgs, + mlAuthz: MlAuthz +): Promise => { + const { ruleToImport, overwriteRules, allowMissingConnectorSecrets } = importRulePayload; + + await validateMlAuth(mlAuthz, ruleToImport.type); + + const existingRule = await readRules({ + rulesClient, + ruleId: ruleToImport.rule_id, + id: undefined, + }); + + if (!existingRule) { + const internalRule = convertCreateAPIToInternalSchema(ruleToImport, { + immutable: false, + }); + + return rulesClient.create({ + data: internalRule, + allowMissingConnectorSecrets, + }); + } else if (existingRule && overwriteRules) { + const newInternalRule = convertUpdateAPIToInternalSchema({ + existingRule, + ruleUpdate: ruleToImport, + }); + + return rulesClient.update({ + id: existingRule.id, + data: newInternalRule, + }); + } else { + throw createBulkErrorObject({ + ruleId: existingRule.params.ruleId, + statusCode: 409, + message: `rule_id: "${existingRule.params.ruleId}" already exists`, + }); + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.ts new file mode 100644 index 0000000000000..b7c8c1539d664 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/patch_rule.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 { RulesClient } from '@kbn/alerting-plugin/server'; +import type { MlAuthz } from '../../../../../machine_learning/authz'; +import type { PatchRuleArgs } from '../detection_rules_client_interface'; +import type { RuleAlertType } from '../../../../rule_schema'; +import { getIdError } from '../../../utils/utils'; +import { convertPatchAPIToInternalSchema } from '../../../normalization/rule_converters'; + +import { validateMlAuth, ClientError, toggleRuleEnabledOnUpdate } from '../utils'; + +import { readRules } from '../read_rules'; + +export const patchRule = async ( + rulesClient: RulesClient, + args: PatchRuleArgs, + mlAuthz: MlAuthz +): Promise => { + const { nextParams } = args; + const { rule_id: ruleId, id } = nextParams; + + const existingRule = await readRules({ + rulesClient, + ruleId, + id, + }); + + if (existingRule == null) { + const error = getIdError({ id, ruleId }); + throw new ClientError(error.message, error.statusCode); + } + + await validateMlAuth(mlAuthz, nextParams.type ?? existingRule.params.type); + + const patchedRule = convertPatchAPIToInternalSchema(nextParams, existingRule); + + const update = await rulesClient.update({ + id: existingRule.id, + data: patchedRule, + }); + + await toggleRuleEnabledOnUpdate(rulesClient, existingRule, nextParams.enabled); + + if (nextParams.enabled != null) { + return { ...update, enabled: nextParams.enabled }; + } else { + return update; + } +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts new file mode 100644 index 0000000000000..a37b5eaddcee0 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/update_rule.ts @@ -0,0 +1,53 @@ +/* + * 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 type { MlAuthz } from '../../../../../machine_learning/authz'; +import type { RuleAlertType } from '../../../../rule_schema'; +import type { UpdateRuleArgs } from '../detection_rules_client_interface'; +import { getIdError } from '../../../utils/utils'; +import { convertUpdateAPIToInternalSchema } from '../../../normalization/rule_converters'; + +import { validateMlAuth, ClientError, toggleRuleEnabledOnUpdate } from '../utils'; + +import { readRules } from '../read_rules'; + +export const updateRule = async ( + rulesClient: RulesClient, + args: UpdateRuleArgs, + mlAuthz: MlAuthz +): Promise => { + const { ruleUpdate } = args; + const { rule_id: ruleId, id } = ruleUpdate; + + await validateMlAuth(mlAuthz, ruleUpdate.type); + + const existingRule = await readRules({ + rulesClient, + ruleId, + id, + }); + + if (existingRule == null) { + const error = getIdError({ id, ruleId }); + throw new ClientError(error.message, error.statusCode); + } + + const newInternalRule = convertUpdateAPIToInternalSchema({ + existingRule, + ruleUpdate, + }); + + const update = await rulesClient.update({ + id: existingRule.id, + data: newInternalRule, + }); + + await toggleRuleEnabledOnUpdate(rulesClient, existingRule, ruleUpdate.enabled); + + return { ...update, enabled: ruleUpdate.enabled ?? existingRule.enabled }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts new file mode 100644 index 0000000000000..528f81ac9c57b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/methods/upgrade_prebuilt_rule.ts @@ -0,0 +1,84 @@ +/* + * 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 type { MlAuthz } from '../../../../../machine_learning/authz'; +import type { RuleAlertType, RuleParams } from '../../../../rule_schema'; +import type { UpgradePrebuiltRuleArgs } from '../detection_rules_client_interface'; +import { + convertPatchAPIToInternalSchema, + convertCreateAPIToInternalSchema, +} from '../../../normalization/rule_converters'; +import { transformAlertToRuleAction } from '../../../../../../../common/detection_engine/transform_actions'; + +import { validateMlAuth, ClientError } from '../utils'; + +import { readRules } from '../read_rules'; + +export const upgradePrebuiltRule = async ( + rulesClient: RulesClient, + upgradePrebuiltRulePayload: UpgradePrebuiltRuleArgs, + mlAuthz: MlAuthz +): Promise => { + const { ruleAsset } = upgradePrebuiltRulePayload; + + await validateMlAuth(mlAuthz, ruleAsset.type); + + const existingRule = await readRules({ + rulesClient, + ruleId: ruleAsset.rule_id, + id: undefined, + }); + + if (!existingRule) { + throw new ClientError(`Failed to find rule ${ruleAsset.rule_id}`, 500); + } + + if (ruleAsset.type !== existingRule.params.type) { + // If we're trying to change the type of a prepackaged rule, we need to delete the old one + // and replace it with the new rule, keeping the enabled setting, actions, throttle, id, + // and exception lists from the old rule + await rulesClient.delete({ id: existingRule.id }); + + const internalRule = convertCreateAPIToInternalSchema( + { + ...ruleAsset, + enabled: existingRule.enabled, + exceptions_list: existingRule.params.exceptionsList, + actions: existingRule.actions.map(transformAlertToRuleAction), + timeline_id: existingRule.params.timelineId, + timeline_title: existingRule.params.timelineTitle, + }, + { immutable: true, defaultEnabled: existingRule.enabled } + ); + + return rulesClient.create({ + data: internalRule, + options: { id: existingRule.id }, + }); + } + + // Else, simply patch it. + const patchedRule = convertPatchAPIToInternalSchema(ruleAsset, existingRule); + + await rulesClient.update({ + id: existingRule.id, + data: patchedRule, + }); + + const updatedRule = await readRules({ + rulesClient, + ruleId: ruleAsset.rule_id, + id: undefined, + }); + + if (!updatedRule) { + throw new ClientError(`Rule ${ruleAsset.rule_id} not found after upgrade`, 500); + } + + return updatedRule; +}; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/read_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/read_rules.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/read_rules.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/read_rules.test.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/read_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/read_rules.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/read_rules.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/read_rules.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/utils.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/utils.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts index 8c8f32181c230..5c64a2a6f9a33 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/import/import_rules_utils.ts @@ -16,7 +16,7 @@ import type { RuleToImport } from '../../../../../../common/api/detection_engine import type { ImportRuleResponse } from '../../../routes/utils'; import { createBulkErrorObject } from '../../../routes/utils'; import { checkRuleExceptionReferences } from './check_rule_exception_references'; -import type { IDetectionRulesClient } from '../rule_management/detection_rules_client'; +import type { IDetectionRulesClient } from '../detection_rules_client/detection_rules_client_interface'; export type PromiseFromStreams = RuleToImport | Error; export interface RuleExceptionsPromiseFromStreams { @@ -94,9 +94,7 @@ export const importRules = async ({ exceptions_list: [...exceptions], }, overwriteRules, - options: { - allowMissingConnectorSecrets, - }, + allowMissingConnectorSecrets, }); resolve({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts deleted file mode 100644 index c8951d5ff4a65..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_custom_rule.ts +++ /dev/null @@ -1,36 +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 { RulesClient } from '@kbn/alerting-plugin/server'; -import type { RuleCreateProps } from '../../../../../../common/api/detection_engine'; -import type { MlAuthz } from '../../../../machine_learning/authz'; -import type { RuleAlertType, RuleParams } from '../../../rule_schema'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; -import { convertCreateAPIToInternalSchema } from '../../normalization/rule_converters'; - -import { validateMlAuth } from './utils'; - -export interface CreateCustomRuleProps { - params: RuleCreateProps; -} - -export const createCustomRule = async ( - rulesClient: RulesClient, - createCustomRulePayload: CreateCustomRuleProps, - mlAuthz: MlAuthz -): Promise => - withSecuritySpan('DetectionRulesClient.createCustomRule', async () => { - const { params } = createCustomRulePayload; - await validateMlAuth(mlAuthz, params.type); - - const internalRule = convertCreateAPIToInternalSchema(params, { immutable: false }); - const rule = await rulesClient.create({ - data: internalRule, - }); - - return rule; - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts deleted file mode 100644 index 7cf13cec63822..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/create_prebuilt_rule.ts +++ /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 type { RulesClient } from '@kbn/alerting-plugin/server'; -import type { PrebuiltRuleAsset } from '../../../prebuilt_rules'; -import type { MlAuthz } from '../../../../machine_learning/authz'; -import type { RuleAlertType, RuleParams } from '../../../rule_schema'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; -import { convertCreateAPIToInternalSchema } from '../../normalization/rule_converters'; - -import { validateMlAuth } from './utils'; - -export interface CreatePrebuiltRuleProps { - ruleAsset: PrebuiltRuleAsset; -} - -export const createPrebuiltRule = async ( - rulesClient: RulesClient, - createPrebuiltRulePayload: CreatePrebuiltRuleProps, - mlAuthz: MlAuthz -): Promise => - withSecuritySpan('DetectionRulesClient.createPrebuiltRule', async () => { - const { ruleAsset } = createPrebuiltRulePayload; - - await validateMlAuth(mlAuthz, ruleAsset.type); - - const internalRule = convertCreateAPIToInternalSchema(ruleAsset, { - immutable: true, - defaultEnabled: false, - }); - - const rule = await rulesClient.create({ - data: internalRule, - }); - - return rule; - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts deleted file mode 100644 index a2b4acfc6a58b..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/delete_rule.ts +++ /dev/null @@ -1,23 +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 { RulesClient } from '@kbn/alerting-plugin/server'; -import type { RuleObjectId } from '../../../../../../common/api/detection_engine'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; - -export interface DeleteRuleProps { - ruleId: RuleObjectId; -} - -export const deleteRule = async ( - rulesClient: RulesClient, - deleteRulePayload: DeleteRuleProps -): Promise => - withSecuritySpan('DetectionRulesClient.deleteRule', async () => { - const { ruleId } = deleteRulePayload; - await rulesClient.delete({ id: ruleId }); - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts deleted file mode 100644 index c976f6d247ac5..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/detection_rules_client.ts +++ /dev/null @@ -1,80 +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 { RulesClient } from '@kbn/alerting-plugin/server'; -import type { MlAuthz } from '../../../../machine_learning/authz'; - -import type { RuleAlertType } from '../../../rule_schema'; - -import type { CreateCustomRuleProps } from './create_custom_rule'; -import type { CreatePrebuiltRuleProps } from './create_prebuilt_rule'; -import type { UpdateRuleProps } from './update_rule'; -import type { PatchRuleProps } from './patch_rule'; -import type { DeleteRuleProps } from './delete_rule'; -import type { UpgradePrebuiltRuleProps } from './upgrade_prebuilt_rule'; -import type { ImportRuleProps } from './import_rule'; - -import { createCustomRule } from './create_custom_rule'; -import { createPrebuiltRule } from './create_prebuilt_rule'; -import { updateRule } from './update_rule'; -import { patchRule } from './patch_rule'; -import { deleteRule } from './delete_rule'; -import { upgradePrebuiltRule } from './upgrade_prebuilt_rule'; -import { importRule } from './import_rule'; - -export interface IDetectionRulesClient { - createCustomRule: (createCustomRulePayload: CreateCustomRuleProps) => Promise; - createPrebuiltRule: ( - createPrebuiltRulePayload: CreatePrebuiltRuleProps - ) => Promise; - updateRule: (updateRulePayload: UpdateRuleProps) => Promise; - patchRule: (patchRulePayload: PatchRuleProps) => Promise; - deleteRule: (deleteRulePayload: DeleteRuleProps) => Promise; - upgradePrebuiltRule: ( - upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps - ) => Promise; - importRule: (importRulePayload: ImportRuleProps) => Promise; -} - -export const createDetectionRulesClient = ( - rulesClient: RulesClient, - mlAuthz: MlAuthz -): IDetectionRulesClient => ({ - createCustomRule: async ( - createCustomRulePayload: CreateCustomRuleProps - ): Promise => { - return createCustomRule(rulesClient, createCustomRulePayload, mlAuthz); - }, - - createPrebuiltRule: async ( - createPrebuiltRulePayload: CreatePrebuiltRuleProps - ): Promise => { - return createPrebuiltRule(rulesClient, createPrebuiltRulePayload, mlAuthz); - }, - - updateRule: async (updateRulePayload: UpdateRuleProps): Promise => { - return updateRule(rulesClient, updateRulePayload, mlAuthz); - }, - - patchRule: async (patchRulePayload: PatchRuleProps): Promise => { - return patchRule(rulesClient, patchRulePayload, mlAuthz); - }, - - deleteRule: async (deleteRulePayload: DeleteRuleProps): Promise => { - return deleteRule(rulesClient, deleteRulePayload); - }, - - upgradePrebuiltRule: async ( - upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps - ): Promise => { - return upgradePrebuiltRule(rulesClient, upgradePrebuiltRulePayload, mlAuthz); - }, - - importRule: async (importRulePayload: ImportRuleProps): Promise => { - return importRule(rulesClient, importRulePayload, mlAuthz); - }, -}); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts deleted file mode 100644 index 643d59a0c495f..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/import_rule.ts +++ /dev/null @@ -1,75 +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 { RulesClient } from '@kbn/alerting-plugin/server'; -import type { MlAuthz } from '../../../../machine_learning/authz'; -import type { RuleAlertType, RuleParams } from '../../../rule_schema'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; -import type { RuleToImport } from '../../../../../../common/api/detection_engine'; -import { createBulkErrorObject } from '../../../routes/utils'; -import { - convertCreateAPIToInternalSchema, - convertUpdateAPIToInternalSchema, -} from '../../normalization/rule_converters'; - -import { validateMlAuth } from './utils'; - -import { readRules } from './read_rules'; - -interface ImportRuleOptions { - allowMissingConnectorSecrets?: boolean; -} - -export interface ImportRuleProps { - ruleToImport: RuleToImport; - overwriteRules?: boolean; - options: ImportRuleOptions; -} - -export const importRule = async ( - rulesClient: RulesClient, - importRulePayload: ImportRuleProps, - mlAuthz: MlAuthz -): Promise => - withSecuritySpan('DetectionRulesClient.importRule', async () => { - const { ruleToImport, overwriteRules, options } = importRulePayload; - - await validateMlAuth(mlAuthz, ruleToImport.type); - - const existingRule = await readRules({ - rulesClient, - ruleId: ruleToImport.rule_id, - id: undefined, - }); - - if (!existingRule) { - const internalRule = convertCreateAPIToInternalSchema(ruleToImport, { - immutable: false, - }); - - return rulesClient.create({ - data: internalRule, - allowMissingConnectorSecrets: options.allowMissingConnectorSecrets, - }); - } else if (existingRule && overwriteRules) { - const newInternalRule = convertUpdateAPIToInternalSchema({ - existingRule, - ruleUpdate: ruleToImport, - }); - - return rulesClient.update({ - id: existingRule.id, - data: newInternalRule, - }); - } else { - throw createBulkErrorObject({ - ruleId: existingRule.params.ruleId, - statusCode: 409, - message: `rule_id: "${existingRule.params.ruleId}" already exists`, - }); - } - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts deleted file mode 100644 index dad3d74a6f208..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/patch_rule.ts +++ /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 type { RulesClient } from '@kbn/alerting-plugin/server'; -import type { PatchRuleRequestBody } from '../../../../../../common/api/detection_engine'; -import type { MlAuthz } from '../../../../machine_learning/authz'; -import type { RuleAlertType } from '../../../rule_schema'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; -import { getIdError } from '../../utils/utils'; -import { convertPatchAPIToInternalSchema } from '../../normalization/rule_converters'; - -import { validateMlAuth, ClientError, toggleRuleEnabledOnUpdate } from './utils'; - -import { readRules } from './read_rules'; - -export interface PatchRuleProps { - nextParams: PatchRuleRequestBody; -} - -export const patchRule = async ( - rulesClient: RulesClient, - patchRulePayload: PatchRuleProps, - mlAuthz: MlAuthz -): Promise => - withSecuritySpan('DetectionRulesClient.patchRule', async () => { - const { nextParams } = patchRulePayload; - const { rule_id: ruleId, id } = nextParams; - - const existingRule = await readRules({ - rulesClient, - ruleId, - id, - }); - - if (existingRule == null) { - const error = getIdError({ id, ruleId }); - throw new ClientError(error.message, error.statusCode); - } - - await validateMlAuth(mlAuthz, nextParams.type ?? existingRule.params.type); - - const patchedRule = convertPatchAPIToInternalSchema(nextParams, existingRule); - - const update = await rulesClient.update({ - id: existingRule.id, - data: patchedRule, - }); - - await toggleRuleEnabledOnUpdate(rulesClient, existingRule, nextParams.enabled); - - if (nextParams.enabled != null) { - return { ...update, enabled: nextParams.enabled }; - } else { - return update; - } - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts deleted file mode 100644 index 4370e4f457448..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/update_rule.ts +++ /dev/null @@ -1,59 +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 { RulesClient } from '@kbn/alerting-plugin/server'; -import type { RuleUpdateProps } from '../../../../../../common/api/detection_engine'; -import type { MlAuthz } from '../../../../machine_learning/authz'; -import type { RuleAlertType } from '../../../rule_schema'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; -import { getIdError } from '../../utils/utils'; -import { convertUpdateAPIToInternalSchema } from '../../normalization/rule_converters'; - -import { validateMlAuth, ClientError, toggleRuleEnabledOnUpdate } from './utils'; - -import { readRules } from './read_rules'; - -export interface UpdateRuleProps { - ruleUpdate: RuleUpdateProps; -} - -export const updateRule = async ( - rulesClient: RulesClient, - updateRulePayload: UpdateRuleProps, - mlAuthz: MlAuthz -): Promise => - withSecuritySpan('DetectionRulesClient.updateRule', async () => { - const { ruleUpdate } = updateRulePayload; - const { rule_id: ruleId, id } = ruleUpdate; - - await validateMlAuth(mlAuthz, ruleUpdate.type); - - const existingRule = await readRules({ - rulesClient, - ruleId, - id, - }); - - if (existingRule == null) { - const error = getIdError({ id, ruleId }); - throw new ClientError(error.message, error.statusCode); - } - - const newInternalRule = convertUpdateAPIToInternalSchema({ - existingRule, - ruleUpdate, - }); - - const update = await rulesClient.update({ - id: existingRule.id, - data: newInternalRule, - }); - - await toggleRuleEnabledOnUpdate(rulesClient, existingRule, ruleUpdate.enabled); - - return { ...update, enabled: ruleUpdate.enabled ?? existingRule.enabled }; - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts deleted file mode 100644 index b516fc997055c..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/rule_management/upgrade_prebuilt_rule.ts +++ /dev/null @@ -1,90 +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 { RulesClient } from '@kbn/alerting-plugin/server'; -import type { PrebuiltRuleAsset } from '../../../prebuilt_rules'; -import type { MlAuthz } from '../../../../machine_learning/authz'; -import type { RuleAlertType, RuleParams } from '../../../rule_schema'; -import { withSecuritySpan } from '../../../../../utils/with_security_span'; -import { - convertPatchAPIToInternalSchema, - convertCreateAPIToInternalSchema, -} from '../../normalization/rule_converters'; -import { transformAlertToRuleAction } from '../../../../../../common/detection_engine/transform_actions'; - -import { validateMlAuth, ClientError } from './utils'; - -import { readRules } from './read_rules'; - -export interface UpgradePrebuiltRuleProps { - ruleAsset: PrebuiltRuleAsset; -} - -export const upgradePrebuiltRule = async ( - rulesClient: RulesClient, - upgradePrebuiltRulePayload: UpgradePrebuiltRuleProps, - mlAuthz: MlAuthz -): Promise => - withSecuritySpan('DetectionRulesClient.upgradePrebuiltRule', async () => { - const { ruleAsset } = upgradePrebuiltRulePayload; - - await validateMlAuth(mlAuthz, ruleAsset.type); - - const existingRule = await readRules({ - rulesClient, - ruleId: ruleAsset.rule_id, - id: undefined, - }); - - if (!existingRule) { - throw new ClientError(`Failed to find rule ${ruleAsset.rule_id}`, 500); - } - - if (ruleAsset.type !== existingRule.params.type) { - // If we're trying to change the type of a prepackaged rule, we need to delete the old one - // and replace it with the new rule, keeping the enabled setting, actions, throttle, id, - // and exception lists from the old rule - await rulesClient.delete({ id: existingRule.id }); - - const internalRule = convertCreateAPIToInternalSchema( - { - ...ruleAsset, - enabled: existingRule.enabled, - exceptions_list: existingRule.params.exceptionsList, - actions: existingRule.actions.map(transformAlertToRuleAction), - timeline_id: existingRule.params.timelineId, - timeline_title: existingRule.params.timelineTitle, - }, - { immutable: true, defaultEnabled: existingRule.enabled } - ); - - return rulesClient.create({ - data: internalRule, - options: { id: existingRule.id }, - }); - } - - // Else, simply patch it. - const patchedRule = convertPatchAPIToInternalSchema(ruleAsset, existingRule); - - await rulesClient.update({ - id: existingRule.id, - data: patchedRule, - }); - - const updatedRule = await readRules({ - rulesClient, - ruleId: ruleAsset.rule_id, - id: undefined, - }); - - if (!updatedRule) { - throw new ClientError(`Rule ${ruleAsset.rule_id} not found after upgrade`, 500); - } - - return updatedRule; - }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/detection_engine_health/rule_objects/fetch_rule_by_id.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/detection_engine_health/rule_objects/fetch_rule_by_id.ts index 520363eb67e5c..4272af8ee9f94 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/detection_engine_health/rule_objects/fetch_rule_by_id.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_monitoring/logic/detection_engine_health/rule_objects/fetch_rule_by_id.ts @@ -11,7 +11,7 @@ import type { RuleObjectId, RuleResponse, } from '../../../../../../../common/api/detection_engine/model/rule_schema'; -import { readRules } from '../../../../rule_management/logic/rule_management/read_rules'; +import { readRules } from '../../../../rule_management/logic/detection_rules_client/read_rules'; import { transform } from '../../../../rule_management/utils/utils'; // TODO: https://github.com/elastic/kibana/issues/125642 Move to rule_management into a DetectionRulesClient diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index a47535772dd83..1f36f7ecff234 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -28,7 +28,7 @@ import type { EndpointAppContextService } from './endpoint/endpoint_app_context_ import { RiskEngineDataClient } from './lib/entity_analytics/risk_engine/risk_engine_data_client'; import { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_score_data_client'; import { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality'; -import { createDetectionRulesClient } from './lib/detection_engine/rule_management/logic/rule_management/detection_rules_client'; +import { createDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client'; import { buildMlAuthz } from './lib/machine_learning/authz'; export interface IRequestContextFactory { @@ -114,7 +114,7 @@ export class RequestContextFactory implements IRequestContextFactory { getAuditLogger, - getDetectionRulesClient: () => { + getDetectionRulesClient: memoize(() => { const mlAuthz = buildMlAuthz({ license: licensing.license, ml: plugins.ml, @@ -126,7 +126,7 @@ export class RequestContextFactory implements IRequestContextFactory { startPlugins.alerting.getRulesClientWithRequest(request), mlAuthz ); - }, + }), getDetectionEngineHealthClient: memoize(() => ruleMonitoringService.createDetectionEngineHealthClient({ diff --git a/x-pack/plugins/security_solution/server/types.ts b/x-pack/plugins/security_solution/server/types.ts index 563d61bfae307..25a045390452c 100644 --- a/x-pack/plugins/security_solution/server/types.ts +++ b/x-pack/plugins/security_solution/server/types.ts @@ -33,7 +33,7 @@ import type { EndpointInternalFleetServicesInterface } from './endpoint/services import type { RiskEngineDataClient } from './lib/entity_analytics/risk_engine/risk_engine_data_client'; import type { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_score_data_client'; import type { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality'; -import type { IDetectionRulesClient } from './lib/detection_engine/rule_management/logic/rule_management/detection_rules_client'; +import type { IDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client'; export { AppClient }; export interface SecuritySolutionApiRequestHandlerContext { From e7e94a792cab23a4653430b64e11257daa6c1595 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 7 Jun 2024 18:48:53 +0200 Subject: [PATCH 2/4] Rename `deleteRule` test file, so that it's consistent with other files --- ..._client.test.ts => detection_rules_client.delete_rule.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/{delete_rule.detection_rules_client.test.ts => detection_rules_client.delete_rule.test.ts} (100%) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/delete_rule.detection_rules_client.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.delete_rule.test.ts similarity index 100% rename from x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/delete_rule.detection_rules_client.test.ts rename to x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.delete_rule.test.ts From f7363a2e11eb420211b52cbde27598d5ba965379 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 7 Jun 2024 18:50:36 +0200 Subject: [PATCH 3/4] Update `IDetectionRulesClient` import --- x-pack/plugins/security_solution/server/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/types.ts b/x-pack/plugins/security_solution/server/types.ts index 25a045390452c..121eb7b1758f4 100644 --- a/x-pack/plugins/security_solution/server/types.ts +++ b/x-pack/plugins/security_solution/server/types.ts @@ -33,7 +33,7 @@ import type { EndpointInternalFleetServicesInterface } from './endpoint/services import type { RiskEngineDataClient } from './lib/entity_analytics/risk_engine/risk_engine_data_client'; import type { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_score_data_client'; import type { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality'; -import type { IDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client'; +import type { IDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface'; export { AppClient }; export interface SecuritySolutionApiRequestHandlerContext { From 6bbb925b553c59acc21ed3e5a90c1b1485a45cce Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Fri, 7 Jun 2024 22:15:36 +0200 Subject: [PATCH 4/4] Update x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤦 Copy-pasted typo fix Co-authored-by: Georgii Gorbachev --- .../logic/detection_rules_client/detection_rules_client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts index 73477cbbadf3b..7256441697e65 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client.ts @@ -53,7 +53,7 @@ export const createDetectionRulesClient = ( }, async patchRule(args: PatchRuleArgs): Promise { - return withSecuritySpan('DetectionRulesClient.createCustomRule', async () => { + return withSecuritySpan('DetectionRulesClient.patchRule', async () => { return patchRule(rulesClient, args, mlAuthz); }); },