From 6367d11beff28ee95a07a30cab805a49b75e73e9 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Tue, 26 Nov 2024 14:30:31 +0000 Subject: [PATCH 01/38] no type errors :) --- .../common/api/entity_analytics/index.ts | 1 - .../risk_engine/engine_init_route.gen.ts | 1 - .../risk_engine/engine_status_route.gen.ts | 1 - .../create_index/create_index_route.ts | 18 - ...reate_prebuilt_saved_objects_route.test.ts | 27 - .../create_prebuilt_saved_objects_route.ts | 17 - .../create_stored_script_route.ts | 25 - .../delete_prebuilt_saved_objects_route.ts | 18 - .../delete_stored_script_route.ts | 15 - .../api/entity_analytics/risk_score/index.ts | 16 - .../index_status/index_status_route.ts | 13 - .../install_modules/install_modules_route.ts | 18 - .../read_prebuilt_dev_tool_content_route.ts | 17 - .../common/api/search_strategy/hosts/all.ts | 1 - .../related_entities/related_hosts.ts | 1 - .../related_entities/related_users.ts | 1 - .../common/api/search_strategy/users/all.ts | 1 - .../security_solution/common/constants.ts | 5 - .../entity_analytics/risk_engine/types.ts | 1 - .../entity_analytics/risk_score/constants.ts | 18 - .../risk_score/common/index.test.ts | 40 - .../risk_score/common/index.ts | 29 +- .../common/utils/risk_score_modules.test.ts | 166 --- .../common/utils/risk_score_modules.ts | 587 --------- .../visualization_embeddable.test.tsx | 33 - .../related_hosts/index.test.tsx | 5 - .../related_entities/related_hosts/index.tsx | 11 +- .../related_users/index.test.tsx | 6 - .../related_entities/related_users/index.tsx | 10 +- .../common/hooks/use_fetch/request_names.ts | 4 - .../public/entity_analytics/api/api.ts | 24 - .../api/hooks/use_risk_engine_status.ts | 53 +- .../api/hooks/use_risk_score.test.tsx | 44 - .../api/hooks/use_risk_score.tsx | 73 +- .../use_risk_score_feature_status.test.ts | 125 -- .../hooks/use_risk_score_feature_status.ts | 74 -- .../api/hooks/use_risk_score_kpi.tsx | 51 +- .../schedule_risk_engine_callout.test.tsx | 11 +- .../schedule_risk_engine_callout.tsx | 5 +- .../components/enable_risk_score/index.tsx | 24 +- .../enable_risk_score/translations.ts | 16 - ...x => entity_analytics_learn_more_link.tsx} | 2 +- .../entity_analytics_risk_score/index.tsx | 20 +- .../risk_details_tab_body/index.tsx | 128 +- .../components/risk_information/index.tsx | 4 +- .../components/risk_score/constants.ts | 3 - .../risk_score_enable_button.test.tsx | 4 +- .../components/risk_score_enable_button.tsx | 47 + .../components/risk_score_enable_section.tsx | 125 +- .../risk_score_header_title.tsx | 3 +- ...ons.ts => risk_score_no_data_detected.tsx} | 52 +- .../risk_score_enable_button.tsx | 102 -- .../risk_score_no_data_detected.tsx | 58 - .../risk_score_restart_button.test.tsx | 99 -- .../risk_score_restart_button.tsx | 64 - .../use_risk_score_toast_content.tsx | 53 - .../risk_score_onboarding/utils.test.ts | 178 --- .../components/risk_score_onboarding/utils.ts | 348 ------ .../components/risk_score_update_panel.tsx | 34 - .../index.test.tsx | 87 -- .../top_risk_score_contributors/index.tsx | 116 -- .../translations.ts | 29 - .../components/user_risk_score_tab_body.tsx | 45 +- .../deprecated_risk_engine/api/index.ts | 11 - .../api/ingest_pipelines.test.ts | 82 -- .../api/ingest_pipelines.ts | 67 -- .../deprecated_risk_engine/api/onboarding.ts | 91 -- .../api/saved_objects.ts | 151 --- .../api/stored_scripts.test.ts | 84 -- .../api/stored_scripts.ts | 92 -- .../api/transforms.test.ts | 214 ---- .../deprecated_risk_engine/api/transforms.ts | 327 ----- .../api/translations.ts | 128 -- .../deprecated_risk_engine/api/types.ts | 107 -- .../hooks/use_get_default_risk_index.ts | 28 + .../lens_attributes/risk_score_donut.ts | 4 +- .../pages/entity_analytics_dashboard.tsx | 11 - .../hosts/containers/hosts/index.test.tsx | 5 - .../explore/hosts/containers/hosts/index.tsx | 21 +- .../navigation/host_risk_score_tab_body.tsx | 47 +- .../all_users_query_tab_body.test.tsx | 5 - .../navigation/all_users_query_tab_body.tsx | 20 +- .../entity_details/host_right/content.tsx | 2 +- .../flyout/entity_details/mocks/index.ts | 6 +- .../entity_details/user_right/content.tsx | 2 +- .../public/flyout/shared/mocks/index.ts | 2 +- .../public/overview/components/common.tsx | 2 +- .../components/host_overview/index.tsx | 2 +- .../components/user_overview/index.tsx | 2 +- .../enrichment_by_type/host_risk.ts | 3 +- .../enrichment_by_type/user_risk.ts | 3 +- .../rule_types/utils/enrichments/index.ts | 15 +- .../rule_types/utils/enrichments/types.ts | 2 - .../lib/entity_analytics/risk_engine/audit.ts | 2 - .../risk_engine_data_client.mock.ts | 1 - .../risk_engine_data_client.test.ts | 50 - .../risk_engine/risk_engine_data_client.ts | 70 -- .../risk_engine/routes/init.ts | 1 - .../risk_engine/routes/status.ts | 10 +- .../utils/saved_object_configuration.ts | 2 +- .../utils/get_alerts_index.ts} | 6 +- .../lib/entity_analytics/utils/transforms.ts | 58 - .../lib/risk_score/index_status/index.test.ts | 85 -- .../lib/risk_score/index_status/index.ts | 68 -- .../indices/create_index_route.test.ts | 84 -- .../risk_score/indices/create_index_route.ts | 66 -- .../indices/delete_indices_route.test.ts | 60 - .../indices/delete_indices_route.ts | 46 - .../server/lib/risk_score/indices/index.ts | 9 - .../risk_score/indices/lib/create_index.ts | 33 - .../risk_score/indices/lib/delete_indices.ts | 23 - .../onboarding/helpers/ingest_pipeline.ts | 44 - .../helpers/install_risk_score_module.ts | 313 ----- .../install_risk_scores.test.ts.snap | 736 ------------ .../routes/install_risk_scores.test.ts | 176 --- .../onboarding/routes/install_risk_scores.ts | 62 - .../console_mappings.ts | 11 - .../enable_host_risk_score.mustache | 86 -- .../enable_user_risk_score.mustache | 78 -- ...ebuilt_dev_tool_content_route.test.ts.snap | 173 --- ...ad_prebuilt_dev_tool_content_route.test.ts | 49 - .../read_prebuilt_dev_tool_content_route.ts | 102 -- .../prebuilt_dev_tool_content/schema.test.ts | 23 - .../prebuilt_dev_tool_content/utils.ts | 114 -- .../helpers/bulk_create_saved_objects.ts | 121 -- .../helpers/bulk_delete_saved_objects.ts | 145 --- .../helpers/create_risk_score_tag.ts | 124 -- .../prebuilt_saved_objects/helpers/utils.ts | 53 - ...create_prebuilt_saved_objects.test.ts.snap | 1056 ----------------- .../create_prebuilt_saved_objects.test.ts | 93 -- .../routes/create_prebuilt_saved_objects.ts | 65 - .../delete_prebuilt_saved_objects.test.ts | 269 ----- .../routes/delete_prebuilt_saved_objects.ts | 64 - .../host_risk_score_dashboards.ts | 417 ------- .../saved_object/index.ts | 8 - .../user_risk_score_dashboards.ts | 419 ------- .../prebuilt_saved_objects/types.ts | 23 - .../server/lib/risk_score/readme.md | 488 -------- .../server/lib/risk_score/routes/index.ts | 20 - .../create_script_route.test.ts | 101 -- .../stored_scripts/create_script_route.ts | 54 - .../delete_script_route.test.ts | 60 - .../stored_scripts/delete_script_route.ts | 47 - .../stored_scripts/lib/create_script.ts | 28 - .../stored_scripts/lib/delete_script.ts | 18 - .../transform/helpers/transforms.ts | 184 --- .../security_solution/server/routes/index.ts | 22 - .../factory/hosts/all/__mocks__/index.ts | 1 - .../factory/hosts/all/index.ts | 18 +- .../related_hosts/__mocks__/index.ts | 1 - .../related_entities/related_hosts/index.ts | 17 +- .../related_users/__mocks__/index.ts | 1 - .../related_entities/related_users/index.ts | 17 +- .../factory/users/all/__mocks__/index.ts | 1 - .../factory/users/all/index.ts | 18 +- .../init_and_status_apis.ts | 80 +- .../risk_engine_cleanup_api.ts | 3 - .../risk_engine_schedule_now.ts | 4 - .../entity_analytics/utils/risk_engine.ts | 141 +-- .../cypress/tasks/entity_analytics.ts | 14 +- 160 files changed, 271 insertions(+), 11308 deletions(-) delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_index/create_index_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_stored_script/create_stored_script_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_stored_script/delete_stored_script_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index_status/index_status_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/install_modules/install_modules_route.ts delete mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts delete mode 100644 x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.test.ts delete mode 100644 x-pack/plugins/security_solution/common/utils/risk_score_modules.test.ts delete mode 100644 x-pack/plugins/security_solution/common/utils/risk_score_modules.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts rename x-pack/plugins/security_solution/public/entity_analytics/components/{risk_score_onboarding/entity_analytics_doc_link.tsx => entity_analytics_learn_more_link.tsx} (95%) rename x-pack/plugins/security_solution/public/entity_analytics/components/{risk_score_onboarding => }/risk_score_enable_button.test.tsx (90%) create mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx rename x-pack/plugins/security_solution/public/entity_analytics/components/{risk_score_onboarding => }/risk_score_header_title.tsx (93%) rename x-pack/plugins/security_solution/public/entity_analytics/components/{risk_score_onboarding/translations.ts => risk_score_no_data_detected.tsx} (50%) delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_update_panel.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/translations.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/index.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.test.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.test.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.test.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/translations.ts delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/types.ts create mode 100644 x-pack/plugins/security_solution/public/entity_analytics/hooks/use_get_default_risk_index.ts rename x-pack/plugins/security_solution/{common/api/entity_analytics/risk_score/delete_indices/delete_indices_route.ts => server/lib/entity_analytics/utils/get_alerts_index.ts} (61%) delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/index.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/delete_indices.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/ingest_pipeline.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/install_risk_score_module.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/__snapshots__/install_risk_scores.test.ts.snap delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_mappings.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_host_risk_score.mustache delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_user_risk_score.mustache delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/__snapshots__/read_prebuilt_dev_tool_content_route.test.ts.snap delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/utils.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_create_saved_objects.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_delete_saved_objects.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/create_risk_score_tag.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/utils.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/__snapshots__/create_prebuilt_saved_objects.test.ts.snap delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/index.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/user_risk_score_dashboards.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/types.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/readme.md delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.test.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts delete mode 100644 x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/index.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/index.ts index 5dbbb7850286a..a1eebaae906ce 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/index.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/index.ts @@ -7,6 +7,5 @@ export * from './asset_criticality'; export * from './risk_engine'; -export * from './risk_score'; export * from './entity_store'; export { EntityAnalyticsPrivileges } from './common'; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts index ec394a721a97b..6ffdea0775fce 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts @@ -21,7 +21,6 @@ export const InitRiskEngineResult = z.object({ risk_engine_enabled: z.boolean(), risk_engine_resources_installed: z.boolean(), risk_engine_configuration_created: z.boolean(), - legacy_risk_engine_disabled: z.boolean(), errors: z.array(z.string()), }); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts index 0faf22c032e06..1afd9c0d04e1d 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts @@ -43,7 +43,6 @@ export const RiskEngineTaskStatus = z.object({ export type RiskEngineStatusResponse = z.infer; export const RiskEngineStatusResponse = z.object({ - legacy_risk_engine_status: RiskEngineStatus, risk_engine_status: RiskEngineStatus, risk_engine_task_status: RiskEngineTaskStatus.optional(), }); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_index/create_index_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_index/create_index_route.ts deleted file mode 100644 index 5199db8132b79..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_index/create_index_route.ts +++ /dev/null @@ -1,18 +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 { TypeOf } from '@kbn/config-schema'; -import { schema } from '@kbn/config-schema'; - -export const createEsIndexRequestBody = schema.object({ - index: schema.string({ minLength: 1 }), - mappings: schema.maybe( - schema.oneOf([schema.string(), schema.recordOf(schema.string({ minLength: 1 }), schema.any())]) - ), -}); - -export type CreateEsIndexRequestBody = TypeOf; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts deleted file mode 100644 index b37f611a6e2bb..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts +++ /dev/null @@ -1,27 +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 { createPrebuiltSavedObjectsRequestBody } from './create_prebuilt_saved_objects_route'; - -describe('createPrebuiltSavedObjectsRequestBody', () => { - it('should throw error', () => { - expect(() => - createPrebuiltSavedObjectsRequestBody.params.validate({ template_name: '123' }) - ).toThrow(); - }); - - it.each([['hostRiskScoreDashboards', 'userRiskScoreDashboards']])( - 'should allow template %p', - async (template) => { - expect( - createPrebuiltSavedObjectsRequestBody.params.validate({ template_name: template }) - ).toEqual({ - template_name: template, - }); - } - ); -}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts deleted file mode 100644 index a21d45430791c..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts +++ /dev/null @@ -1,17 +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 { schema } from '@kbn/config-schema'; - -export const createPrebuiltSavedObjectsRequestBody = { - params: schema.object({ - template_name: schema.oneOf([ - schema.literal('hostRiskScoreDashboards'), - schema.literal('userRiskScoreDashboards'), - ]), - }), -}; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_stored_script/create_stored_script_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_stored_script/create_stored_script_route.ts deleted file mode 100644 index 4a16cdfa247bc..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/create_stored_script/create_stored_script_route.ts +++ /dev/null @@ -1,25 +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 { TypeOf } from '@kbn/config-schema'; -import { schema } from '@kbn/config-schema'; - -export const createStoredScriptRequestBody = schema.object({ - id: schema.string({ minLength: 1 }), - script: schema.object({ - lang: schema.oneOf([ - schema.string(), - schema.literal('painless'), - schema.literal('expression'), - schema.literal('mustache'), - schema.literal('java'), - ]), - options: schema.maybe(schema.recordOf(schema.string(), schema.string())), - source: schema.string(), - }), -}); - -export type CreateStoredScriptRequestBody = TypeOf; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts deleted file mode 100644 index 729197a18ddb6..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts +++ /dev/null @@ -1,18 +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 { schema } from '@kbn/config-schema'; - -export const deletePrebuiltSavedObjectsRequestBody = { - params: schema.object({ - template_name: schema.oneOf([ - schema.literal('hostRiskScoreDashboards'), - schema.literal('userRiskScoreDashboards'), - ]), - }), - body: schema.nullable(schema.object({ deleteAll: schema.maybe(schema.boolean()) })), -}; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_stored_script/delete_stored_script_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_stored_script/delete_stored_script_route.ts deleted file mode 100644 index 3859e25f427ed..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_stored_script/delete_stored_script_route.ts +++ /dev/null @@ -1,15 +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 { TypeOf } from '@kbn/config-schema'; -import { schema } from '@kbn/config-schema'; - -export const deleteStoredScriptRequestBody = schema.object({ - id: schema.string({ minLength: 1 }), -}); - -export type DeleteStoredScriptRequestBody = TypeOf; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index.ts deleted file mode 100644 index e3bb3d622c3c0..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './create_index/create_index_route'; -export * from './create_prebuilt_saved_objects/create_prebuilt_saved_objects_route'; -export * from './create_stored_script/create_stored_script_route'; -export * from './delete_indices/delete_indices_route'; -export * from './delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route'; -export * from './delete_stored_script/delete_stored_script_route'; -export * from './index_status/index_status_route'; -export * from './install_modules/install_modules_route'; -export * from './read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route'; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index_status/index_status_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index_status/index_status_route.ts deleted file mode 100644 index afe8529838878..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/index_status/index_status_route.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import * as t from 'io-ts'; - -export const indexStatusRequestQuery = t.type({ - indexName: t.string, - entity: t.string, -}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/install_modules/install_modules_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/install_modules/install_modules_route.ts deleted file mode 100644 index 3f721f1c859d8..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/install_modules/install_modules_route.ts +++ /dev/null @@ -1,18 +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 { schema } from '@kbn/config-schema'; -import { RiskScoreEntity } from '../../../../search_strategy'; - -export const onboardingRiskScoreRequestBody = { - body: schema.object({ - riskScoreEntity: schema.oneOf([ - schema.literal(RiskScoreEntity.host), - schema.literal(RiskScoreEntity.user), - ]), - }), -}; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts deleted file mode 100644 index 8f8ddd62299ff..0000000000000 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts +++ /dev/null @@ -1,17 +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 { schema } from '@kbn/config-schema'; - -export const readConsoleRequestBody = { - params: schema.object({ - console_id: schema.oneOf([ - schema.literal('enable_host_risk_score'), - schema.literal('enable_user_risk_score'), - ]), - }), -}; diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/hosts/all.ts b/x-pack/plugins/security_solution/common/api/search_strategy/hosts/all.ts index 2806f121e51f6..fd1e8629a9f7b 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/hosts/all.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/hosts/all.ts @@ -16,7 +16,6 @@ export const allHostsSchema = requestBasicOptionsSchema.extend({ sort, pagination, timerange, - isNewRiskScoreModuleInstalled: z.boolean().default(false), factoryQueryType: z.literal(HostsQueries.hosts), }); diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_hosts.ts b/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_hosts.ts index 8049570e66a98..71f0329c1cea3 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_hosts.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_hosts.ts @@ -15,7 +15,6 @@ export const relatedHostsRequestOptionsSchema = requestBasicOptionsSchema.extend skip: z.boolean().optional(), from: z.string(), inspect, - isNewRiskScoreModuleInstalled: z.boolean().default(false), factoryQueryType: z.literal(RelatedEntitiesQueries.relatedHosts), }); diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_users.ts b/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_users.ts index 74e2d019688be..39695146dd06c 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_users.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/related_entities/related_users.ts @@ -15,7 +15,6 @@ export const relatedUsersRequestOptionsSchema = requestBasicOptionsSchema.extend skip: z.boolean().optional(), from: z.string(), inspect, - isNewRiskScoreModuleInstalled: z.boolean().default(false), factoryQueryType: z.literal(RelatedEntitiesQueries.relatedUsers), }); diff --git a/x-pack/plugins/security_solution/common/api/search_strategy/users/all.ts b/x-pack/plugins/security_solution/common/api/search_strategy/users/all.ts index 72fc3fcaf9fe5..888e5e187fc43 100644 --- a/x-pack/plugins/security_solution/common/api/search_strategy/users/all.ts +++ b/x-pack/plugins/security_solution/common/api/search_strategy/users/all.ts @@ -22,7 +22,6 @@ export const usersSchema = requestOptionsPaginatedSchema.extend({ field: z.enum([UsersFields.name, UsersFields.lastSeen]), }), timerange, - isNewRiskScoreModuleInstalled: z.boolean().default(false), factoryQueryType: z.literal(UsersQueries.users), }); diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 265af5a47e1fe..c420592b271c9 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -280,7 +280,6 @@ export const TIMELINE_COPY_URL = `${TIMELINE_URL}/_copy` as const; export const NOTE_URL = '/api/note' as const; export const PINNED_EVENT_URL = '/api/pinned_event' as const; export const SOURCERER_API_URL = '/internal/security_solution/sourcerer' as const; -export const RISK_SCORE_INDEX_STATUS_API_URL = '/internal/risk_score/index_status' as const; export const EVENT_GRAPH_VISUALIZATION_API = '/internal/cloud_security_posture/graph' as const; @@ -355,10 +354,6 @@ export const showAllOthersBucket: string[] = [ 'user.name', ]; -export const RISKY_HOSTS_INDEX_PREFIX = 'ml_host_risk_score_' as const; - -export const RISKY_USERS_INDEX_PREFIX = 'ml_user_risk_score_' as const; - export const TRANSFORM_STATES = { ABORTING: 'aborting', FAILED: 'failed', diff --git a/x-pack/plugins/security_solution/common/entity_analytics/risk_engine/types.ts b/x-pack/plugins/security_solution/common/entity_analytics/risk_engine/types.ts index a6c429126e297..1c861296852b8 100644 --- a/x-pack/plugins/security_solution/common/entity_analytics/risk_engine/types.ts +++ b/x-pack/plugins/security_solution/common/entity_analytics/risk_engine/types.ts @@ -13,7 +13,6 @@ export enum RiskScoreEntity { } export interface InitRiskEngineResult { - legacyRiskEngineDisabled: boolean; riskEngineResourcesInstalled: boolean; riskEngineConfigurationCreated: boolean; riskEngineEnabled: boolean; diff --git a/x-pack/plugins/security_solution/common/entity_analytics/risk_score/constants.ts b/x-pack/plugins/security_solution/common/entity_analytics/risk_score/constants.ts index 638383bf340ed..f1124f6a762c6 100644 --- a/x-pack/plugins/security_solution/common/entity_analytics/risk_score/constants.ts +++ b/x-pack/plugins/security_solution/common/entity_analytics/risk_score/constants.ts @@ -10,24 +10,6 @@ */ export const INTERNAL_RISK_SCORE_URL = '/internal/risk_score' as const; export const PUBLIC_RISK_SCORE_URL = '/api/risk_score' as const; -export const DEV_TOOL_PREBUILT_CONTENT = - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/dev_tool/{console_id}` as const; -export const devToolPrebuiltContentUrl = (spaceId: string, consoleId: string) => - `/s/${spaceId}${INTERNAL_RISK_SCORE_URL}/prebuilt_content/dev_tool/${consoleId}` as const; -export const PREBUILT_SAVED_OBJECTS_BULK_CREATE = - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_create/{template_name}` as const; -export const prebuiltSavedObjectsBulkCreateUrl = (templateName: string) => - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_create/${templateName}` as const; -export const PREBUILT_SAVED_OBJECTS_BULK_DELETE = - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_delete/{template_name}` as const; -export const prebuiltSavedObjectsBulkDeleteUrl = (templateName: string) => - `${INTERNAL_RISK_SCORE_URL}/prebuilt_content/saved_objects/_bulk_delete/${templateName}` as const; -export const RISK_SCORE_CREATE_INDEX = `${INTERNAL_RISK_SCORE_URL}/indices/create` as const; -export const RISK_SCORE_DELETE_INDICES = `${INTERNAL_RISK_SCORE_URL}/indices/delete` as const; -export const RISK_SCORE_CREATE_STORED_SCRIPT = - `${INTERNAL_RISK_SCORE_URL}/stored_scripts/create` as const; -export const RISK_SCORE_DELETE_STORED_SCRIPT = - `${INTERNAL_RISK_SCORE_URL}/stored_scripts/delete` as const; export const RISK_SCORE_PREVIEW_URL = `${INTERNAL_RISK_SCORE_URL}/preview` as const; export const RISK_SCORE_ENTITY_CALCULATION_URL = `${INTERNAL_RISK_SCORE_URL}/calculation/entity` as const; diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.test.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.test.ts deleted file mode 100644 index 98ac71c664a98..0000000000000 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.test.ts +++ /dev/null @@ -1,40 +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 { getHostRiskIndex, getUserRiskIndex } from '.'; - -describe('hosts risk search_strategy getHostRiskIndex', () => { - it('should properly return host index if space is specified', () => { - expect(getHostRiskIndex('testName', true, false)).toEqual('ml_host_risk_score_latest_testName'); - }); - - it('should properly return user index if space is specified', () => { - expect(getUserRiskIndex('testName', true, false)).toEqual('ml_user_risk_score_latest_testName'); - }); - - describe('with new risk score module installed', () => { - it('should properly return host index if onlyLatest is false', () => { - expect(getHostRiskIndex('default', false, true)).toEqual('risk-score.risk-score-default'); - }); - - it('should properly return host index if onlyLatest is true', () => { - expect(getHostRiskIndex('default', true, true)).toEqual( - 'risk-score.risk-score-latest-default' - ); - }); - - it('should properly return user index if onlyLatest is false', () => { - expect(getUserRiskIndex('default', false, true)).toEqual('risk-score.risk-score-default'); - }); - - it('should properly return user index if onlyLatest is true', () => { - expect(getUserRiskIndex('default', true, true)).toEqual( - 'risk-score.risk-score-latest-default' - ); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.ts b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.ts index 12f666c3230b8..b9c151b21a3e4 100644 --- a/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.ts +++ b/x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score/common/index.ts @@ -6,7 +6,6 @@ */ import type { ESQuery } from '../../../../typed_json'; -import { RISKY_HOSTS_INDEX_PREFIX, RISKY_USERS_INDEX_PREFIX } from '../../../../constants'; import { RiskScoreEntity, getRiskScoreLatestIndex, @@ -14,32 +13,12 @@ import { } from '../../../../entity_analytics/risk_engine'; export { RiskQueries } from '../../../../api/search_strategy'; -/** - * Make sure this aligns with the index in step 6, 9 in - * prebuilt_dev_tool_content/console_templates/enable_host_risk_score.console - */ -export const getHostRiskIndex = ( - spaceId: string, - onlyLatest: boolean = true, - isNewRiskScoreModuleInstalled: boolean -): string => { - if (isNewRiskScoreModuleInstalled) { - return onlyLatest ? getRiskScoreLatestIndex(spaceId) : getRiskScoreTimeSeriesIndex(spaceId); - } else { - return `${RISKY_HOSTS_INDEX_PREFIX}${onlyLatest ? 'latest_' : ''}${spaceId}`; - } +export const getHostRiskIndex = (spaceId: string, onlyLatest: boolean = true): string => { + return onlyLatest ? getRiskScoreLatestIndex(spaceId) : getRiskScoreTimeSeriesIndex(spaceId); }; -export const getUserRiskIndex = ( - spaceId: string, - onlyLatest: boolean = true, - isNewRiskScoreModuleInstalled: boolean -): string => { - if (isNewRiskScoreModuleInstalled) { - return onlyLatest ? getRiskScoreLatestIndex(spaceId) : getRiskScoreTimeSeriesIndex(spaceId); - } else { - return `${RISKY_USERS_INDEX_PREFIX}${onlyLatest ? 'latest_' : ''}${spaceId}`; - } +export const getUserRiskIndex = (spaceId: string, onlyLatest: boolean = true): string => { + return onlyLatest ? getRiskScoreLatestIndex(spaceId) : getRiskScoreTimeSeriesIndex(spaceId); }; export const buildHostNamesFilter = (hostNames: string[]) => { diff --git a/x-pack/plugins/security_solution/common/utils/risk_score_modules.test.ts b/x-pack/plugins/security_solution/common/utils/risk_score_modules.test.ts deleted file mode 100644 index 3f69c8c163080..0000000000000 --- a/x-pack/plugins/security_solution/common/utils/risk_score_modules.test.ts +++ /dev/null @@ -1,166 +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 { RiskScoreEntity } from '../search_strategy'; -import { - getCreateLatestTransformOptions, - getCreateMLHostPivotTransformOptions, - getCreateMLUserPivotTransformOptions, - getCreateRiskScoreIndicesOptions, - getCreateRiskScoreLatestIndicesOptions, - getIngestPipelineName, - getLatestTransformIndex, - getPivotTransformIndex, - getRiskScoreIngestPipelineOptions, - getRiskScorePivotTransformId, - getRiskHostCreateInitScriptOptions, - getRiskHostCreateLevelScriptOptions, - getRiskHostCreateMapScriptOptions, - getRiskHostCreateReduceScriptOptions, - getRiskScoreInitScriptId, - getRiskScoreLevelScriptId, - getRiskScoreMapScriptId, - getRiskScoreReduceScriptId, - getRiskUserCreateLevelScriptOptions, - getRiskUserCreateMapScriptOptions, - getRiskUserCreateReduceScriptOptions, - getLegacyIngestPipelineName, - getLegacyRiskScoreLevelScriptId, - getLegacyRiskScoreInitScriptId, - getLegacyRiskScoreMapScriptId, - getLegacyRiskScoreReduceScriptId, -} from './risk_score_modules'; - -const mockSpaceId = 'customSpaceId'; - -describe.each([[RiskScoreEntity.host], [RiskScoreEntity.user]])('Risk Score Modules', (entity) => { - test(`getRiskScorePivotTransformId - ${entity}`, () => { - const id = getRiskScorePivotTransformId(entity, mockSpaceId); - expect(id).toMatchInlineSnapshot(`"ml_${entity}riskscore_pivot_transform_customSpaceId"`); - }); - test(`getIngestPipelineName - ${entity}`, () => { - const name = getIngestPipelineName(entity); - expect(name).toMatchInlineSnapshot(`"ml_${entity}riskscore_ingest_pipeline_default"`); - }); - test(`getPivotTransformIndex - ${entity}`, () => { - const index = getPivotTransformIndex(entity, mockSpaceId); - expect(index).toMatchInlineSnapshot(`"ml_${entity}_risk_score_customSpaceId"`); - }); - test(`getLatestTransformIndex - ${entity}`, () => { - const index = getLatestTransformIndex(entity, mockSpaceId); - expect(index).toMatchInlineSnapshot(`"ml_${entity}_risk_score_latest_customSpaceId"`); - }); - test(`getRiskScoreLevelScriptId - ${entity}`, () => { - const index = getRiskScoreLevelScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_levels_script_default"`); - }); - test(`getRiskScoreInitScriptId - ${entity}`, () => { - const index = getRiskScoreInitScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_init_script_default"`); - }); - test(`getRiskScoreMapScriptId - ${entity}`, () => { - const index = getRiskScoreMapScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_map_script_default"`); - }); - test(`getRiskScoreReduceScriptId - ${entity}`, () => { - const index = getRiskScoreReduceScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_reduce_script_default"`); - }); - test(`getLegacyIngestPipelineName - ${entity}`, () => { - const name = getLegacyIngestPipelineName(entity); - expect(name).toMatchInlineSnapshot(`"ml_${entity}riskscore_ingest_pipeline"`); - }); - test(`getLegacyRiskScoreLevelScriptId - ${entity}`, () => { - const index = getLegacyRiskScoreLevelScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_levels_script"`); - }); - test(`getLegacyRiskScoreInitScriptId - ${entity}`, () => { - const index = getLegacyRiskScoreInitScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_init_script"`); - }); - test(`getLegacyRiskScoreMapScriptId - ${entity}`, () => { - const index = getLegacyRiskScoreMapScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_map_script"`); - }); - test(`getLegacyRiskScoreReduceScriptId - ${entity}`, () => { - const index = getLegacyRiskScoreReduceScriptId(entity); - expect(index).toMatchInlineSnapshot(`"ml_${entity}riskscore_reduce_script"`); - }); - test(`getRiskScoreIngestPipelineOptions - ${entity}`, () => { - const options = getRiskScoreIngestPipelineOptions(entity); - expect(options).toMatchSnapshot(); - }); - test(`getCreateRiskScoreIndicesOptions - ${entity}`, () => { - const options = getCreateRiskScoreIndicesOptions({ - spaceId: mockSpaceId, - riskScoreEntity: entity, - }); - expect(options).toMatchSnapshot(); - }); - test(`getCreateRiskScoreLatestIndicesOptions - ${entity}`, () => { - const options = getCreateRiskScoreLatestIndicesOptions({ - spaceId: mockSpaceId, - riskScoreEntity: entity, - }); - expect(options).toMatchSnapshot(); - }); - test(`getCreateLatestTransformOptions - ${entity}`, () => { - const options = getCreateLatestTransformOptions({ - spaceId: mockSpaceId, - riskScoreEntity: entity, - }); - expect(options).toMatchSnapshot(); - }); - test(`getCreateML${ - entity.charAt(0).toUpperCase() + entity.slice(1) - }PivotTransformOptions`, () => { - const fn = - entity === RiskScoreEntity.host - ? getCreateMLHostPivotTransformOptions - : getCreateMLUserPivotTransformOptions; - const options = fn({ - spaceId: mockSpaceId, - }); - expect(options).toMatchSnapshot(); - }); - test(`getRisk${entity.charAt(0).toUpperCase() + entity.slice(1)}CreateLevelScriptOptions`, () => { - const fn = - entity === RiskScoreEntity.host - ? getRiskHostCreateLevelScriptOptions - : getRiskUserCreateLevelScriptOptions; - const options = fn(); - expect(options).toMatchSnapshot(); - }); - test(`getRisk${entity.charAt(0).toUpperCase() + entity.slice(1)}CreateMapScriptOptions`, () => { - const fn = - entity === RiskScoreEntity.host - ? getRiskHostCreateMapScriptOptions - : getRiskUserCreateMapScriptOptions; - const options = fn(); - expect(options).toMatchSnapshot(); - }); - test(`getRisk${ - entity.charAt(0).toUpperCase() + entity.slice(1) - }CreateReduceScriptOptions`, () => { - const fn = - entity === RiskScoreEntity.host - ? getRiskHostCreateReduceScriptOptions - : getRiskUserCreateReduceScriptOptions; - const options = fn(); - expect(options).toMatchSnapshot(); - }); - - /** - * User risk score doesn't have init script, so we only check for host - */ - if (entity === RiskScoreEntity.host) { - test(`getRiskHostCreateInitScriptOptions`, () => { - const options = getRiskHostCreateInitScriptOptions(); - expect(options).toMatchSnapshot(); - }); - } -}); diff --git a/x-pack/plugins/security_solution/common/utils/risk_score_modules.ts b/x-pack/plugins/security_solution/common/utils/risk_score_modules.ts deleted file mode 100644 index 5c2d6d2a6af26..0000000000000 --- a/x-pack/plugins/security_solution/common/utils/risk_score_modules.ts +++ /dev/null @@ -1,587 +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 { DEFAULT_ALERTS_INDEX } from '../constants'; -import { RiskScoreEntity, RiskScoreFields } from '../search_strategy'; -import type { Pipeline, Processor } from '../types/risk_scores'; - -/** - * Aside from 8.4, all the transforms, scripts, - * and ingest pipelines (and dashboard saved objects) are created with spaceId - * so they won't affect each other across different spaces. - */ -export const getRiskScorePivotTransformId = ( - riskScoreEntity: RiskScoreEntity, - spaceId = 'default' -) => `ml_${riskScoreEntity}riskscore_pivot_transform_${spaceId}`; - -export const getRiskScoreLatestTransformId = ( - riskScoreEntity: RiskScoreEntity, - spaceId = 'default' -) => `ml_${riskScoreEntity}riskscore_latest_transform_${spaceId}`; - -export const getIngestPipelineName = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_ingest_pipeline_${spaceId}`; - -export const getPivotTransformIndex = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}_risk_score_${spaceId}`; - -export const getLatestTransformIndex = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}_risk_score_latest_${spaceId}`; - -export const getAlertsIndex = (spaceId = 'default') => `${DEFAULT_ALERTS_INDEX}-${spaceId}`; - -export const getRiskScoreLevelScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_levels_script_${spaceId}`; -export const getRiskScoreInitScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_init_script_${spaceId}`; -export const getRiskScoreMapScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_map_script_${spaceId}`; -export const getRiskScoreReduceScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_reduce_script_${spaceId}`; - -/** - * These scripts and Ingest pipeline were not space aware in 8.4 - * They were shared across spaces and therefore affected each other. - * New scripts and ingest pipeline are all independent in each space, so these ids - * are Deprecated. - * But We still need to keep track of the old ids, so we can delete them during upgrade. - */ -export const getLegacyIngestPipelineName = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_ingest_pipeline`; -export const getLegacyRiskScoreLevelScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_levels_script`; -export const getLegacyRiskScoreInitScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_init_script`; -export const getLegacyRiskScoreMapScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_map_script`; -export const getLegacyRiskScoreReduceScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_reduce_script`; - -/** - * This should be aligned with - * console_templates/enable_host_risk_score.console step 1 - */ -export const getRiskHostCreateLevelScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - "double risk_score = (def)ctx.getByPath(params.risk_score);\nif (risk_score < 20) {\n ctx['host']['risk']['calculated_level'] = 'Unknown'\n}\nelse if (risk_score >= 20 && risk_score < 40) {\n ctx['host']['risk']['calculated_level'] = 'Low'\n}\nelse if (risk_score >= 40 && risk_score < 70) {\n ctx['host']['risk']['calculated_level'] = 'Moderate'\n}\nelse if (risk_score >= 70 && risk_score < 90) {\n ctx['host']['risk']['calculated_level'] = 'High'\n}\nelse if (risk_score >= 90) {\n ctx['host']['risk']['calculated_level'] = 'Critical'\n}"; - return { - id: getRiskScoreLevelScriptId(RiskScoreEntity.host, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_host_risk_score.console step 2 - */ -export const getRiskHostCreateInitScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - 'state.rule_risk_stats = new HashMap();\nstate.host_variant_set = false;\nstate.host_variant = new String();\nstate.tactic_ids = new HashSet();'; - return { - id: getRiskScoreInitScriptId(RiskScoreEntity.host, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_host_risk_score.console step 3 - */ -export const getRiskHostCreateMapScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - '// Get the host variant\nif (state.host_variant_set == false) {\n if (doc.containsKey("host.os.full") && doc["host.os.full"].size() != 0) {\n state.host_variant = doc["host.os.full"].value;\n state.host_variant_set = true;\n }\n}\n// Aggregate all the tactics seen on the host\nif (doc.containsKey("signal.rule.threat.tactic.id") && doc["signal.rule.threat.tactic.id"].size() != 0) {\n state.tactic_ids.add(doc["signal.rule.threat.tactic.id"].value);\n}\n// Get running sum of time-decayed risk score per rule name per shard\nString rule_name = doc["signal.rule.name"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, [0.0,"",false]);\nint time_diff = (int)((System.currentTimeMillis() - doc["@timestamp"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0));\ndouble risk_derate = Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant));\nstats[0] = Math.max(stats[0], doc["signal.rule.risk_score"].value * risk_derate);\nif (stats[2] == false) {\n stats[1] = doc["kibana.alert.rule.uuid"].value;\n stats[2] = true;\n}\nstate.rule_risk_stats.put(rule_name, stats);'; - return { - id: getRiskScoreMapScriptId(RiskScoreEntity.host, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_host_risk_score.console step 4 - */ -export const getRiskHostCreateReduceScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - '// Consolidating time decayed risks and tactics from across all shards\nMap total_risk_stats = new HashMap();\nString host_variant = new String();\ndef tactic_ids = new HashSet();\nfor (state in states) {\n for (key in state.rule_risk_stats.keySet()) {\n def rule_stats = state.rule_risk_stats.get(key);\n def stats = total_risk_stats.getOrDefault(key, [0.0,"",false]);\n stats[0] = Math.max(stats[0], rule_stats[0]);\n if (stats[2] == false) {\n stats[1] = rule_stats[1];\n stats[2] = true;\n } \n total_risk_stats.put(key, stats);\n }\n if (host_variant.length() == 0) {\n host_variant = state.host_variant;\n }\n tactic_ids.addAll(state.tactic_ids);\n}\n// Consolidating individual rule risks and arranging them in decreasing order\nList risks = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n risks.add(total_risk_stats[key][0])\n}\nCollections.sort(risks, Collections.reverseOrder());\n// Calculating total host risk score\ndouble total_risk = 0.0;\ndouble risk_cap = params.max_risk * params.zeta_constant;\nfor (int i=0;i= 40 && total_norm_risk < 50) {\n total_norm_risk = 85 + (total_norm_risk - 40);\n}\nelse {\n total_norm_risk = 95 + (total_norm_risk - 50) / 10;\n}\n// Calculating multipliers to the host risk score\ndouble risk_multiplier = 1.0;\nList multipliers = new ArrayList();\n// Add a multiplier if host is a server\nif (host_variant.toLowerCase().contains("server")) {\n risk_multiplier *= params.server_multiplier;\n multipliers.add("Host is a server");\n}\n// Add multipliers based on number and diversity of tactics seen on the host\nfor (String tactic : tactic_ids) {\n multipliers.add("Tactic "+tactic);\n risk_multiplier *= 1 + params.tactic_base_multiplier * params.tactic_weights.getOrDefault(tactic, 0);\n}\n// Calculating final risk\ndouble final_risk = total_norm_risk;\nif (risk_multiplier > 1.0) {\n double prior_odds = (total_norm_risk) / (100 - total_norm_risk);\n double updated_odds = prior_odds * risk_multiplier; \n final_risk = 100 * updated_odds / (1 + updated_odds);\n}\n// Adding additional metadata\nList rule_stats = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n Map temp = new HashMap();\n temp["rule_name"] = key;\n temp["rule_risk"] = total_risk_stats[key][0];\n temp["rule_id"] = total_risk_stats[key][1];\n rule_stats.add(temp);\n}\n\nreturn ["calculated_score_norm": final_risk, "rule_risks": rule_stats, "multipliers": multipliers];'; - return { - id: getRiskScoreReduceScriptId(RiskScoreEntity.host, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 1 - */ -export const getRiskUserCreateLevelScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - "double risk_score = (def)ctx.getByPath(params.risk_score);\nif (risk_score < 20) {\n ctx['user']['risk']['calculated_level'] = 'Unknown'\n}\nelse if (risk_score >= 20 && risk_score < 40) {\n ctx['user']['risk']['calculated_level'] = 'Low'\n}\nelse if (risk_score >= 40 && risk_score < 70) {\n ctx['user']['risk']['calculated_level'] = 'Moderate'\n}\nelse if (risk_score >= 70 && risk_score < 90) {\n ctx['user']['risk']['calculated_level'] = 'High'\n}\nelse if (risk_score >= 90) {\n ctx['user']['risk']['calculated_level'] = 'Critical'\n}"; - return { - id: getRiskScoreLevelScriptId(RiskScoreEntity.user, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 2 - */ -export const getRiskUserCreateMapScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - '// Get running sum of risk score per rule name per shard\\\\\nString rule_name = doc["signal.rule.name"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, 0.0);\nstats = doc["signal.rule.risk_score"].value;\nstate.rule_risk_stats.put(rule_name, stats);'; - return { - id: getRiskScoreMapScriptId(RiskScoreEntity.user, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 3 - */ -export const getRiskUserCreateReduceScriptOptions = ( - spaceId = 'default', - stringifyScript?: boolean -) => { - const source = - '// Consolidating time decayed risks from across all shards\nMap total_risk_stats = new HashMap();\nfor (state in states) {\n for (key in state.rule_risk_stats.keySet()) {\n def rule_stats = state.rule_risk_stats.get(key);\n def stats = total_risk_stats.getOrDefault(key, 0.0);\n stats = rule_stats;\n total_risk_stats.put(key, stats);\n }\n}\n// Consolidating individual rule risks and arranging them in decreasing order\nList risks = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n risks.add(total_risk_stats[key])\n}\nCollections.sort(risks, Collections.reverseOrder());\n// Calculating total risk and normalizing it to a range\ndouble total_risk = 0.0;\ndouble risk_cap = params.max_risk * params.zeta_constant;\nfor (int i=0;i= 40 && total_norm_risk < 50) {\n total_norm_risk = 85 + (total_norm_risk - 40);\n}\nelse {\n total_norm_risk = 95 + (total_norm_risk - 50) / 10;\n}\n\nList rule_stats = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n Map temp = new HashMap();\n temp["rule_name"] = key;\n temp["rule_risk"] = total_risk_stats[key];\n rule_stats.add(temp);\n}\n\nreturn ["calculated_score_norm": total_norm_risk, "rule_risks": rule_stats];'; - return { - id: getRiskScoreReduceScriptId(RiskScoreEntity.user, spaceId), - script: { - lang: 'painless', - source: stringifyScript ? JSON.stringify(source) : source, - }, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 4 - * console_templates/enable_host_risk_score.console step 5 - */ -export const getRiskScoreIngestPipelineOptions = ( - riskScoreEntity: RiskScoreEntity, - spaceId = 'default', - stringifyScript?: boolean -): Pipeline => { - const processors: Processor[] = [ - { - set: { - field: 'ingest_timestamp', - value: '{{_ingest.timestamp}}', - }, - }, - { - fingerprint: { - fields: ['@timestamp', '_id'], - method: 'SHA-256', - target_field: '_id', - }, - }, - { - script: { - id: getRiskScoreLevelScriptId(riskScoreEntity, spaceId), - params: { - risk_score: `${riskScoreEntity}.risk.calculated_score_norm`, - }, - }, - }, - ]; - return { - name: getIngestPipelineName(riskScoreEntity, spaceId), - processors: stringifyScript ? JSON.stringify(processors) : processors, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 5 - * console_templates/enable_host_risk_score.console step 6 - */ -export const getCreateRiskScoreIndicesOptions = ({ - spaceId = 'default', - riskScoreEntity, - stringifyScript, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; - stringifyScript?: boolean; -}) => { - const mappings = { - properties: { - [riskScoreEntity]: { - properties: { - name: { - type: 'keyword', - }, - risk: { - properties: { - calculated_score_norm: { - type: 'float', - }, - calculated_level: { - type: 'keyword', - }, - multipliers: { - type: 'keyword', - }, - rule_risks: { - properties: { - rule_name: { - type: 'text', - fields: { - keyword: { - type: 'keyword', - }, - }, - }, - rule_risk: { - type: 'float', - }, - rule_id: { - type: 'keyword', - }, - }, - }, - }, - }, - }, - }, - ingest_timestamp: { - type: 'date', - }, - '@timestamp': { - type: 'date', - }, - }, - }; - return { - index: getPivotTransformIndex(riskScoreEntity, spaceId), - mappings: stringifyScript ? JSON.stringify(mappings) : mappings, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 8 - * console_templates/enable_host_risk_score.console step 9 - */ -export const getCreateRiskScoreLatestIndicesOptions = ({ - spaceId = 'default', - riskScoreEntity, - stringifyScript, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; - stringifyScript?: boolean; -}) => { - const mappings = { - properties: { - [riskScoreEntity]: { - properties: { - name: { - type: 'keyword', - }, - risk: { - properties: { - calculated_score_norm: { - type: 'float', - }, - calculated_level: { - type: 'keyword', - }, - multipliers: { - type: 'keyword', - }, - rule_risks: { - properties: { - rule_name: { - type: 'text', - fields: { - keyword: { - type: 'keyword', - }, - }, - }, - rule_risk: { - type: 'float', - }, - rule_id: { - type: 'keyword', - }, - }, - }, - }, - }, - }, - }, - ingest_timestamp: { - type: 'date', - }, - '@timestamp': { - type: 'date', - }, - }, - }; - return { - index: getLatestTransformIndex(riskScoreEntity, spaceId), - mappings: stringifyScript ? JSON.stringify(mappings) : mappings, - }; -}; - -/** - * This should be aligned with - * console_templates/enable_host_risk_score.console step 7 - */ -export const getCreateMLHostPivotTransformOptions = ({ - spaceId = 'default', - stringifyScript, -}: { - spaceId?: string; - stringifyScript?: boolean; -}) => { - const options = { - dest: { - index: getPivotTransformIndex(RiskScoreEntity.host, spaceId), - pipeline: getIngestPipelineName(RiskScoreEntity.host, spaceId), - }, - frequency: '1h', - pivot: { - aggregations: { - '@timestamp': { - max: { - field: '@timestamp', - }, - }, - 'host.risk': { - scripted_metric: { - combine_script: 'return state', - init_script: { - id: getRiskScoreInitScriptId(RiskScoreEntity.host, spaceId), - }, - map_script: { - id: getRiskScoreMapScriptId(RiskScoreEntity.host, spaceId), - }, - params: { - lookback_time: 72, - max_risk: 100, - p: 1.5, - server_multiplier: 1.5, - tactic_base_multiplier: 0.25, - tactic_weights: { - TA0001: 1, - TA0002: 2, - TA0003: 3, - TA0004: 4, - TA0005: 4, - TA0006: 4, - TA0007: 4, - TA0008: 5, - TA0009: 6, - TA0010: 7, - TA0011: 6, - TA0040: 8, - TA0042: 1, - TA0043: 1, - }, - time_decay_constant: 6, - zeta_constant: 2.612, - }, - reduce_script: { - id: getRiskScoreReduceScriptId(RiskScoreEntity.host, spaceId), - }, - }, - }, - }, - group_by: { - [RiskScoreFields.hostName]: { - terms: { - field: RiskScoreFields.hostName, - }, - }, - }, - }, - source: { - index: [getAlertsIndex(spaceId)], - query: { - bool: { - filter: [ - { - range: { - '@timestamp': { - gte: 'now-5d', - }, - }, - }, - ], - }, - }, - }, - sync: { - time: { - delay: '120s', - field: '@timestamp', - }, - }, - }; - - return stringifyScript ? JSON.stringify(options) : options; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 6 - */ -export const getCreateMLUserPivotTransformOptions = ({ - spaceId = 'default', - stringifyScript, -}: { - spaceId?: string; - stringifyScript?: boolean; -}) => { - const options = { - dest: { - index: getPivotTransformIndex(RiskScoreEntity.user, spaceId), - pipeline: getIngestPipelineName(RiskScoreEntity.user, spaceId), - }, - frequency: '1h', - pivot: { - aggregations: { - '@timestamp': { - max: { - field: '@timestamp', - }, - }, - 'user.risk': { - scripted_metric: { - combine_script: 'return state', - init_script: 'state.rule_risk_stats = new HashMap();', - map_script: { - id: getRiskScoreMapScriptId(RiskScoreEntity.user, spaceId), - }, - params: { - max_risk: 100, - p: 1.5, - zeta_constant: 2.612, - }, - reduce_script: { - id: getRiskScoreReduceScriptId(RiskScoreEntity.user, spaceId), - }, - }, - }, - }, - group_by: { - 'user.name': { - terms: { - field: 'user.name', - }, - }, - }, - }, - source: { - index: [getAlertsIndex(spaceId)], - query: { - bool: { - filter: [ - { - range: { - '@timestamp': { - gte: 'now-90d', - }, - }, - }, - { - match: { - 'signal.status': 'open', - }, - }, - ], - }, - }, - }, - sync: { - time: { - delay: '120s', - field: '@timestamp', - }, - }, - }; - return stringifyScript ? JSON.stringify(options) : options; -}; - -/** - * This should be aligned with - * console_templates/enable_user_risk_score.console step 9 - * console_templates/enable_host_risk_score.console step 10 - */ -export const getCreateLatestTransformOptions = ({ - spaceId = 'default', - riskScoreEntity, - stringifyScript, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; - stringifyScript?: boolean; -}) => { - const options = { - dest: { - index: getLatestTransformIndex(riskScoreEntity, spaceId), - }, - frequency: '1h', - latest: { - sort: '@timestamp', - unique_key: [`${riskScoreEntity}.name`], - }, - source: { - index: [getPivotTransformIndex(riskScoreEntity, spaceId)], - }, - sync: { - time: { - delay: '2s', - field: 'ingest_timestamp', - }, - }, - }; - return stringifyScript ? JSON.stringify(options) : options; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx index f6f8597ef52a7..79f2d2a54d37b 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/visualization_embeddable.test.tsx @@ -14,7 +14,6 @@ import * as inputActions from '../../store/inputs/actions'; import { InputsModelId } from '../../store/inputs/constants'; import { createMockStore, mockGlobalState, TestProviders } from '../../mock'; import { useRefetchByRestartingSession } from '../page/use_refetch_by_session'; -import { getRiskScoreDonutAttributes } from '../../../entity_analytics/lens_attributes/risk_score_donut'; jest.mock('./lens_embeddable'); jest.mock('../page/use_refetch_by_session', () => ({ @@ -148,36 +147,4 @@ describe('VisualizationEmbeddable', () => { }); }); }); - - describe('when isDonut = true', () => { - beforeEach(() => { - jest.clearAllMocks(); - (useRefetchByRestartingSession as jest.Mock).mockReturnValue({ - session: { - current: { - start: jest - .fn() - .mockReturnValueOnce(mockSearchSessionId) - .mockReturnValue(mockSearchSessionIdDefault), - }, - }, - refetchByRestartingSession: mockRefetchByRestartingSession, - }); - res = render( - - - - ); - }); - - it('should render donut wrapper ', () => { - expect(res.getByTestId('donut-chart')).toBeInTheDocument(); - }); - }); }); diff --git a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.test.tsx index fade86c6c698c..ffec23cecbaac 100644 --- a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.test.tsx @@ -13,11 +13,6 @@ jest.mock('../../use_search_strategy', () => ({ useSearchStrategy: jest.fn(), })); -jest.mock('../../../../entity_analytics/api/hooks/use_risk_engine_status', () => ({ - useIsNewRiskScoreModuleInstalled: jest - .fn() - .mockReturnValue({ isLoading: false, installed: true }), -})); const mockUseSearchStrategy = useSearchStrategy as jest.Mock; const mockSearch = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.tsx b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.tsx index 81bca2bed7cf2..d43410ae86ae1 100644 --- a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_hosts/index.tsx @@ -12,7 +12,6 @@ import { RelatedEntitiesQueries } from '../../../../../common/search_strategy/se import type { RelatedHost } from '../../../../../common/search_strategy/security_solution/related_entities/related_hosts'; import { useSearchStrategy } from '../../use_search_strategy'; import { FAIL_RELATED_HOSTS } from './translations'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; export interface UseUserRelatedHostsResult { inspect: InspectResponse; @@ -51,9 +50,6 @@ export const useUserRelatedHosts = ({ abort: skip, }); - const { installed: isNewRiskScoreModuleInstalled, isLoading: riskScoreStatusLoading } = - useIsNewRiskScoreModuleInstalled(); - const userRelatedHostsResponse = useMemo( () => ({ inspect, @@ -71,16 +67,15 @@ export const useUserRelatedHosts = ({ factoryQueryType: RelatedEntitiesQueries.relatedHosts, userName, from, - isNewRiskScoreModuleInstalled, }), - [indexNames, from, userName, isNewRiskScoreModuleInstalled] + [indexNames, from, userName] ); useEffect(() => { - if (!skip && !riskScoreStatusLoading) { + if (!skip) { search(userRelatedHostsRequest); } - }, [userRelatedHostsRequest, search, skip, riskScoreStatusLoading]); + }, [userRelatedHostsRequest, search, skip]); return userRelatedHostsResponse; }; diff --git a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.test.tsx index 51bf34bddd338..38d050e9e8fa3 100644 --- a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.test.tsx @@ -13,12 +13,6 @@ jest.mock('../../use_search_strategy', () => ({ useSearchStrategy: jest.fn(), })); -jest.mock('../../../../entity_analytics/api/hooks/use_risk_engine_status', () => ({ - useIsNewRiskScoreModuleInstalled: jest - .fn() - .mockReturnValue({ isLoading: false, installed: true }), -})); - const mockUseSearchStrategy = useSearchStrategy as jest.Mock; const mockSearch = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.tsx b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.tsx index c759b33d29954..7369ca2d57024 100644 --- a/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/related_entities/related_users/index.tsx @@ -12,7 +12,6 @@ import { RelatedEntitiesQueries } from '../../../../../common/search_strategy/se import type { RelatedUser } from '../../../../../common/search_strategy/security_solution/related_entities/related_users'; import { useSearchStrategy } from '../../use_search_strategy'; import { FAIL_RELATED_USERS } from './translations'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; export interface UseHostRelatedUsersResult { inspect: InspectResponse; @@ -35,8 +34,6 @@ export const useHostRelatedUsers = ({ from, skip = false, }: UseHostRelatedUsersParam): UseHostRelatedUsersResult => { - const { installed: isNewRiskScoreModuleInstalled, isLoading: riskScoreStatusLoading } = - useIsNewRiskScoreModuleInstalled(); const { loading, result: response, @@ -70,16 +67,15 @@ export const useHostRelatedUsers = ({ factoryQueryType: RelatedEntitiesQueries.relatedUsers, hostName, from, - isNewRiskScoreModuleInstalled, }), - [indexNames, from, hostName, isNewRiskScoreModuleInstalled] + [indexNames, from, hostName] ); useEffect(() => { - if (!skip && !riskScoreStatusLoading) { + if (!skip) { search(hostRelatedUsersRequest); } - }, [hostRelatedUsersRequest, riskScoreStatusLoading, search, skip]); + }, [hostRelatedUsersRequest, search, skip]); return hostRelatedUsersResponse; }; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts b/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts index f7bcf5030ca8d..21e6cfedc3096 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts +++ b/x-pack/plugins/security_solution/public/common/hooks/use_fetch/request_names.ts @@ -12,10 +12,6 @@ export const REQUEST_NAMES = { SECURITY_CREATE_TAG: `${APP_UI_ID} fetch security create tag`, CTI_TAGS: `${APP_UI_ID} fetch cti tags`, ANOMALIES_TABLE: `${APP_UI_ID} fetch anomalies table data`, - GET_RISK_SCORE_DEPRECATED: `${APP_UI_ID} fetch is risk score deprecated`, - ENABLE_RISK_SCORE: `${APP_UI_ID} fetch enable risk score`, - REFRESH_RISK_SCORE: `${APP_UI_ID} fetch refresh risk score`, - UPGRADE_RISK_SCORE: `${APP_UI_ID} fetch upgrade risk score`, } as const; export type RequestName = (typeof REQUEST_NAMES)[keyof typeof REQUEST_NAMES]; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts index fa33d8fa575be..9e585e4b4486f 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/api.ts @@ -28,7 +28,6 @@ import type { AssetCriticalityRecord, EntityAnalyticsPrivileges, } from '../../../common/api/entity_analytics'; -import type { RiskScoreEntity } from '../../../common/search_strategy'; import { RISK_ENGINE_STATUS_URL, RISK_SCORE_PREVIEW_URL, @@ -38,7 +37,6 @@ import { RISK_ENGINE_PRIVILEGES_URL, ASSET_CRITICALITY_INTERNAL_PRIVILEGES_URL, ASSET_CRITICALITY_PUBLIC_URL, - RISK_SCORE_INDEX_STATUS_API_URL, RISK_ENGINE_SETTINGS_URL, ASSET_CRITICALITY_PUBLIC_CSV_UPLOAD_URL, RISK_SCORE_ENTITY_CALCULATION_URL, @@ -258,27 +256,6 @@ export const useEntityAnalyticsRoutes = () => { ); }; - const getRiskScoreIndexStatus = ({ - query, - signal, - }: { - query: { - indexName: string; - entity: RiskScoreEntity; - }; - signal?: AbortSignal; - }): Promise<{ - isDeprecated: boolean; - isEnabled: boolean; - }> => - http.fetch<{ isDeprecated: boolean; isEnabled: boolean }>(RISK_SCORE_INDEX_STATUS_API_URL, { - version: '1', - method: 'GET', - query, - asSystemRequest: true, - signal, - }); - /** * Fetches risk engine settings */ @@ -312,7 +289,6 @@ export const useEntityAnalyticsRoutes = () => { deleteAssetCriticality, fetchAssetCriticality, uploadAssetCriticalityFile, - getRiskScoreIndexStatus, fetchRiskEngineSettings, calculateEntityRiskScore, cleanUpRiskEngine, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_engine_status.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_engine_status.ts index a9c9dc0939b03..6e4c3b2e1b779 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_engine_status.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_engine_status.ts @@ -7,10 +7,8 @@ import type { UseQueryOptions } from '@tanstack/react-query'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useCallback } from 'react'; -import type { RiskEngineStatusResponse } from '../../../../common/api/entity_analytics/risk_engine/engine_status_route.gen'; -import { RiskEngineStatusEnum } from '../../../../common/api/entity_analytics/risk_engine/engine_status_route.gen'; +import type { RiskEngineStatusResponse } from '../../../../common/api/entity_analytics'; import { useEntityAnalyticsRoutes } from '../api'; -import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; const FETCH_RISK_ENGINE_STATUS = ['GET', 'FETCH_RISK_ENGINE_STATUS']; export const useInvalidateRiskEngineStatusQuery = () => { @@ -23,61 +21,16 @@ export const useInvalidateRiskEngineStatusQuery = () => { }, [queryClient]); }; -interface RiskScoreModuleStatus { - isLoading: boolean; - installed?: boolean; -} - -export const useIsNewRiskScoreModuleInstalled = (): RiskScoreModuleStatus => { - const { data: riskEngineStatus, isLoading } = useRiskEngineStatus(); - - if (isLoading) { - return { isLoading: true }; - } - - return { isLoading: false, installed: !!riskEngineStatus?.isNewRiskScoreModuleInstalled }; -}; - -interface RiskEngineStatus extends RiskEngineStatusResponse { - isUpdateAvailable: boolean; - isNewRiskScoreModuleInstalled: boolean; - isNewRiskScoreModuleAvailable: boolean; -} - export const useRiskEngineStatus = ( queryOptions: Pick< - UseQueryOptions, + UseQueryOptions, 'refetchInterval' | 'structuralSharing' > = {} ) => { - const isNewRiskScoreModuleAvailable = useIsExperimentalFeatureEnabled('riskScoringRoutesEnabled'); const { fetchRiskEngineStatus } = useEntityAnalyticsRoutes(); return useQuery( FETCH_RISK_ENGINE_STATUS, - async ({ signal }) => { - if (!isNewRiskScoreModuleAvailable) { - return { - isUpdateAvailable: false, - isNewRiskScoreModuleInstalled: false, - isNewRiskScoreModuleAvailable, - risk_engine_status: null, - legacy_risk_engine_status: null, - risk_engine_task_status: null, - }; - } - const response = await fetchRiskEngineStatus({ signal }); - const isUpdateAvailable = - response?.legacy_risk_engine_status === RiskEngineStatusEnum.ENABLED && - response.risk_engine_status === RiskEngineStatusEnum.NOT_INSTALLED; - const isNewRiskScoreModuleInstalled = - response.risk_engine_status !== RiskEngineStatusEnum.NOT_INSTALLED; - return { - isUpdateAvailable, - isNewRiskScoreModuleInstalled, - isNewRiskScoreModuleAvailable, - ...response, - }; - }, + async ({ signal }) => fetchRiskEngineStatus({ signal }), queryOptions ); }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx index 60fdb04dffa96..82cd125d7443d 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx @@ -7,12 +7,9 @@ import { renderHook } from '@testing-library/react-hooks'; import { useRiskScore } from './use_risk_score'; import { TestProviders } from '../../../common/mock'; - import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { useAppToastsMock } from '../../../common/hooks/use_app_toasts.mock'; -import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; -import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status'; import { RiskScoreEntity } from '../../../../common/search_strategy'; jest.mock('../../../common/containers/use_search_strategy', () => ({ useSearchStrategy: jest.fn(), @@ -23,29 +20,13 @@ jest.mock('../../../common/hooks/use_space_id', () => ({ })); jest.mock('../../../common/hooks/use_app_toasts'); -jest.mock('./use_risk_score_feature_status'); - jest.mock('./use_risk_engine_status'); -const mockUseIsNewRiskScoreModuleInstalled = useIsNewRiskScoreModuleInstalled as jest.Mock; -const mockUseRiskScoreFeatureStatus = useRiskScoreFeatureStatus as jest.Mock; const mockUseSearchStrategy = useSearchStrategy as jest.Mock; const mockSearch = jest.fn(); let appToastsMock: jest.Mocked>; -const defaultRiskScoreModuleStatus = { - isLoading: false, - installed: false, -}; - -const defaultFeatureStatus = { - isLoading: false, - isDeprecated: false, - isAuthorized: true, - isEnabled: true, - refetch: () => {}, -}; const defaultRisk = { data: undefined, inspect: {}, @@ -73,16 +54,10 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( jest.clearAllMocks(); appToastsMock = useAppToastsMock.create(); (useAppToasts as jest.Mock).mockReturnValue(appToastsMock); - mockUseRiskScoreFeatureStatus.mockReturnValue(defaultFeatureStatus); mockUseSearchStrategy.mockReturnValue(defaultSearchResponse); - mockUseIsNewRiskScoreModuleInstalled.mockReturnValue(defaultRiskScoreModuleStatus); }); test('does not search if license is not valid', () => { - mockUseRiskScoreFeatureStatus.mockReturnValue({ - ...defaultFeatureStatus, - isAuthorized: false, - }); const { result } = renderHook(() => useRiskScore({ riskEntity }), { wrapper: TestProviders, }); @@ -95,11 +70,6 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( }); }); test('does not search if feature is not enabled', () => { - mockUseRiskScoreFeatureStatus.mockReturnValue({ - ...defaultFeatureStatus, - isEnabled: false, - }); - const { result } = renderHook(() => useRiskScore({ riskEntity }), { wrapper: TestProviders, }); @@ -113,10 +83,6 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( }); test('does not search if index is deprecated ', () => { - mockUseRiskScoreFeatureStatus.mockReturnValue({ - ...defaultFeatureStatus, - isDeprecated: true, - }); const { result } = renderHook(() => useRiskScore({ riskEntity, skip: true }), { wrapper: TestProviders, }); @@ -130,11 +96,6 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( }); test('handle index not found error', () => { - mockUseRiskScoreFeatureStatus.mockReturnValue({ - ...defaultFeatureStatus, - isDeprecated: false, - isEnabled: false, - }); mockUseSearchStrategy.mockReturnValue({ ...defaultSearchResponse, error: { @@ -192,11 +153,6 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( }); test('runs search with new index if feature is enabled and not deprecated and new module installed', () => { - mockUseIsNewRiskScoreModuleInstalled.mockReturnValue({ - ...defaultRiskScoreModuleStatus, - installed: true, - }); - renderHook(() => useRiskScore({ riskEntity }), { wrapper: TestProviders, }); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx index b82c805d3622e..50756f092e27b 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx @@ -8,24 +8,20 @@ import { useCallback, useEffect, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; import { createFilter } from '../../../common/containers/helpers'; import type { RiskScoreSortField, StrategyResponseType } from '../../../../common/search_strategy'; -import { - RiskQueries, - getUserRiskIndex, - RiskScoreEntity, - getHostRiskIndex, -} from '../../../../common/search_strategy'; +import { RiskQueries, RiskScoreEntity } from '../../../../common/search_strategy'; import type { ESQuery } from '../../../../common/typed_json'; import type { InspectResponse } from '../../../types'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { isIndexNotFoundError } from '../../../common/utils/exceptions'; import type { inputsModel } from '../../../common/store'; -import { useSpaceId } from '../../../common/hooks/use_space_id'; import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; -import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status'; +import { useGetDefaulRiskIndex } from '../../hooks/use_get_default_risk_index'; +import { useHasSecurityCapability } from '../../../helper_hooks'; +import { useRiskEngineStatus } from './use_risk_engine_status'; export interface RiskScoreState { data: @@ -37,9 +33,8 @@ export interface RiskScoreState): RiskScoreState => { - const spaceId = useSpaceId(); - const { installed: isNewRiskScoreModuleInstalled, isLoading: riskScoreStatusLoading } = - useIsNewRiskScoreModuleInstalled(); - const defaultIndex = - spaceId && !riskScoreStatusLoading && isNewRiskScoreModuleInstalled !== undefined - ? riskEntity === RiskScoreEntity.host - ? getHostRiskIndex(spaceId, onlyLatest, isNewRiskScoreModuleInstalled) - : getUserRiskIndex(spaceId, onlyLatest, isNewRiskScoreModuleInstalled) - : undefined; + const defaultIndex = useGetDefaulRiskIndex(riskEntity, onlyLatest); const factoryQueryType = riskEntity === RiskScoreEntity.host ? RiskQueries.hostsRiskScore : RiskQueries.usersRiskScore; - const { querySize, cursorStart } = pagination || {}; - const { addError } = useAppToasts(); - - const { - isDeprecated, - isEnabled, - isAuthorized, - isLoading: isDeprecatedLoading, - refetch: refetchDeprecated, - } = useRiskScoreFeatureStatus(riskEntity, defaultIndex); - + const { isPlatinumOrTrialLicense } = useMlCapabilities(); + const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics'); + const isAuthorized = isPlatinumOrTrialLicense && hasEntityAnalyticsCapability; + const { data: riskEngineStatus, isFetching: isStatusLoading } = useRiskEngineStatus(); + const isEngineEnabled = riskEngineStatus?.risk_engine_status === 'ENABLED'; const { loading, result: response, @@ -120,10 +101,9 @@ export const useRiskScore = { if (defaultIndex) { - refetchDeprecated(defaultIndex); refetch(); } - }, [defaultIndex, refetch, refetchDeprecated]); + }, [defaultIndex, refetch]); const riskScoreResponse = useMemo( () => ({ @@ -132,21 +112,11 @@ export const useRiskScore = { - if ( - !skip && - !isDeprecatedLoading && - riskScoreRequest != null && - isAuthorized && - isEnabled && - !isDeprecated - ) { + if (!skip && riskScoreRequest != null && isAuthorized) { search(riskScoreRequest); } - }, [isEnabled, isDeprecated, isAuthorized, isDeprecatedLoading, riskScoreRequest, search, skip]); + }, [isAuthorized, riskScoreRequest, search, skip]); - const result = { ...riskScoreResponse, loading: loading || isDeprecatedLoading }; + const result = { ...riskScoreResponse, loading: loading || isStatusLoading }; return result; }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts deleted file mode 100644 index 30719d1559f54..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.test.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { act, renderHook } from '@testing-library/react-hooks'; -import { TestProviders } from '../../../common/mock'; - -import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { useFetch } from '../../../common/hooks/use_fetch'; -import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; -import { useHasSecurityCapability } from '../../../helper_hooks'; - -jest.mock('../../../common/hooks/use_fetch'); -jest.mock('../../../common/components/ml/hooks/use_ml_capabilities'); -jest.mock('../../../helper_hooks'); - -const mockFetch = jest.fn(); -const mockUseMlCapabilities = useMlCapabilities as jest.Mock; -const mockUseFetch = useFetch as jest.Mock; -const mockUseHasSecurityCapability = useHasSecurityCapability as jest.Mock; - -describe(`risk score feature status`, () => { - beforeEach(() => { - jest.clearAllMocks(); - mockUseMlCapabilities.mockReturnValue({ isPlatinumOrTrialLicense: true }); - mockUseFetch.mockReturnValue(defaultFetch); - mockUseHasSecurityCapability.mockReturnValue(true); - }); - - const defaultFetch = { - data: undefined, - error: undefined, - fetch: mockFetch, - isLoading: false, - refetch: () => {}, - }; - const defaultResult = { - error: undefined, - isDeprecated: true, - isAuthorized: true, - isEnabled: true, - isLoading: true, - }; - - test('does not search if license is not valid, and initial isDeprecated state is false', () => { - mockUseMlCapabilities.mockReturnValue({ isPlatinumOrTrialLicense: false }); - const { result } = renderHook( - () => useRiskScoreFeatureStatus(RiskScoreEntity.host, 'the_right_one'), - { - wrapper: TestProviders, - } - ); - expect(mockFetch).not.toHaveBeenCalled(); - expect(result.current).toEqual({ - ...defaultResult, - isAuthorized: false, - isDeprecated: false, - isEnabled: false, - refetch: result.current.refetch, - }); - }); - - test("does not search if the user doesn't has entity analytics capability", () => { - mockUseHasSecurityCapability.mockReturnValue(false); - const { result } = renderHook( - () => useRiskScoreFeatureStatus(RiskScoreEntity.host, 'the_right_one'), - { - wrapper: TestProviders, - } - ); - expect(mockFetch).not.toHaveBeenCalled(); - expect(result.current).toEqual({ - ...defaultResult, - isAuthorized: false, - isDeprecated: false, - isEnabled: false, - refetch: result.current.refetch, - }); - }); - - test('runs search if feature is enabled, and initial isDeprecated state is true', () => { - const { result } = renderHook( - () => useRiskScoreFeatureStatus(RiskScoreEntity.host, 'the_right_one'), - { - wrapper: TestProviders, - } - ); - expect(mockFetch).toHaveBeenCalledWith({ - query: { entity: RiskScoreEntity.host, indexName: 'the_right_one' }, - }); - expect(result.current).toEqual({ - ...defaultResult, - refetch: result.current.refetch, - }); - }); - - test('updates state after search returns isDeprecated = false', () => { - const { result, rerender } = renderHook( - () => useRiskScoreFeatureStatus(RiskScoreEntity.host, 'the_right_one'), - { - wrapper: TestProviders, - } - ); - expect(result.current).toEqual({ - ...defaultResult, - refetch: result.current.refetch, - }); - mockUseFetch.mockReturnValue({ - ...defaultFetch, - data: { - isDeprecated: false, - isEnabled: true, - }, - }); - act(() => rerender()); - expect(result.current).toEqual({ - ...defaultResult, - isDeprecated: false, - refetch: result.current.refetch, - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts deleted file mode 100644 index 03fb48f56559a..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_feature_status.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useCallback, useEffect, useMemo } from 'react'; -import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; -import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch'; -import type { RiskScoreEntity } from '../../../../common/search_strategy'; -import { useHasSecurityCapability } from '../../../helper_hooks'; -import { useEntityAnalyticsRoutes } from '../api'; - -interface RiskScoresFeatureStatus { - error: unknown; - // Is transform index an old version? - isDeprecated: boolean; - // Does the transform index exist? - isEnabled: boolean; - // Does the user has the authorization for the risk score feature? - isAuthorized: boolean; - isLoading: boolean; - refetch: (indexName: string) => void; -} - -export const useRiskScoreFeatureStatus = ( - riskEntity: RiskScoreEntity.host | RiskScoreEntity.user, - defaultIndex?: string -): RiskScoresFeatureStatus => { - const { isPlatinumOrTrialLicense, capabilitiesFetched } = useMlCapabilities(); - const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics'); - const isAuthorized = isPlatinumOrTrialLicense && hasEntityAnalyticsCapability; - const { getRiskScoreIndexStatus } = useEntityAnalyticsRoutes(); - - const { fetch, data, isLoading, error } = useFetch( - REQUEST_NAMES.GET_RISK_SCORE_DEPRECATED, - getRiskScoreIndexStatus - ); - - const response = useMemo( - // if authorized is true, let isDeprecated = true so the actual - // risk score fetch is not called until this check is complete - () => (data ? data : { isDeprecated: isAuthorized, isEnabled: isAuthorized }), - // isAuthorized is initial state, not update requirement - // eslint-disable-next-line react-hooks/exhaustive-deps - [data] - ); - - const searchIndexStatus = useCallback( - (indexName: string) => { - if (isAuthorized) { - fetch({ - query: { indexName, entity: riskEntity }, - }); - } - }, - [isAuthorized, fetch, riskEntity] - ); - - useEffect(() => { - if (defaultIndex != null) { - searchIndexStatus(defaultIndex); - } - }, [defaultIndex, searchIndexStatus]); - - return { - error, - isLoading: isLoading || !capabilitiesFetched || defaultIndex == null, - refetch: searchIndexStatus, - isAuthorized, - ...response, - }; -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx index c25c2d126456d..90993db7771d3 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score_kpi.tsx @@ -8,24 +8,21 @@ import { useCallback, useEffect, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; +import type { RiskScoreEntity } from '../../../../common/search_strategy'; import { - getHostRiskIndex, - getUserRiskIndex, RiskQueries, RiskSeverity, - RiskScoreEntity, EMPTY_SEVERITY_COUNT, } from '../../../../common/search_strategy'; import { isIndexNotFoundError } from '../../../common/utils/exceptions'; import type { ESQuery } from '../../../../common/typed_json'; import type { SeverityCount } from '../../components/severity/types'; -import { useSpaceId } from '../../../common/hooks/use_space_id'; import { useSearchStrategy } from '../../../common/containers/use_search_strategy'; import type { InspectResponse } from '../../../types'; import type { inputsModel } from '../../../common/store'; import { useAppToasts } from '../../../common/hooks/use_app_toasts'; -import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status'; -import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status'; +import { useGetDefaulRiskIndex } from '../../hooks/use_get_default_risk_index'; +import { useRiskEngineStatus } from './use_risk_engine_status'; interface RiskScoreKpi { error: unknown; @@ -51,24 +48,13 @@ export const useRiskScoreKpi = ({ timerange, }: UseRiskScoreKpiProps): RiskScoreKpi => { const { addError } = useAppToasts(); - const spaceId = useSpaceId(); - const { installed: isNewRiskScoreModuleInstalled, isLoading: riskScoreStatusLoading } = - useIsNewRiskScoreModuleInstalled(); - const defaultIndex = - spaceId && !riskScoreStatusLoading && isNewRiskScoreModuleInstalled !== undefined - ? riskEntity === RiskScoreEntity.host - ? getHostRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled) - : getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled) - : undefined; - + const defaultIndex = useGetDefaulRiskIndex(riskEntity); const { - isDeprecated, - isEnabled, - isAuthorized, - isLoading: isDeprecatedLoading, - refetch: refetchFeatureStatus, - } = useRiskScoreFeatureStatus(riskEntity, defaultIndex); - + data: riskEngineStatus, + isFetching: isStatusLoading, + refetch: refetchEngineStatus, + } = useRiskEngineStatus(); + const riskEngineHasBeenEnabled = riskEngineStatus?.risk_engine_status !== 'NOT_INSTALLED'; const { loading, result, search, refetch, inspect, error } = useSearchStrategy({ factoryQueryType: RiskQueries.kpiRiskScore, @@ -87,14 +73,7 @@ export const useRiskScoreKpi = ({ ); useEffect(() => { - if ( - !skip && - defaultIndex && - !isDeprecatedLoading && - isAuthorized && - isEnabled && - !isDeprecated - ) { + if (!skip && defaultIndex && !isStatusLoading && riskEngineHasBeenEnabled) { search({ filterQuery, defaultIndex: [defaultIndex], @@ -109,18 +88,16 @@ export const useRiskScoreKpi = ({ skip, riskEntity, requestTimerange, - isEnabled, - isDeprecated, - isAuthorized, - isDeprecatedLoading, + isStatusLoading, + riskEngineHasBeenEnabled, ]); const refetchAll = useCallback(() => { if (defaultIndex) { - refetchFeatureStatus(defaultIndex); + refetchEngineStatus(); refetch(); } - }, [defaultIndex, refetch, refetchFeatureStatus]); + }, [defaultIndex, refetch, refetchEngineStatus]); useEffect(() => { if (error) { diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.test.tsx index fa22892f21db8..5773556f110b5 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.test.tsx @@ -48,7 +48,6 @@ describe('ScheduleRiskEngineCallout', () => { it('should show the remaining time for the next risk engine run', async () => { mockUseRiskEngineStatus.mockReturnValue({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.ENABLED, risk_engine_task_status: { status: 'idle', @@ -70,7 +69,6 @@ describe('ScheduleRiskEngineCallout', () => { it('should show "now running" status when the risk engine status is "running"', () => { mockUseRiskEngineStatus.mockReturnValue({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.ENABLED, risk_engine_task_status: { status: 'running', @@ -89,7 +87,6 @@ describe('ScheduleRiskEngineCallout', () => { it('should show "now running" status when the next schedule run is in the past', () => { mockUseRiskEngineStatus.mockReturnValue({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.ENABLED, risk_engine_task_status: { status: 'idle', @@ -110,7 +107,6 @@ describe('ScheduleRiskEngineCallout', () => { it('should update the count down time when time has passed', () => { mockUseRiskEngineStatus.mockReturnValueOnce({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.ENABLED, risk_engine_task_status: { status: 'idle', @@ -127,7 +123,6 @@ describe('ScheduleRiskEngineCallout', () => { // simulate useQuery re-render after fetching data mockUseRiskEngineStatus.mockReturnValueOnce({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.ENABLED, risk_engine_task_status: { status: 'idle', @@ -143,7 +138,6 @@ describe('ScheduleRiskEngineCallout', () => { it('should call the run risk engine api when button is clicked', () => { mockUseRiskEngineStatus.mockReturnValue({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.ENABLED, risk_engine_task_status: { status: 'idle', @@ -163,9 +157,7 @@ describe('ScheduleRiskEngineCallout', () => { it('should not show the callout if the risk engine is not installed', () => { mockUseRiskEngineStatus.mockReturnValue({ - data: { - isNewRiskScoreModuleInstalled: false, - }, + data: {}, }); const { queryByTestId } = render(, { @@ -178,7 +170,6 @@ describe('ScheduleRiskEngineCallout', () => { it('should not show the callout if the risk engine is disabled', () => { mockUseRiskEngineStatus.mockReturnValue({ data: { - isNewRiskScoreModuleInstalled: true, risk_engine_status: RiskEngineStatusEnum.DISABLED, }, }); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.tsx index 432e03c231a4d..942610c268dea 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/asset_criticality_file_uploader/components/schedule_risk_engine_callout.tsx @@ -77,10 +77,7 @@ export const ScheduleRiskEngineCallout: React.FC = () => { scheduleRiskEngineMutation(); }, [scheduleRiskEngineMutation]); - if ( - !riskEngineStatus?.isNewRiskScoreModuleInstalled || - riskEngineStatus?.risk_engine_status !== RiskEngineStatusEnum.ENABLED - ) { + if (riskEngineStatus?.risk_engine_status !== RiskEngineStatusEnum.ENABLED) { return null; } diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx index 93fce26b3c475..a6d3c57b4999b 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx @@ -9,20 +9,18 @@ import React from 'react'; import type { RiskScoreEntity } from '../../../../common/search_strategy'; import { useCheckSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_check_signal_index'; import type { inputsModel } from '../../../common/store'; -import { RiskScoreHeaderTitle } from '../risk_score_onboarding/risk_score_header_title'; import { HeaderSection } from '../../../common/components/header_section'; -import { EntityAnalyticsLearnMoreLink } from '../risk_score_onboarding/entity_analytics_doc_link'; -import { RiskScoreEnableButton } from '../risk_score_onboarding/risk_score_enable_button'; import * as i18n from './translations'; +import { EntityAnalyticsLearnMoreLink } from '../entity_analytics_learn_more_link'; +import { RiskScoreHeaderTitle } from '../risk_score_header_title'; +import { RiskScoreEnableButton } from '../risk_score_enable_button'; const EnableRiskScoreComponent = ({ - isDeprecated, isDisabled, entityType, refetch, timerange, }: { - isDeprecated: boolean; isDisabled: boolean; entityType: RiskScoreEntity; refetch: inputsModel.Refetch; @@ -32,28 +30,18 @@ const EnableRiskScoreComponent = ({ }; }) => { const { signalIndexExists } = useCheckSignalIndex(); - if (!isDeprecated && !isDisabled) { + if (!isDisabled) { return null; } - const text = isDeprecated - ? { - cta: i18n.UPGRADE_RISK_SCORE(entityType), - body: i18n.UPGRADE_RISK_SCORE_DESCRIPTION, - } - : { - cta: i18n.ENABLE_RISK_SCORE(entityType), - body: i18n.ENABLE_RISK_SCORE_DESCRIPTION(entityType), - }; - return ( } titleSize="s" /> {text.cta}} + title={

{i18n.ENABLE_RISK_SCORE(entityType)}

} body={ <> - {text.body} + {i18n.ENABLE_RISK_SCORE_DESCRIPTION(entityType)} {` `} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts index c109c403a091e..6ce452cd44621 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/translations.ts @@ -15,22 +15,6 @@ export const ENABLE_RISK_SCORE_POPOVER = i18n.translate( } ); -export const UPGRADE_RISK_SCORE = (riskEntity: RiskScoreEntity) => - i18n.translate('xpack.securitySolution.enableRiskScore.upgradeRiskScore', { - defaultMessage: 'Upgrade {riskEntity} Risk Score', - values: { - riskEntity: getRiskEntityTranslation(riskEntity), - }, - }); - -export const UPGRADE_RISK_SCORE_DESCRIPTION = i18n.translate( - 'xpack.securitySolution.riskDeprecated.entity.upgradeRiskScoreDescription', - { - defaultMessage: - 'Current data is no longer supported. Please migrate your data and upgrade the module. The data might need an hour to be generated after enabling the module.', - } -); - export const ENABLE_RISK_SCORE = (riskEntity: RiskScoreEntity) => i18n.translate('xpack.securitySolution.enableRiskScore.enableRiskScore', { defaultMessage: 'Enable {riskEntity} Risk Score', diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/entity_analytics_doc_link.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx similarity index 95% rename from x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/entity_analytics_doc_link.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx index b0d421c743411..b0e590db8f0e6 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/entity_analytics_doc_link.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx @@ -8,7 +8,7 @@ import { EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; -import { useKibana } from '../../../common/lib/kibana'; +import { useKibana } from '../../common/lib/kibana'; const EntityAnalyticsLearnMoreLinkComponent = ({ title }: { title?: string | React.ReactNode }) => { const { docLinks } = useKibana().services; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx index 08ce79cc74c17..e4c01e0d06ff5 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx @@ -21,8 +21,6 @@ import { useGlobalTime } from '../../../common/containers/use_global_time'; import { InspectButtonContainer } from '../../../common/components/inspect'; import { useQueryToggle } from '../../../common/containers/query_toggle'; import { StyledBasicTable } from '../styled_basic_table'; -import { RiskScoreHeaderTitle } from '../risk_score_onboarding/risk_score_header_title'; -import { RiskScoresNoDataDetected } from '../risk_score_onboarding/risk_score_no_data_detected'; import { useRefetchQueries } from '../../../common/hooks/use_refetch_queries'; import { Loader } from '../../../common/components/loader'; import { Panel } from '../../../common/components/panel'; @@ -39,6 +37,8 @@ import { UserPanelKey } from '../../../flyout/entity_details/user_right'; import { RiskEnginePrivilegesCallOut } from '../risk_engine_privileges_callout'; import { useMissingRiskEnginePrivileges } from '../../hooks/use_missing_risk_engine_privileges'; import { EntityEventTypes } from '../../../common/lib/telemetry'; +import { RiskScoresNoDataDetected } from '../risk_score_no_data_detected'; +import { RiskScoreHeaderTitle } from '../risk_score_header_title'; export const ENTITY_RISK_SCORE_TABLE_ID = 'entity-risk-score-table'; @@ -131,9 +131,8 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc loading: isTableLoading, inspect, refetch, - isDeprecated, isAuthorized, - isModuleEnabled, + isEngineEnabled, } = useRiskScore({ filterQuery, skip: !toggleStatus, @@ -167,10 +166,7 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc return null; } - const status = { - isDisabled: !isModuleEnabled && !isTableLoading, - isDeprecated: isDeprecated && !isTableLoading, - }; + const isDisabled = !isEngineEnabled && !isTableLoading; if (!privileges.isLoading && !privileges.hasAllRequiredPrivileges) { return ( @@ -180,10 +176,10 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc ); } - if (status.isDisabled || status.isDeprecated) { + if (isDisabled) { return ( ; + if (isEngineEnabled && selectedSeverity.length === 0 && data && data.length === 0) { + return ; } return ( diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx index b9cfcd18b6cfd..4c26749c86319 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx @@ -5,37 +5,27 @@ * 2.0. */ -import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; import { useUpsellingComponent } from '../../../common/hooks/use_upselling'; -import { RISKY_HOSTS_DASHBOARD_TITLE, RISKY_USERS_DASHBOARD_TITLE } from '../risk_score/constants'; import { EnableRiskScore } from '../enable_risk_score'; import { useDeepEqualSelector } from '../../../common/hooks/use_selector'; import type { State } from '../../../common/store'; import { hostsModel, hostsSelectors } from '../../../explore/hosts/store'; import { usersSelectors } from '../../../explore/users/store'; -import { RiskInformationButtonEmpty } from '../risk_information'; -import * as i18n from './translations'; - import { useQueryInspector } from '../../../common/components/page/manage_query'; -import { RiskScoreOverTime } from '../risk_score_over_time'; -import { TopRiskScoreContributors } from '../top_risk_score_contributors'; import { TopRiskScoreContributorsAlerts } from '../top_risk_score_contributors_alerts'; import { useQueryToggle } from '../../../common/containers/query_toggle'; -import type { HostRiskScore, UserRiskScore } from '../../../../common/search_strategy'; import { buildEntityNameFilter, RiskScoreEntity } from '../../../../common/search_strategy'; import type { UsersComponentsQueryProps } from '../../../explore/users/pages/navigation/types'; import type { HostsComponentsQueryProps } from '../../../explore/hosts/pages/navigation/types'; -import { useDashboardHref } from '../../../common/hooks/use_dashboard_href'; -import { RiskScoresNoDataDetected } from '../risk_score_onboarding/risk_score_no_data_detected'; -import { useRiskEngineStatus } from '../../api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from '../risk_score_update_panel'; import { HostRiskScoreQueryId, UserRiskScoreQueryId } from '../../common/utils'; import { useRiskScore } from '../../api/hooks/use_risk_score'; import { useMissingRiskEnginePrivileges } from '../../hooks/use_missing_risk_engine_privileges'; import { RiskEnginePrivilegesCallOut } from '../risk_engine_privileges_callout'; +import { RiskScoresNoDataDetected } from '../risk_score_no_data_detected'; const StyledEuiFlexGroup = styled(EuiFlexGroup)` margin-top: ${({ theme }) => theme.eui.euiSizeL}; @@ -43,9 +33,6 @@ const StyledEuiFlexGroup = styled(EuiFlexGroup)` type ComponentsQueryProps = HostsComponentsQueryProps | UsersComponentsQueryProps; -const getDashboardTitle = (riskEntity: RiskScoreEntity) => - riskEntity === RiskScoreEntity.host ? RISKY_HOSTS_DASHBOARD_TITLE : RISKY_USERS_DASHBOARD_TITLE; - const RiskDetailsTabBodyComponent: React.FC< Pick & { entityName: string; @@ -66,8 +53,6 @@ const RiskDetailsTabBodyComponent: React.FC< : usersSelectors.userRiskScoreSeverityFilterSelector()(state) ); - const buttonHref = useDashboardHref({ title: getDashboardTitle(riskEntity) }); - const timerange = useMemo( () => ({ from: startDate, @@ -76,8 +61,6 @@ const RiskDetailsTabBodyComponent: React.FC< [startDate, endDate] ); - const { toggleStatus: overTimeToggleStatus, setToggleStatus: setOverTimeToggleStatus } = - useQueryToggle(`${queryId} overTime`); const { toggleStatus: contributorsToggleStatus, setToggleStatus: setContributorsToggleStatus } = useQueryToggle(`${queryId} contributors`); @@ -86,26 +69,14 @@ const RiskDetailsTabBodyComponent: React.FC< [entityName, riskEntity] ); - const { data, loading, refetch, inspect, isDeprecated, isModuleEnabled } = useRiskScore({ + const { data, loading, refetch, inspect, isEngineEnabled } = useRiskScore({ filterQuery, onlyLatest: false, riskEntity, - skip: !overTimeToggleStatus && !contributorsToggleStatus, + skip: !contributorsToggleStatus, timerange, }); - const { data: riskScoreEngineStatus } = useRiskEngineStatus(); - - const rules = useMemo(() => { - const lastRiskItem = data && data.length > 0 ? data[data.length - 1] : null; - if (lastRiskItem) { - return riskEntity === RiskScoreEntity.host - ? (lastRiskItem as HostRiskScore).host.risk.rule_risks - : (lastRiskItem as UserRiskScore).user.risk.rule_risks; - } - return []; - }, [data, riskEntity]); - useQueryInspector({ queryId, loading, @@ -122,13 +93,6 @@ const RiskDetailsTabBodyComponent: React.FC< [setContributorsToggleStatus] ); - const toggleOverTimeQuery = useCallback( - (status: boolean) => { - setOverTimeToggleStatus(status); - }, - [setOverTimeToggleStatus] - ); - const privileges = useMissingRiskEnginePrivileges(); const RiskScoreUpsell = useUpsellingComponent('entity_analytics_panel'); @@ -145,11 +109,10 @@ const RiskDetailsTabBodyComponent: React.FC< } const status = { - isDisabled: !isModuleEnabled && !loading, - isDeprecated: isDeprecated && !loading, + isDisabled: !isEngineEnabled && !loading, }; - if (status.isDisabled || status.isDeprecated) { + if (status.isDisabled) { return ( ; + if (isEngineEnabled && severitySelectionRedux.length === 0 && data && data.length === 0) { + return ; } return ( <> - {riskScoreEngineStatus?.isUpdateAvailable && } - {riskScoreEngineStatus?.isNewRiskScoreModuleInstalled ? ( - - - {data?.[0] && ( - - )} - - - ) : ( - <> - - - - - - - - - - - - - {i18n.VIEW_DASHBOARD_BUTTON} - - - - - - - - - )} + + + {data?.[0] && ( + + )} + + ); }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx index 0b08c8976cf67..490e4b5d09e9b 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_information/index.tsx @@ -28,6 +28,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/react'; +import { BETA } from '../../../common/translations'; import * as i18n from './translations'; import { useOnOpenCloseHandler } from '../../../helper_hooks'; import { RiskScoreLevel } from '../severity/common'; @@ -37,9 +38,8 @@ import { CriticalityLevels, CriticalityModifiers, } from '../../../../common/entity_analytics/asset_criticality'; -import { EntityAnalyticsLearnMoreLink } from '../risk_score_onboarding/entity_analytics_doc_link'; -import { BETA } from '../risk_score_onboarding/translations'; import { AssetCriticalityBadge } from '../asset_criticality'; +import { EntityAnalyticsLearnMoreLink } from '../entity_analytics_learn_more_link'; const SpacedOrderedList = styled.ol` li { diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/constants.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/constants.ts index d6147328d6be2..413f8dd22019e 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/constants.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score/constants.ts @@ -5,9 +5,6 @@ * 2.0. */ -export const RISKY_HOSTS_DASHBOARD_TITLE = 'Current Risk Score for Hosts'; -export const RISKY_USERS_DASHBOARD_TITLE = 'Current Risk Score for Users'; - export const CELL_ACTIONS_TELEMETRY = { component: 'RiskScoreTable', }; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx similarity index 90% rename from x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.test.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx index 92e022b55aeeb..f2d42d335611d 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx @@ -6,8 +6,8 @@ */ import { render, screen } from '@testing-library/react'; import React from 'react'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { TestProviders } from '../../../common/mock'; +import { RiskScoreEntity } from '../../../common/search_strategy'; +import { TestProviders } from '../../common/mock'; import { RiskScoreEnableButton } from './risk_score_enable_button'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx new file mode 100644 index 0000000000000..20a6b9fb8009d --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import type { RiskScoreEntity } from '../../../common/search_strategy'; +import type { inputsModel } from '../../common/store'; +import { SecuritySolutionLinkButton } from '../../common/components/links'; +import { SecurityPageName } from '../../../common/constants'; + +const RiskScoreEnableButtonComponent = ({ + refetch, + riskScoreEntity, + disabled = false, + timerange, +}: { + refetch: inputsModel.Refetch; + riskScoreEntity: RiskScoreEntity; + disabled?: boolean; + timerange: { + from: string; + to: string; + }; +}) => { + return ( + <> + + + + + ); +}; + +export const RiskScoreEnableButton = React.memo(RiskScoreEnableButtonComponent); +RiskScoreEnableButton.displayName = 'RiskScoreEnableButton'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx index 63ff39ebca7dc..6798dbe5b0501 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState } from 'react'; +import React from 'react'; import { EuiFlexGroup, EuiFlexItem, @@ -16,14 +16,6 @@ import { EuiSwitch, EuiTitle, EuiLoadingSpinner, - EuiBadge, - EuiButtonEmpty, - EuiButton, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, EuiText, EuiCallOut, EuiAccordion, @@ -72,74 +64,6 @@ const RiskScoreErrorPanel = ({ errors }: { errors: string[] }) => ( ); -interface RiskScoreUpdateModalParams { - isLoading: boolean; - isVisible: boolean; - closeModal: () => void; - onConfirm: () => void; -} - -const RiskScoreUpdateModal = ({ - closeModal, - isLoading, - onConfirm, - isVisible, -}: RiskScoreUpdateModalParams) => { - if (!isVisible) return null; - - return ( - - {isLoading ? ( - - - - {i18n.UPDATING_RISK_ENGINE} - - - ) : ( - <> - - {i18n.UPDATE_RISK_ENGINE_MODAL_TITLE} - - - - -

- {i18n.UPDATE_RISK_ENGINE_MODAL_EXISTING_USER_HOST_1} - {i18n.UPDATE_RISK_ENGINE_MODAL_EXISTING_USER_HOST_2} -

- -

- {i18n.UPDATE_RISK_ENGINE_MODAL_EXISTING_DATA_1} - {i18n.UPDATE_RISK_ENGINE_MODAL_EXISTING_DATA_2} -

-
- -
- - - - {i18n.UPDATE_RISK_ENGINE_MODAL_BUTTON_NO} - - - {i18n.UPDATE_RISK_ENGINE_MODAL_BUTTON_YES} - - - - )} -
- ); -}; - const RiskEngineHealth: React.FC<{ currentRiskEngineStatus?: RiskEngineStatus | null }> = ({ currentRiskEngineStatus, }) => { @@ -194,15 +118,11 @@ export const RiskScoreEnableSection: React.FC<{ privileges: RiskEngineMissingPrivilegesResponse; }> = ({ privileges }) => { const { addSuccess } = useAppToasts(); - const [isModalVisible, setIsModalVisible] = useState(false); const { data: riskEngineStatus, isFetching: isStatusLoading } = useRiskEngineStatus(); const initRiskEngineMutation = useInitRiskEngineMutation({ onSuccess: () => { addSuccess(i18n.RISK_SCORE_MODULE_TURNED_ON, toastOptions); }, - onSettled: () => { - setIsModalVisible(false); - }, }); const enableRiskEngineMutation = useEnableRiskEngineMutation({ @@ -218,9 +138,6 @@ export const RiskScoreEnableSection: React.FC<{ const currentRiskEngineStatus = riskEngineStatus?.risk_engine_status; - const closeModal = () => setIsModalVisible(false); - const showModal = () => setIsModalVisible(true); - const [isFlyoutVisible, handleOnOpen, handleOnClose] = useOnOpenCloseHandler(); const isLoading = @@ -230,8 +147,6 @@ export const RiskScoreEnableSection: React.FC<{ privileges.isLoading || isStatusLoading; - const isUpdateAvailable = riskEngineStatus?.isUpdateAvailable; - const onSwitchClick = () => { if (!currentRiskEngineStatus || isLoading) { return; @@ -267,47 +182,21 @@ export const RiskScoreEnableSection: React.FC<{ - initRiskEngineMutation.mutate()} - isLoading={initRiskEngineMutation.isLoading} - closeModal={closeModal} - /> {i18n.ENTITY_RISK_SCORING} - {isUpdateAvailable && {i18n.UPDATE_AVAILABLE}} - {isUpdateAvailable && ( - - - {initRiskEngineMutation.isLoading && !isModalVisible && ( - - )} - - - {i18n.START_UPDATE} - - - )} - {!isUpdateAvailable && ( - - )} + diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_header_title.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx similarity index 93% rename from x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_header_title.tsx rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx index 1ec4edd65fe3b..2693c859f9ed8 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_header_title.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx @@ -7,8 +7,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; - -import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../common/search_strategy'; const RiskScoreHeaderTitleComponent = ({ riskScoreEntity, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_no_data_detected.tsx similarity index 50% rename from x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/translations.ts rename to x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_no_data_detected.tsx index f8bcbf29725f9..1e57f1bb7bf23 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_no_data_detected.tsx @@ -4,54 +4,58 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { i18n } from '@kbn/i18n'; -import type { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; -import { getRiskEntityTranslation } from '../risk_score/translations'; -export const BETA = i18n.translate('xpack.securitySolution.riskScore.technicalPreviewLabel', { - defaultMessage: 'Beta', -}); +import { EuiEmptyPrompt, EuiPanel } from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { RiskScoreEntity } from '../../../common/search_strategy'; +import { RiskScoreHeaderTitle } from './risk_score_header_title'; +import { HeaderSection } from '../../common/components/header_section'; -export const HOST_WARNING_TITLE = i18n.translate( +const HOST_WARNING_TITLE = i18n.translate( 'xpack.securitySolution.riskScore.hostsDashboardWarningPanelTitle', { defaultMessage: 'No host risk score data available to display', } ); -export const USER_WARNING_TITLE = i18n.translate( +const USER_WARNING_TITLE = i18n.translate( 'xpack.securitySolution.riskScore.usersDashboardWarningPanelTitle', { defaultMessage: 'No user risk score data available to display', } ); -export const HOST_WARNING_BODY = i18n.translate( +const HOST_WARNING_BODY = i18n.translate( 'xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody', { defaultMessage: `We haven’t found any host risk score data. Check if you have any global filters in the global KQL search bar. If you have just enabled the host risk module, the risk engine might need an hour to generate host risk score data and display in this panel.`, } ); -export const USER_WARNING_BODY = i18n.translate( +const USER_WARNING_BODY = i18n.translate( 'xpack.securitySolution.riskScore.usersDashboardWarningPanelBody', { defaultMessage: `We haven’t found any user risk score data. Check if you have any global filters in the global KQL search bar. If you have just enabled the user risk module, the risk engine might need an hour to generate user risk score data and display in this panel.`, } ); -export const RESTART_TOOLTIP = i18n.translate( - 'xpack.securitySolution.riskScore.usersDashboardRestartTooltip', - { - defaultMessage: - 'The risk score calculation might take a while to run. However, by pressing restart, you can force it to run immediately.', - } -); +const RiskScoresNoDataDetectedComponent = ({ entityType }: { entityType: RiskScoreEntity }) => { + const translations = useMemo( + () => ({ + title: entityType === RiskScoreEntity.user ? USER_WARNING_TITLE : HOST_WARNING_TITLE, + body: entityType === RiskScoreEntity.user ? USER_WARNING_BODY : HOST_WARNING_BODY, + }), + [entityType] + ); + + return ( + + } titleSize="s" /> + {translations.title}} body={translations.body} /> + + ); +}; -export const RISK_DATA_TITLE = (riskEntity: RiskScoreEntity) => - i18n.translate('xpack.securitySolution.alertDetails.overview.hostRiskDataTitle', { - defaultMessage: '{riskEntity} Risk Data', - values: { - riskEntity: getRiskEntityTranslation(riskEntity), - }, - }); +export const RiskScoresNoDataDetected = React.memo(RiskScoresNoDataDetectedComponent); +RiskScoresNoDataDetected.displayName = 'RiskScoresNoDataDetected'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx deleted file mode 100644 index 6878f9aab0512..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_enable_button.tsx +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton } from '@elastic/eui'; -import React, { useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import type { RiskScoreEntity } from '../../../../common/search_strategy'; -import { useSpaceId } from '../../../common/hooks/use_space_id'; -import { useKibana } from '../../../common/lib/kibana'; -import type { inputsModel } from '../../../common/store'; -import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch'; -import { useRiskScoreToastContent } from './use_risk_score_toast_content'; -import { installRiskScoreModule } from './utils'; -import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; -import { SecuritySolutionLinkButton } from '../../../common/components/links'; -import { SecurityPageName } from '../../../../common/constants'; - -const RiskScoreEnableButtonComponent = ({ - refetch, - riskScoreEntity, - disabled = false, - timerange, -}: { - refetch: inputsModel.Refetch; - riskScoreEntity: RiskScoreEntity; - disabled?: boolean; - timerange: { - from: string; - to: string; - }; -}) => { - const spaceId = useSpaceId(); - const { http, dashboard, ...startServices } = useKibana().services; - const { renderDocLink, renderDashboardLink } = useRiskScoreToastContent(); - const { fetch, isLoading } = useFetch(REQUEST_NAMES.ENABLE_RISK_SCORE, installRiskScoreModule); - const isRiskEngineEnabled = useIsExperimentalFeatureEnabled('riskScoringRoutesEnabled'); - - const onBoardingRiskScore = useCallback(() => { - fetch({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - riskScoreEntity, - spaceId, - timerange, - startServices, - }); - }, [ - dashboard, - fetch, - http, - refetch, - renderDashboardLink, - renderDocLink, - riskScoreEntity, - spaceId, - timerange, - startServices, - ]); - - return ( - <> - {isRiskEngineEnabled ? ( - - - - ) : ( - - - - )} - - ); -}; - -export const RiskScoreEnableButton = React.memo(RiskScoreEnableButtonComponent); -RiskScoreEnableButton.displayName = 'RiskScoreEnableButton'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx deleted file mode 100644 index c7bd233c7030a..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected.tsx +++ /dev/null @@ -1,58 +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 { EuiEmptyPrompt, EuiPanel, EuiToolTip } from '@elastic/eui'; -import React, { useMemo } from 'react'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; - -import { HeaderSection } from '../../../common/components/header_section'; -import * as i18n from './translations'; -import { RiskScoreHeaderTitle } from './risk_score_header_title'; -import { RiskScoreRestartButton } from './risk_score_restart_button'; -import type { inputsModel } from '../../../common/store'; -import { useIsNewRiskScoreModuleInstalled } from '../../api/hooks/use_risk_engine_status'; - -const RiskScoresNoDataDetectedComponent = ({ - entityType, - refetch, -}: { - entityType: RiskScoreEntity; - refetch: inputsModel.Refetch; -}) => { - const isNewRiskScoreModuleInstalled = useIsNewRiskScoreModuleInstalled(); - - const translations = useMemo( - () => ({ - title: - entityType === RiskScoreEntity.user ? i18n.USER_WARNING_TITLE : i18n.HOST_WARNING_TITLE, - body: entityType === RiskScoreEntity.user ? i18n.USER_WARNING_BODY : i18n.HOST_WARNING_BODY, - }), - [entityType] - ); - - return ( - - } titleSize="s" /> - {translations.title}} - body={translations.body} - actions={ - <> - {!isNewRiskScoreModuleInstalled && ( - - - - )} - - } - /> - - ); -}; - -export const RiskScoresNoDataDetected = React.memo(RiskScoresNoDataDetectedComponent); -RiskScoresNoDataDetected.displayName = 'RiskScoresNoDataDetected'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx deleted file mode 100644 index b320aef91f6e9..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.test.tsx +++ /dev/null @@ -1,99 +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 { render, screen, waitFor } from '@testing-library/react'; -import userEvent, { type UserEvent } from '@testing-library/user-event'; -import React from 'react'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { TestProviders } from '../../../common/mock'; -import { RiskScoreRestartButton } from './risk_score_restart_button'; - -import { restartRiskScoreTransforms } from './utils'; - -jest.mock('./utils'); - -const mockRestartRiskScoreTransforms = restartRiskScoreTransforms as jest.Mock; - -const mockUseState = React.useState; -jest.mock('../../../common/hooks/use_fetch', () => ({ - ...jest.requireActual('../../../common/hooks/use_fetch'), - useFetch: jest.fn().mockImplementation(() => { - const [isLoading, setIsLoading] = mockUseState(false); - return { - fetch: jest.fn().mockImplementation((param) => { - setIsLoading(true); - mockRestartRiskScoreTransforms(param); - }), - isLoading, - }; - }), -})); - -describe('RiskScoreRestartButton', () => { - let user: UserEvent; - const mockRefetch = jest.fn(); - beforeEach(() => { - jest.useFakeTimers(); - jest.clearAllMocks(); - // Workaround for timeout via https://github.com/testing-library/user-event/issues/833#issuecomment-1171452841 - user = userEvent.setup({ - advanceTimers: jest.advanceTimersByTime, - pointerEventsCheck: 0, - }); - }); - afterEach(() => { - jest.clearAllTimers(); - jest.clearAllMocks(); - jest.useRealTimers(); - }); - describe.each([[RiskScoreEntity.host], [RiskScoreEntity.user]])('%s', (riskScoreEntity) => { - it('Renders expected children', () => { - render( - - - - ); - - expect(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)).toHaveTextContent( - 'Restart' - ); - }); - - it('calls restartRiskScoreTransforms with correct entity', async () => { - render( - - - - ); - - await user.click(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)); - - await waitFor(() => { - expect(mockRestartRiskScoreTransforms).toHaveBeenCalled(); - expect(mockRestartRiskScoreTransforms.mock.calls[0][0].riskScoreEntity).toEqual( - riskScoreEntity - ); - }); - }); - - it('Update button state while installing', async () => { - render( - - - - ); - - await user.click(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)); - - await waitFor(() => { - expect(screen.getByTestId(`restart_${riskScoreEntity}_risk_score`)).toHaveProperty( - 'disabled', - true - ); - }); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx deleted file mode 100644 index 87ef0df078c09..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/risk_score_restart_button.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton } from '@elastic/eui'; -import React, { useCallback } from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import type { RiskScoreEntity } from '../../../../common/search_strategy'; -import { useSpaceId } from '../../../common/hooks/use_space_id'; -import { useKibana } from '../../../common/lib/kibana'; -import type { inputsModel } from '../../../common/store'; -import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch'; -import { useRiskScoreToastContent } from './use_risk_score_toast_content'; -import { restartRiskScoreTransforms } from './utils'; - -const RiskScoreRestartButtonComponent = ({ - refetch, - riskScoreEntity, -}: { - refetch: inputsModel.Refetch; - riskScoreEntity: RiskScoreEntity; -}) => { - const { fetch, isLoading } = useFetch( - REQUEST_NAMES.REFRESH_RISK_SCORE, - restartRiskScoreTransforms - ); - const spaceId = useSpaceId(); - - const { renderDocLink } = useRiskScoreToastContent(); - const { http, ...startServices } = useKibana().services; - - const onClick = useCallback(async () => { - fetch({ - http, - refetch, - renderDocLink, - riskScoreEntity, - spaceId, - startServices, - }); - }, [fetch, http, refetch, renderDocLink, riskScoreEntity, spaceId, startServices]); - - return ( - - - - ); -}; - -export const RiskScoreRestartButton = React.memo(RiskScoreRestartButtonComponent); -RiskScoreRestartButton.displayName = 'RiskScoreRestartButton'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx deleted file mode 100644 index 30fdc0f9204f2..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/use_risk_score_toast_content.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton, EuiSpacer } from '@elastic/eui'; -import React, { useCallback, useMemo } from 'react'; -import styled from 'styled-components'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { EntityAnalyticsLearnMoreLink } from './entity_analytics_doc_link'; - -const StyledButton = styled(EuiButton)` - float: right; -`; - -export const useRiskScoreToastContent = () => { - const renderDocLink = useCallback( - (message: string) => ( - <> - {message} - - ), - [] - ); - const renderDashboardLink = useCallback( - (message: string, targetUrl: string) => ( - <> - {message} - - - - - - ), - [] - ); - - const renderLinks = useMemo( - () => ({ - renderDocLink, - renderDashboardLink, - }), - [renderDashboardLink, renderDocLink] - ); - - return renderLinks; -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts deleted file mode 100644 index f23a645643b2a..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.test.ts +++ /dev/null @@ -1,178 +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 { coreMock } from '@kbn/core/public/mocks'; -import type { HttpSetup } from '@kbn/core/public'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { - getIngestPipelineName, - getLegacyIngestPipelineName, - getRiskScoreLatestTransformId, - getRiskScorePivotTransformId, -} from '../../../../common/utils/risk_score_modules'; -import { - bulkDeletePrebuiltSavedObjects, - bulkCreatePrebuiltSavedObjects, -} from '../../deprecated_risk_engine/api'; - -import * as api from '../../deprecated_risk_engine/api'; -import { - installRiskScoreModule, - restartRiskScoreTransforms, - uninstallRiskScoreModule, -} from './utils'; - -jest.mock('../../deprecated_risk_engine/api'); - -const startServices = coreMock.createStart(); -const mockHttp = { - post: jest.fn(), -} as unknown as HttpSetup; -const mockSpaceId = 'customSpace'; -const mockTimerange = { - from: 'startDate', - to: 'endDate', -}; -const mockRefetch = jest.fn(); -describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( - `installRiskScoreModule - %s`, - (riskScoreEntity) => { - beforeAll(async () => { - await installRiskScoreModule({ - http: mockHttp, - refetch: mockRefetch, - spaceId: mockSpaceId, - timerange: mockTimerange, - riskScoreEntity, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - it(`installRiskScore`, () => { - expect((api.installRiskScore as jest.Mock).mock.calls[0][0].options.riskScoreEntity).toEqual( - riskScoreEntity - ); - }); - - it(`Create ${riskScoreEntity} dashboards`, () => { - expect( - (bulkCreatePrebuiltSavedObjects as jest.Mock).mock.calls[0][0].options.templateName - ).toEqual(`${riskScoreEntity}RiskScoreDashboards`); - }); - - it('Refresh module', () => { - expect(mockRefetch).toBeCalled(); - }); - } -); - -describe.each([[RiskScoreEntity.host], [RiskScoreEntity.user]])( - 'uninstallRiskScoreModule - %s', - (riskScoreEntity) => { - beforeAll(async () => { - await uninstallRiskScoreModule({ - http: mockHttp, - spaceId: mockSpaceId, - riskScoreEntity, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - it(`Delete ${riskScoreEntity} dashboards`, () => { - expect( - (bulkDeletePrebuiltSavedObjects as jest.Mock).mock.calls[0][0].options.templateName - ).toEqual(`${riskScoreEntity}RiskScoreDashboards`); - }); - - it('Delete Transforms', () => { - expect((api.deleteTransforms as jest.Mock).mock.calls[0][0].transformIds).toEqual([ - getRiskScorePivotTransformId(riskScoreEntity, mockSpaceId), - getRiskScoreLatestTransformId(riskScoreEntity, mockSpaceId), - ]); - }); - - it('Delete legacy ingest pipelines', () => { - expect((api.deleteIngestPipelines as jest.Mock).mock.calls[0][0].names).toEqual( - [ - getLegacyIngestPipelineName(riskScoreEntity), - getIngestPipelineName(riskScoreEntity, mockSpaceId), - ].join(',') - ); - }); - - it('Delete legacy stored scripts', () => { - if (riskScoreEntity === RiskScoreEntity.user) { - expect((api.deleteStoredScripts as jest.Mock).mock.calls[0][0].ids).toMatchInlineSnapshot(` - Array [ - "ml_userriskscore_levels_script", - "ml_userriskscore_map_script", - "ml_userriskscore_reduce_script", - "ml_userriskscore_levels_script_customSpace", - "ml_userriskscore_map_script_customSpace", - "ml_userriskscore_reduce_script_customSpace", - ] - `); - } else { - expect((api.deleteStoredScripts as jest.Mock).mock.calls[0][0].ids).toMatchInlineSnapshot(` - Array [ - "ml_hostriskscore_levels_script", - "ml_hostriskscore_init_script", - "ml_hostriskscore_map_script", - "ml_hostriskscore_reduce_script", - "ml_hostriskscore_levels_script_customSpace", - "ml_hostriskscore_init_script_customSpace", - "ml_hostriskscore_map_script_customSpace", - "ml_hostriskscore_reduce_script_customSpace", - ] - `); - } - }); - } -); - -describe.each([[RiskScoreEntity.host], [RiskScoreEntity.user]])( - 'Restart Transforms - %s', - (riskScoreEntity) => { - beforeAll(async () => { - await restartRiskScoreTransforms({ - http: mockHttp, - refetch: mockRefetch, - riskScoreEntity, - spaceId: mockSpaceId, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - it('Restart Transforms with correct Ids', () => { - expect((api.stopTransforms as jest.Mock).mock.calls[0][0].transformIds).toEqual([ - getRiskScorePivotTransformId(riskScoreEntity, mockSpaceId), - getRiskScoreLatestTransformId(riskScoreEntity, mockSpaceId), - ]); - - expect((api.startTransforms as jest.Mock).mock.calls[0][0].transformIds).toEqual([ - getRiskScorePivotTransformId(riskScoreEntity, mockSpaceId), - getRiskScoreLatestTransformId(riskScoreEntity, mockSpaceId), - ]); - }); - - it('Refresh module', () => { - expect(mockRefetch).toBeCalled(); - }); - } -); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts deleted file mode 100644 index d3edda716e763..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_onboarding/utils.ts +++ /dev/null @@ -1,348 +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 { HttpSetup } from '@kbn/core/public'; -import type { DashboardStart } from '@kbn/dashboard-plugin/public'; -import type { StartRenderServices } from '../../../types'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import * as utils from '../../../../common/utils/risk_score_modules'; -import type { inputsModel } from '../../../common/store'; - -import { - deleteStoredScripts, - deleteTransforms, - deleteIngestPipelines, - bulkDeletePrebuiltSavedObjects, - installRiskScore, - bulkCreatePrebuiltSavedObjects, - stopTransforms, - startTransforms, -} from '../../deprecated_risk_engine/api'; -import { - INGEST_PIPELINE_DELETION_ERROR_MESSAGE, - TRANSFORM_DELETION_ERROR_MESSAGE, - UNINSTALLATION_ERROR, -} from '../../deprecated_risk_engine/api/translations'; - -interface InstallRiskScoreModule { - dashboard?: DashboardStart; - http: HttpSetup; - refetch?: inputsModel.Refetch; - renderDashboardLink?: (message: string, dashboardUrl: string) => React.ReactNode; - renderDocLink?: (message: string) => React.ReactNode; - riskScoreEntity: RiskScoreEntity; - spaceId?: string; - timerange: { - from: string; - to: string; - }; - startServices: StartRenderServices; -} - -type UpgradeRiskScoreModule = InstallRiskScoreModule; - -const installHostRiskScoreModule = async ({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - timerange, - startServices, -}: InstallRiskScoreModule) => { - await installRiskScore({ - http, - renderDocLink, - options: { - riskScoreEntity: RiskScoreEntity.host, - }, - startServices, - }); - - // Install dashboards and relevant saved objects - await bulkCreatePrebuiltSavedObjects({ - http, - dashboard, - renderDashboardLink, - renderDocLink, - ...timerange, - options: { - templateName: `${RiskScoreEntity.host}RiskScoreDashboards`, - }, - startServices, - }); - - if (refetch) { - refetch(); - } -}; - -const installUserRiskScoreModule = async ({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - spaceId = 'default', - timerange, - startServices, -}: InstallRiskScoreModule) => { - await installRiskScore({ - http, - renderDocLink, - options: { - riskScoreEntity: RiskScoreEntity.user, - }, - startServices, - }); - - // Install dashboards and relevant saved objects - await bulkCreatePrebuiltSavedObjects({ - dashboard, - http, - options: { - templateName: `${RiskScoreEntity.user}RiskScoreDashboards`, - }, - renderDashboardLink, - renderDocLink, - startServices, - ...timerange, - }); - - if (refetch) { - refetch(); - } -}; - -export const installRiskScoreModule = async (settings: InstallRiskScoreModule) => { - if (settings.riskScoreEntity === RiskScoreEntity.user) { - await installUserRiskScoreModule(settings); - } else { - await installHostRiskScoreModule(settings); - } -}; - -export const uninstallRiskScoreModule = async ({ - http, - refetch, - renderDocLink, - riskScoreEntity, - spaceId = 'default', - startServices, -}: { - http: HttpSetup; - refetch?: inputsModel.Refetch; - renderDocLink?: (message: string) => React.ReactNode; - riskScoreEntity: RiskScoreEntity; - spaceId?: string; - deleteAll?: boolean; - startServices: StartRenderServices; -}) => { - const legacyTransformIds = [ - // transform Ids never changed since 8.3 - utils.getRiskScorePivotTransformId(riskScoreEntity, spaceId), - utils.getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - ]; - const legacyRiskScoreHostsScriptIds = [ - // 8.4 - utils.getLegacyRiskScoreLevelScriptId(RiskScoreEntity.host), - utils.getLegacyRiskScoreInitScriptId(RiskScoreEntity.host), - utils.getLegacyRiskScoreMapScriptId(RiskScoreEntity.host), - utils.getLegacyRiskScoreReduceScriptId(RiskScoreEntity.host), - // 8.3 and after 8.5 - utils.getRiskScoreLevelScriptId(RiskScoreEntity.host, spaceId), - utils.getRiskScoreInitScriptId(RiskScoreEntity.host, spaceId), - utils.getRiskScoreMapScriptId(RiskScoreEntity.host, spaceId), - utils.getRiskScoreReduceScriptId(RiskScoreEntity.host, spaceId), - ]; - const legacyRiskScoreUsersScriptIds = [ - // 8.4 - utils.getLegacyRiskScoreLevelScriptId(RiskScoreEntity.user), - utils.getLegacyRiskScoreMapScriptId(RiskScoreEntity.user), - utils.getLegacyRiskScoreReduceScriptId(RiskScoreEntity.user), - // 8.3 and after 8.5 - utils.getRiskScoreLevelScriptId(RiskScoreEntity.user, spaceId), - utils.getRiskScoreMapScriptId(RiskScoreEntity.user, spaceId), - utils.getRiskScoreReduceScriptId(RiskScoreEntity.user, spaceId), - ]; - - const legacyIngestPipelineNames = [ - // 8.4 - utils.getLegacyIngestPipelineName(riskScoreEntity), - // 8.3 and 8.5 - utils.getIngestPipelineName(riskScoreEntity, spaceId), - ]; - - await Promise.all([ - /** - * Intended not to pass notification to bulkDeletePrebuiltSavedObjects. - * As the only error it can happen is saved object not found, and - * that is what bulkDeletePrebuiltSavedObjects wants. - * (Before 8.5 once an saved object was created, it was shared across different spaces. - * If it has been upgrade in one space, "saved object not found" will happen when upgrading other spaces. - * Or it could be users manually deleted the saved object.) - */ - bulkDeletePrebuiltSavedObjects({ - http, - options: { - templateName: `${riskScoreEntity}RiskScoreDashboards`, - }, - startServices, - }), - deleteTransforms({ - http, - renderDocLink, - errorMessage: `${UNINSTALLATION_ERROR} - ${TRANSFORM_DELETION_ERROR_MESSAGE( - legacyTransformIds.length - )}`, - transformIds: legacyTransformIds, - options: { - deleteDestIndex: true, - deleteDestDataView: true, - forceDelete: false, - }, - startServices, - }), - /** - * Intended not to pass notification to deleteIngestPipelines. - * As the only error it can happen is ingest pipeline not found, and - * that is what deleteIngestPipelines wants. - * (Before 8.5 once an ingest pipeline was created, it was shared across different spaces. - * If it has been upgrade in one space, "ingest pipeline not found" will happen when upgrading other spaces. - * Or it could be users manually deleted the ingest pipeline.) - */ - deleteIngestPipelines({ - http, - errorMessage: `${UNINSTALLATION_ERROR} - ${INGEST_PIPELINE_DELETION_ERROR_MESSAGE( - legacyIngestPipelineNames.length - )}`, - names: legacyIngestPipelineNames.join(','), - startServices, - }), - /** - * Intended not to pass notification to deleteStoredScripts. - * As the only error it can happen is script not found, and - * that is what deleteStoredScripts wants. - * (In 8.4 once a script was created, it was shared across different spaces. - * If it has been upgrade in one space, "script not found" will happen when upgrading other spaces. - * Or it could be users manually deleted the script.) - */ - deleteStoredScripts({ - http, - ids: - riskScoreEntity === RiskScoreEntity.user - ? legacyRiskScoreUsersScriptIds - : legacyRiskScoreHostsScriptIds, - startServices, - }), - ]); - - if (refetch) { - refetch(); - } -}; - -export const upgradeHostRiskScoreModule = async ({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - spaceId = 'default', - timerange, - startServices, -}: UpgradeRiskScoreModule) => { - await uninstallRiskScoreModule({ - http, - renderDocLink, - riskScoreEntity: RiskScoreEntity.host, - spaceId, - startServices, - }); - await installRiskScoreModule({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - riskScoreEntity: RiskScoreEntity.host, - spaceId, - timerange, - startServices, - }); -}; - -export const upgradeUserRiskScoreModule = async ({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - spaceId = 'default', - timerange, - startServices, -}: UpgradeRiskScoreModule) => { - await uninstallRiskScoreModule({ - http, - renderDocLink, - riskScoreEntity: RiskScoreEntity.user, - spaceId, - startServices, - }); - await installRiskScoreModule({ - dashboard, - http, - refetch, - renderDashboardLink, - renderDocLink, - riskScoreEntity: RiskScoreEntity.user, - spaceId, - timerange, - startServices, - }); -}; - -export const restartRiskScoreTransforms = async ({ - http, - refetch, - renderDocLink, - riskScoreEntity, - spaceId, - startServices, -}: { - http: HttpSetup; - refetch?: inputsModel.Refetch; - renderDocLink?: (message: string) => React.ReactNode; - riskScoreEntity: RiskScoreEntity; - spaceId?: string; - startServices: StartRenderServices; -}) => { - const transformIds = [ - utils.getRiskScorePivotTransformId(riskScoreEntity, spaceId), - utils.getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - ]; - - await stopTransforms({ - http, - renderDocLink, - transformIds, - startServices, - }); - - const res = await startTransforms({ - http, - renderDocLink, - transformIds, - startServices, - }); - - if (refetch) { - refetch(); - } - - return res; -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_update_panel.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_update_panel.tsx deleted file mode 100644 index 37baf3c6c97cd..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_update_panel.tsx +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { EuiCallOut, EuiText, EuiFlexGroup, EuiSpacer } from '@elastic/eui'; -import * as i18n from '../translations'; -import { SecuritySolutionLinkButton } from '../../common/components/links'; -import { SecurityPageName } from '../../../common/constants'; - -export const RiskScoreUpdatePanel = () => { - return ( - <> - - {i18n.UPDATE_PANEL_MESSAGE} - - - - {i18n.UPDATE_PANEL_GO_TO_MANAGE} - - - - - - ); -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx deleted file mode 100644 index 710b5427a7479..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.test.tsx +++ /dev/null @@ -1,87 +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 { render } from '@testing-library/react'; -import React from 'react'; -import { TopRiskScoreContributors } from '.'; -import { TestProviders } from '../../../common/mock'; -import type { RuleRisk } from '../../../../common/search_strategy'; - -jest.mock('../../../common/containers/query_toggle'); -const testProps = { - riskScore: [], - setQuery: jest.fn(), - deleteQuery: jest.fn(), - hostName: 'test-host-name', - from: '2020-07-07T08:20:18.966Z', - to: '2020-07-08T08:20:18.966Z', - loading: false, - toggleStatus: true, - queryId: 'test-query-id', -}; - -describe('Top Risk Score Contributors', () => { - it('renders', () => { - const { queryByTestId } = render( - - - - ); - - expect(queryByTestId('topRiskScoreContributors')).toBeInTheDocument(); - }); - - it('renders sorted items', () => { - const ruleRisk: RuleRisk[] = [ - { - rule_name: 'third', - rule_risk: 10, - rule_id: '3', - }, - { - rule_name: 'first', - rule_risk: 99, - rule_id: '1', - }, - { - rule_name: 'second', - rule_risk: 55, - rule_id: '2', - }, - ]; - - const { queryAllByRole } = render( - - - - ); - - expect(queryAllByRole('row')[1]).toHaveTextContent('first'); - expect(queryAllByRole('row')[2]).toHaveTextContent('second'); - expect(queryAllByRole('row')[3]).toHaveTextContent('third'); - }); - - describe('toggleStatus', () => { - test('toggleStatus=true, render components', () => { - const { queryByTestId } = render( - - - - ); - expect(queryByTestId('topRiskScoreContributors-table')).toBeTruthy(); - }); - - test('toggleStatus=false, do not render components', () => { - const { queryByTestId } = render( - - - - ); - expect(queryByTestId('topRiskScoreContributors-table')).toBeFalsy(); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx deleted file mode 100644 index 587f3a6082469..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/index.tsx +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useMemo } from 'react'; - -import type { EuiTableFieldDataColumnType } from '@elastic/eui'; -import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiInMemoryTable } from '@elastic/eui'; - -import { HeaderSection } from '../../../common/components/header_section'; -import { InspectButton, InspectButtonContainer } from '../../../common/components/inspect'; -import * as i18n from './translations'; - -import type { RuleRisk } from '../../../../common/search_strategy'; - -import { RuleLink } from '../../../detection_engine/rule_management_ui/components/rules_table/use_columns'; - -export interface TopRiskScoreContributorsProps { - loading: boolean; - rules?: RuleRisk[]; - queryId: string; - toggleStatus: boolean; - toggleQuery?: (status: boolean) => void; -} -interface TableItem { - rank: number; - name: string; - id: string; -} - -const columns: Array> = [ - { - name: i18n.RANK_TITLE, - field: 'rank', - width: '45px', - align: 'right', - }, - { - name: i18n.RULE_NAME_TITLE, - field: 'name', - sortable: true, - truncateText: true, - render: (value: TableItem['name'], { id }: TableItem) => - id ? : value, - }, -]; - -const PAGE_SIZE = 5; - -const TopRiskScoreContributorsComponent: React.FC = ({ - rules = [], - loading, - queryId, - toggleStatus, - toggleQuery, -}) => { - const items = useMemo(() => { - return rules - ?.sort((a, b) => b.rule_risk - a.rule_risk) - .map(({ rule_name: name, rule_id: id }, i) => ({ rank: i + 1, name, id })); - }, [rules]); - - const tablePagination = useMemo( - () => ({ - showPerPageOptions: false, - pageSize: PAGE_SIZE, - totalItemCount: items.length, - }), - [items.length] - ); - - return ( - - - - - - - {toggleStatus && ( - - - - )} - - - {toggleStatus && ( - - - - - - )} - - - ); -}; - -export const TopRiskScoreContributors = React.memo(TopRiskScoreContributorsComponent); -TopRiskScoreContributors.displayName = 'TopRiskScoreContributors'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/translations.ts deleted file mode 100644 index 02017bf33d2da..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/top_risk_score_contributors/translations.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const TOP_RISK_SCORE_CONTRIBUTORS = i18n.translate( - 'xpack.securitySolution.hosts.topRiskScoreContributors.title', - { - defaultMessage: 'Top risk score contributors', - } -); - -export const RANK_TITLE = i18n.translate( - 'xpack.securitySolution.hosts.topRiskScoreContributors.rankColumnTitle', - { - defaultMessage: 'Rank', - } -); - -export const RULE_NAME_TITLE = i18n.translate( - 'xpack.securitySolution.hosts.topRiskScoreContributors.ruleNameColumnTitle', - { - defaultMessage: 'Rule name', - } -); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx index de17151fb68b7..ad312e3a8b499 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx @@ -21,12 +21,10 @@ import { UserRiskScoreTable } from './user_risk_score_table'; import { usersSelectors } from '../../explore/users/store'; import { useQueryToggle } from '../../common/containers/query_toggle'; import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../common/search_strategy'; -import { RiskScoresNoDataDetected } from './risk_score_onboarding/risk_score_no_data_detected'; -import { useRiskEngineStatus } from '../api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from './risk_score_update_panel'; import { useMissingRiskEnginePrivileges } from '../hooks/use_missing_risk_engine_privileges'; import { RiskEnginePrivilegesCallOut } from './risk_engine_privileges_callout'; import { useUpsellingComponent } from '../../common/hooks/use_upselling'; +import { RiskScoresNoDataDetected } from './risk_score_no_data_detected'; const UserRiskScoreTableManage = manageQuery(UserRiskScoreTable); @@ -39,7 +37,6 @@ export const UserRiskScoreQueryTabBody = ({ startDate: from, type, }: UsersComponentsQueryProps) => { - const { data: riskScoreEngineStatus } = useRiskEngineStatus(); const getUserRiskScoreSelector = useMemo(() => usersSelectors.userRiskScoreSelector(), []); const { activePage, limit, sort } = useDeepEqualSelector((state: State) => getUserRiskScoreSelector(state) @@ -69,23 +66,15 @@ export const UserRiskScoreQueryTabBody = ({ const privileges = useMissingRiskEnginePrivileges(); - const { - data, - inspect, - isDeprecated, - isInspected, - isModuleEnabled, - loading, - refetch, - totalCount, - } = useRiskScore({ - filterQuery, - pagination, - riskEntity: RiskScoreEntity.user, - skip: querySkip, - sort, - timerange, - }); + const { data, inspect, isInspected, isEngineEnabled, loading, refetch, totalCount } = + useRiskScore({ + filterQuery, + pagination, + riskEntity: RiskScoreEntity.user, + skip: querySkip, + sort, + timerange, + }); const { severityCount, loading: isKpiLoading } = useRiskScoreKpi({ filterQuery, @@ -93,10 +82,7 @@ export const UserRiskScoreQueryTabBody = ({ skip: querySkip, }); - const status = { - isDisabled: !isModuleEnabled && !loading, - isDeprecated: isDeprecated && !loading, - }; + const isDisabled = !isEngineEnabled && !loading; const RiskScoreUpsell = useUpsellingComponent('entity_analytics_panel'); if (RiskScoreUpsell) { @@ -111,11 +97,11 @@ export const UserRiskScoreQueryTabBody = ({ ); } - if (status.isDisabled || status.isDeprecated) { + if (isDisabled) { return ( ; + if (isEngineEnabled && userSeveritySelectionRedux.length === 0 && data && data.length === 0) { + return ; } return ( <> - {riskScoreEngineStatus?.isUpdateAvailable && } { - const mockOptions = { name: 'test', processors: [] }; - - beforeAll(async () => { - mockRequest.mockRejectedValue({ body: { message: 'test error' } }); - await createIngestPipeline({ - http: mockHttp, - options: mockOptions, - renderDocLink: mockRenderDocLink, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('create ingest pipeline', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/api/ingest_pipelines`); - }); - - it('handles error', () => { - expect(mockAddDanger.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "text": [Function], - "title": "Failed to create Ingest pipeline", - } - `); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test error'); - }); -}); - -describe('deleteIngestPipelines', () => { - beforeAll(async () => { - mockRequest.mockRejectedValue({ body: { message: 'test error' } }); - await deleteIngestPipelines({ - http: mockHttp, - names: 'test,abc', - renderDocLink: mockRenderDocLink, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('delete ingest pipeline', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/api/ingest_pipelines/test,abc`); - }); - - it('handles error', () => { - expect(mockAddDanger.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "text": [Function], - "title": "Failed to delete Ingest pipelines", - } - `); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test error'); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts deleted file mode 100644 index 9edc8ca886447..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/ingest_pipelines.ts +++ /dev/null @@ -1,67 +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 { toMountPoint } from '@kbn/react-kibana-mount'; -import { - INGEST_PIPELINE_CREATION_ERROR_MESSAGE, - INGEST_PIPELINE_DELETION_ERROR_MESSAGE, -} from './translations'; -import type { CreateIngestPipeline, DeleteIngestPipeline } from './types'; - -const INGEST_PIPELINES_API_BASE_PATH = `/api/ingest_pipelines`; - -export async function createIngestPipeline({ - errorMessage, - http, - options, - renderDocLink, - signal, - startServices: { notifications, ...startServices }, -}: CreateIngestPipeline) { - const res = await http - .post(INGEST_PIPELINES_API_BASE_PATH, { - body: JSON.stringify(options), - signal, - }) - .catch((e) => { - notifications.toasts.addDanger({ - title: errorMessage ?? INGEST_PIPELINE_CREATION_ERROR_MESSAGE, - text: toMountPoint( - renderDocLink ? renderDocLink(e?.body?.message) : e?.body?.message, - startServices - ), - }); - }); - - return res; -} - -export async function deleteIngestPipelines({ - errorMessage, - http, - names, // separate with ',' - renderDocLink, - signal, - startServices: { notifications, ...startServices }, -}: DeleteIngestPipeline) { - const count = names.split(',').length; - const res = await http - .delete(`${INGEST_PIPELINES_API_BASE_PATH}/${names}`, { - signal, - }) - .catch((e) => { - notifications.toasts.addDanger({ - title: errorMessage ?? INGEST_PIPELINE_DELETION_ERROR_MESSAGE(count), - text: toMountPoint( - renderDocLink ? renderDocLink(e?.body?.message) : e?.body?.message, - startServices - ), - }); - }); - - return res; -} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts deleted file mode 100644 index 66ebddf348bdb..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/onboarding.ts +++ /dev/null @@ -1,91 +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 { HttpSetup } from '@kbn/core/public'; - -import type { StartRenderServices } from '../../../types'; -import { INTERNAL_RISK_SCORE_URL } from '../../../../common/constants'; - -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { - HOST_RISK_SCORES_ENABLED_TITLE, - INSTALLATION_ERROR, - RISK_SCORES_ENABLED_TEXT, - USER_RISK_SCORES_ENABLED_TITLE, -} from './translations'; - -interface Options { - riskScoreEntity: RiskScoreEntity; -} - -type Response = Record; -const toastLifeTimeMs = 600000; - -export const installRiskScore = ({ - errorMessage, - http, - options, - renderDocLink, - signal, - startServices, -}: { - errorMessage?: string; - http: HttpSetup; - options: Options; - renderDocLink?: (message: string) => React.ReactNode; - signal?: AbortSignal; - startServices: Pick; -}) => { - const { notifications } = startServices; - return http - .post(INTERNAL_RISK_SCORE_URL, { - version: '1', - body: JSON.stringify(options), - signal, - }) - .then((result) => { - const resp = result.reduce( - (acc, curr) => { - const [[key, res]] = Object.entries(curr); - if (res.success) { - return res.success != null ? { ...acc, success: [...acc.success, `${key}`] } : acc; - } else { - return res.error != null - ? { ...acc, error: [...acc.error, `${key}: ${res?.error?.message}`] } - : acc; - } - }, - { success: [] as string[], error: [] as string[] } - ); - - if (resp.error.length > 0) { - notifications.toasts.addError(new Error(errorMessage ?? INSTALLATION_ERROR), { - title: errorMessage ?? INSTALLATION_ERROR, - toastMessage: renderDocLink - ? (renderDocLink(resp.error.join(', ')) as unknown as string) - : resp.error.join(', '), - toastLifeTimeMs, - }); - } else { - notifications.toasts.addSuccess({ - 'data-test-subj': `${options.riskScoreEntity}EnableSuccessToast`, - title: - options.riskScoreEntity === RiskScoreEntity.user - ? USER_RISK_SCORES_ENABLED_TITLE - : HOST_RISK_SCORES_ENABLED_TITLE, - text: RISK_SCORES_ENABLED_TEXT(resp.success.join(', ')), - }); - } - }) - .catch((e) => { - notifications.toasts.addError(new Error(errorMessage ?? INSTALLATION_ERROR), { - title: errorMessage ?? INSTALLATION_ERROR, - toastMessage: renderDocLink ? renderDocLink(e?.body?.message) : e?.body?.message, - toastLifeTimeMs, - }); - }); -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts deleted file mode 100644 index eb9adc159d019..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/saved_objects.ts +++ /dev/null @@ -1,151 +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 { HttpSetup } from '@kbn/core/public'; -import { toMountPoint } from '@kbn/react-kibana-mount'; -import type { DashboardStart } from '@kbn/dashboard-plugin/public'; -import type { StartRenderServices } from '../../../types'; -import { - RISKY_HOSTS_DASHBOARD_TITLE, - RISKY_USERS_DASHBOARD_TITLE, -} from '../../components/risk_score/constants'; -import { - prebuiltSavedObjectsBulkCreateUrl, - prebuiltSavedObjectsBulkDeleteUrl, -} from '../../../../common/constants'; - -import { RiskScoreEntity } from '../../../../common/search_strategy'; - -import { - DELETE_SAVED_OBJECTS_FAILURE, - IMPORT_SAVED_OBJECTS_FAILURE, - IMPORT_SAVED_OBJECTS_SUCCESS, -} from './translations'; - -const toastLifeTimeMs = 600000; - -type DashboardsSavedObjectTemplate = `${RiskScoreEntity}RiskScoreDashboards`; - -interface Options { - templateName: DashboardsSavedObjectTemplate; -} - -export const bulkCreatePrebuiltSavedObjects = async ({ - dashboard, - to, - errorMessage, - http, - options, - renderDashboardLink, - renderDocLink, - from, - startServices: { notifications, ...startServices }, -}: { - dashboard?: DashboardStart; - to: string; - errorMessage?: string; - http: HttpSetup; - options: Options; - renderDashboardLink?: (message: string, dashboardUrl: string) => React.ReactNode; - renderDocLink?: (message: string) => React.ReactNode; - from: string; - startServices: StartRenderServices; -}) => { - const res = await http - .post< - Record< - DashboardsSavedObjectTemplate, - { - success?: boolean; - error: Error; - body?: Array<{ type: string; title: string; id: string; name: string }>; - } - > - >(prebuiltSavedObjectsBulkCreateUrl(options.templateName), { version: '1' }) - .then((result) => { - const response = result[options.templateName]; - const error = response?.error?.message; - - if (error) { - notifications.toasts.addError(new Error(errorMessage ?? IMPORT_SAVED_OBJECTS_FAILURE), { - title: errorMessage ?? IMPORT_SAVED_OBJECTS_FAILURE, - toastMessage: renderDocLink ? (renderDocLink(error) as unknown as string) : error, - toastLifeTimeMs, - }); - } else { - const dashboardTitle = - options.templateName === `${RiskScoreEntity.user}RiskScoreDashboards` - ? RISKY_USERS_DASHBOARD_TITLE - : RISKY_HOSTS_DASHBOARD_TITLE; - - const targetDashboard = response?.body?.find( - (obj) => obj.type === 'dashboard' && obj?.title === dashboardTitle - ); - - let targetUrl; - if (targetDashboard?.id) { - targetUrl = dashboard?.locator?.getRedirectUrl({ - dashboardId: targetDashboard?.id, - timeRange: { - to, - from, - }, - }); - } - - const successMessage = response?.body?.map((o) => o?.title ?? o?.name).join(', '); - - if (successMessage == null || response?.body?.length == null) { - return; - } - - notifications.toasts.addSuccess({ - 'data-test-subj': `${options.templateName}SuccessToast`, - title: IMPORT_SAVED_OBJECTS_SUCCESS(response?.body?.length), - text: toMountPoint( - renderDashboardLink && targetUrl - ? renderDashboardLink(successMessage, targetUrl) - : successMessage, - startServices - ), - toastLifeTimeMs, - }); - } - }) - .catch((e) => { - notifications.toasts.addError(new Error(errorMessage ?? IMPORT_SAVED_OBJECTS_FAILURE), { - title: errorMessage ?? IMPORT_SAVED_OBJECTS_FAILURE, - toastMessage: renderDocLink ? renderDocLink(e?.body?.message) : e?.body?.message, - toastLifeTimeMs, - }); - }); - - return res; -}; - -export const bulkDeletePrebuiltSavedObjects = async ({ - http, - errorMessage, - options, - startServices: { notifications }, -}: { - http: HttpSetup; - errorMessage?: string; - options: Options; - startServices: StartRenderServices; -}) => { - const res = await http - .post(prebuiltSavedObjectsBulkDeleteUrl(options.templateName), { version: '1' }) - .catch((e) => { - notifications.toasts.addDanger({ - title: errorMessage ?? DELETE_SAVED_OBJECTS_FAILURE, - text: e?.body?.message, - }); - }); - - return res; -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.test.ts deleted file mode 100644 index fe23e8dbdb6c9..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.test.ts +++ /dev/null @@ -1,84 +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 { coreMock } from '@kbn/core/public/mocks'; -import type { HttpSetup } from '@kbn/core/public'; -import { createStoredScript, deleteStoredScript } from './stored_scripts'; - -const mockRequest = jest.fn(); -const mockHttp = { - put: mockRequest, - post: mockRequest, - delete: mockRequest, -} as unknown as HttpSetup; - -const startServices = coreMock.createStart(); -const mockAddDanger = jest.spyOn(startServices.notifications.toasts, 'addDanger'); - -const mockRenderDocLink = jest.fn(); - -describe('createStoredScript', () => { - const mockOptions = { id: 'test', script: { lang: 'painless', source: '' } }; - - beforeAll(async () => { - mockRequest.mockRejectedValue({ body: { message: 'test error' } }); - await createStoredScript({ - http: mockHttp, - options: mockOptions, - renderDocLink: mockRenderDocLink, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('create stored script', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/risk_score/stored_scripts/create`); - }); - - it('handles error', () => { - expect(mockAddDanger.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "text": [Function], - "title": "Failed to create stored script", - } - `); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test error'); - }); -}); - -describe('deleteStoredScript', () => { - const mockOptions = { id: 'test' }; - - beforeAll(async () => { - mockRequest.mockRejectedValue({ body: { message: 'test error' } }); - await deleteStoredScript({ - http: mockHttp, - options: mockOptions, - renderDocLink: mockRenderDocLink, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('delete stored script', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/risk_score/stored_scripts/delete`); - }); - - it('handles error', () => { - expect(mockAddDanger.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "text": [Function], - "title": "Failed to delete stored script", - } - `); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test error'); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts deleted file mode 100644 index 90aeef15c22a8..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/stored_scripts.ts +++ /dev/null @@ -1,92 +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 { toMountPoint } from '@kbn/react-kibana-mount'; -import { - RISK_SCORE_CREATE_STORED_SCRIPT, - RISK_SCORE_DELETE_STORED_SCRIPT, -} from '../../../../common/constants'; -import { - STORED_SCRIPT_CREATION_ERROR_MESSAGE, - STORED_SCRIPT_DELETION_ERROR_MESSAGE, -} from './translations'; -import type { CreateStoredScript, DeleteStoredScript, DeleteStoredScripts } from './types'; - -export async function createStoredScript({ - errorMessage, - http, - options, - renderDocLink, - signal, - startServices: { notifications, ...startServices }, -}: CreateStoredScript) { - const res = await http - .put(RISK_SCORE_CREATE_STORED_SCRIPT, { - version: '1', - body: JSON.stringify(options), - signal, - }) - .catch((e) => { - notifications.toasts.addDanger({ - title: errorMessage ?? STORED_SCRIPT_CREATION_ERROR_MESSAGE, - text: toMountPoint( - renderDocLink ? renderDocLink(e?.body?.message) : e?.body?.message, - startServices - ), - }); - }); - - return res; -} - -export async function deleteStoredScript({ - errorMessage, - http, - options, - renderDocLink, - signal, - startServices: { notifications, ...startServices }, -}: DeleteStoredScript) { - const res = await http - .delete(RISK_SCORE_DELETE_STORED_SCRIPT, { - version: '1', - body: JSON.stringify(options), - signal, - }) - .catch((e) => { - notifications.toasts.addDanger({ - title: errorMessage ?? STORED_SCRIPT_DELETION_ERROR_MESSAGE, - text: toMountPoint( - renderDocLink ? renderDocLink(e?.body?.message) : e?.body?.message, - startServices - ), - }); - }); - - return res; -} - -export async function deleteStoredScripts({ - http, - signal, - errorMessage, - ids, - startServices, -}: DeleteStoredScripts) { - const result = await Promise.all( - ids.map((id) => { - return deleteStoredScript({ - http, - signal, - errorMessage, - options: { id }, - startServices, - }); - }) - ); - return result; -} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.test.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.test.ts deleted file mode 100644 index d45d19d8d6227..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.test.ts +++ /dev/null @@ -1,214 +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 { coreMock } from '@kbn/core/public/mocks'; -import type { HttpSetup } from '@kbn/core/public'; -import { createTransform, deleteTransforms, getTransformState, stopTransforms } from './transforms'; - -const mockRequest = jest.fn(); -const mockHttp = { - get: mockRequest, - put: mockRequest, - post: mockRequest, - delete: mockRequest, -} as unknown as HttpSetup; - -const startServices = coreMock.createStart(); -const mockAddError = jest.spyOn(startServices.notifications.toasts, 'addError'); - -const mockRenderDocLink = jest.fn(); - -describe('createTransform', () => { - const mockOptions = {}; - - beforeAll(async () => { - mockRequest.mockResolvedValue({ - errors: [ - { id: 'test', error: { name: 'test error', output: { payload: { cause: 'unknown' } } } }, - ], - }); - await createTransform({ - http: mockHttp, - options: mockOptions, - renderDocLink: mockRenderDocLink, - transformId: 'test', - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('create transform', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/transform/transforms/test`); - }); - - it('handles error', () => { - expect(mockAddError.mock.calls[0][1].title).toEqual('Failed to create Transform'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test: unknown'); - }); -}); - -describe('getTransformState', () => { - beforeAll(async () => { - mockRequest.mockResolvedValue({ - count: 0, - }); - await getTransformState({ - http: mockHttp, - renderDocLink: mockRenderDocLink, - transformId: 'test', - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('get transform state', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/transform/transforms/test/_stats`); - }); - - it('handles error', () => { - expect(mockAddError.mock.calls[0][1].title).toEqual('Failed to get Transform state'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('Transform not found: test'); - }); -}); - -describe('startTransforms', () => { - beforeAll(async () => { - mockRequest.mockResolvedValue({ - count: 0, - }); - await getTransformState({ - http: mockHttp, - renderDocLink: mockRenderDocLink, - transformId: 'test', - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('get transform state', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/transform/transforms/test/_stats`); - }); - - it('handles error', () => { - expect(mockAddError.mock.calls[0][1].title).toEqual('Failed to get Transform state'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('Transform not found: test'); - }); -}); - -describe('stopTransforms', () => { - beforeAll(async () => { - // mock get transform state result - mockRequest.mockResolvedValueOnce({ - transforms: [{ id: 'test', state: 'stopped' }], - count: 1, - }); - // mock stop transform result - mockRequest.mockResolvedValueOnce({ - test: { - success: false, - error: { - root_cause: '', - type: '', - reason: 'unknown', - }, - }, - }); - - await stopTransforms({ - http: mockHttp, - transformIds: ['test'], - renderDocLink: mockRenderDocLink, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('get transform state', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/transform/transforms/test/_stats`); - }); - - it('stop transform', () => { - expect(mockRequest.mock.calls[1][0]).toEqual(`/internal/transform/stop_transforms`); - }); - - it('handles error', () => { - expect(mockAddError.mock.calls[0][1].title).toEqual('Failed to stop Transform'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test: unknown'); - }); -}); - -describe('deleteTransforms', () => { - const mockOptions = { - deleteDestIndex: true, - deleteDestDataView: true, - forceDelete: false, - }; - - beforeAll(async () => { - // mock get transform state result - mockRequest.mockResolvedValueOnce({ - transforms: [{ id: 'test', state: 'stopped' }], - count: 1, - }); - // mock stop transform result - mockRequest.mockResolvedValueOnce({ - test: { - success: true, - }, - }); - // mock delete transform result - mockRequest.mockResolvedValue({ - test: { - transformDeleted: { - success: false, - error: { - root_cause: '', - type: '', - reason: 'unknown', - }, - }, - destIndexDeleted: false, - destDataViewDeleted: false, - }, - }); - await deleteTransforms({ - http: mockHttp, - options: mockOptions, - transformIds: ['test'], - renderDocLink: mockRenderDocLink, - startServices, - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - it('get transform state', () => { - expect(mockRequest.mock.calls[0][0]).toEqual(`/internal/transform/transforms/test/_stats`); - }); - - it('stop transform', () => { - expect(mockRequest.mock.calls[1][0]).toEqual(`/internal/transform/stop_transforms`); - }); - - it('delete transform', () => { - expect(mockRequest.mock.calls[2][0]).toEqual(`/internal/transform/delete_transforms`); - }); - - it('handles error', () => { - expect(mockAddError.mock.calls[0][1].title).toEqual('Failed to delete Transform'); - expect(mockRenderDocLink.mock.calls[0][0]).toEqual('test: unknown'); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.ts deleted file mode 100644 index 9619b062b5f3d..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/transforms.ts +++ /dev/null @@ -1,327 +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 { - GET_TRANSFORM_STATE_ERROR_MESSAGE, - GET_TRANSFORM_STATE_NOT_FOUND_MESSAGE, - START_TRANSFORMS_ERROR_MESSAGE, - STOP_TRANSFORMS_ERROR_MESSAGE, - TRANSFORM_CREATION_ERROR_MESSAGE, - TRANSFORM_DELETION_ERROR_MESSAGE, -} from './translations'; -import type { - CreateTransform, - CreateTransformResult, - DeleteTransforms, - DeleteTransformsResult, - GetTransformsState, - GetTransformState, - StartTransforms, - StartTransformsResult, - StopTransforms, - StopTransformsResult, -} from './types'; - -const TRANSFORM_API_BASE_PATH = `/internal/transform`; -const toastLifeTimeMs = 600000; - -const getErrorToastMessage = ({ - messageBody, - renderDocLink, -}: { - messageBody: string; - renderDocLink?: (message: string) => React.ReactNode; -}) => (renderDocLink ? (renderDocLink(messageBody) as unknown as string) : messageBody); - -export async function createTransform({ - errorMessage, - http, - options, - renderDocLink, - signal, - transformId, - startServices: { notifications }, -}: CreateTransform) { - const res = await http - .put(`${TRANSFORM_API_BASE_PATH}/transforms/${transformId}`, { - body: JSON.stringify(options), - version: '1', - signal, - }) - .then((result) => { - const { errors } = result; - const errorMessageTitle = errorMessage ?? TRANSFORM_CREATION_ERROR_MESSAGE; - - if (errors && errors.length > 0) { - const failedIds = errors?.map(({ id, error }) => { - if (error?.output?.payload?.cause) { - return `${id}: ${error?.output?.payload?.cause}`; - } - return id; - }, []); - - notifications.toasts.addError(new Error(errorMessageTitle), { - title: errorMessageTitle, - toastMessage: getErrorToastMessage({ - messageBody: failedIds.join(', '), - renderDocLink, - }), - toastLifeTimeMs, - }); - } - return result; - }) - .catch((e) => { - notifications.toasts.addError(e, { - title: errorMessage ?? TRANSFORM_CREATION_ERROR_MESSAGE, - toastMessage: getErrorToastMessage({ messageBody: e?.body?.message, renderDocLink }), - toastLifeTimeMs, - }); - }); - - return res; -} - -export async function startTransforms({ - http, - renderDocLink, - signal, - errorMessage, - transformIds, - startServices: { notifications }, -}: StartTransforms) { - const res = await http - .post(`${TRANSFORM_API_BASE_PATH}/start_transforms`, { - body: JSON.stringify( - transformIds.map((id) => ({ - id, - })) - ), - version: '1', - signal, - }) - .then((result) => { - const failedIds = Object.entries(result).reduce((acc, [key, val]) => { - return !val.success - ? [...acc, val?.error?.reason ? `${key}: ${val?.error?.reason}` : key] - : acc; - }, []); - const errorMessageTitle = errorMessage ?? START_TRANSFORMS_ERROR_MESSAGE(failedIds.length); - - if (failedIds.length > 0) { - notifications.toasts.addError(new Error(errorMessageTitle), { - title: errorMessageTitle, - toastMessage: getErrorToastMessage({ - messageBody: failedIds.join(', '), - renderDocLink, - }), - toastLifeTimeMs, - }); - } - - return result; - }) - .catch((e) => { - notifications.toasts.addError(e, { - title: errorMessage ?? START_TRANSFORMS_ERROR_MESSAGE(transformIds.length), - toastMessage: getErrorToastMessage({ messageBody: e?.body?.message, renderDocLink }), - toastLifeTimeMs, - }); - }); - - return res; -} - -export async function getTransformState({ - http, - renderDocLink, - signal, - errorMessage = GET_TRANSFORM_STATE_ERROR_MESSAGE, - transformId, - startServices: { notifications }, -}: GetTransformState) { - const res = await http - .get<{ transforms: Array<{ id: string; state: string }>; count: number }>( - `${TRANSFORM_API_BASE_PATH}/transforms/${transformId}/_stats`, - { - version: '1', - signal, - } - ) - .then((result) => { - if (result.count === 0) { - notifications.toasts.addError(new Error(errorMessage), { - title: errorMessage, - toastMessage: getErrorToastMessage({ - messageBody: `${GET_TRANSFORM_STATE_NOT_FOUND_MESSAGE}: ${transformId}`, - renderDocLink, - }), - toastLifeTimeMs, - }); - } - return result; - }) - .catch((e) => { - notifications.toasts.addError(e, { - title: errorMessage, - toastMessage: getErrorToastMessage({ messageBody: e?.body?.message, renderDocLink }), - toastLifeTimeMs, - }); - }); - - return res; -} - -export async function getTransformsState({ - http, - signal, - errorMessage, - transformIds, - startServices, -}: GetTransformsState) { - const states = await Promise.all( - transformIds.map((transformId) => { - const transformState = getTransformState({ - http, - signal, - errorMessage, - transformId, - startServices, - }); - return transformState; - }) - ); - return states; -} - -export async function stopTransforms({ - http, - signal, - errorMessage, - transformIds, - renderDocLink, - startServices, -}: StopTransforms) { - const { notifications } = startServices; - const states = await getTransformsState({ http, signal, transformIds, startServices }); - const res = await http - .post(`${TRANSFORM_API_BASE_PATH}/stop_transforms`, { - version: '1', - body: JSON.stringify( - states.reduce( - (acc, state) => - state != null && state.transforms.length > 0 - ? [ - ...acc, - { - id: state.transforms[0].id, - state: state.transforms[0].state, - }, - ] - : acc, - [] as Array<{ id: string; state: string }> - ) - ), - signal, - }) - .then((result) => { - const failedIds = Object.entries(result).reduce((acc, [key, val]) => { - return !val.success - ? [...acc, val?.error?.reason ? `${key}: ${val?.error?.reason}` : key] - : acc; - }, []); - - const errorMessageTitle = errorMessage ?? STOP_TRANSFORMS_ERROR_MESSAGE(failedIds.length); - if (failedIds.length > 0) { - notifications.toasts.addError(new Error(errorMessageTitle), { - title: errorMessageTitle, - toastMessage: getErrorToastMessage({ - messageBody: failedIds.join(', '), - renderDocLink, - }), - toastLifeTimeMs, - }); - } - - return result; - }) - .catch((e) => { - notifications.toasts.addError(e, { - title: errorMessage ?? STOP_TRANSFORMS_ERROR_MESSAGE(transformIds.length), - toastMessage: getErrorToastMessage({ - messageBody: e?.body?.message, - renderDocLink, - }), - toastLifeTimeMs, - }); - }); - - return res; -} - -export async function deleteTransforms({ - http, - signal, - errorMessage, - transformIds, - options, - renderDocLink, - startServices, -}: DeleteTransforms) { - const { notifications } = startServices; - await stopTransforms({ http, signal, transformIds, startServices }); - const res = await http - .post(`${TRANSFORM_API_BASE_PATH}/delete_transforms`, { - version: '1', - body: JSON.stringify({ - transformsInfo: transformIds.map((id) => ({ - id, - state: 'stopped', - })), - ...(options ? options : {}), - }), - signal, - }) - .then((result) => { - const failedIds = Object.entries(result).reduce((acc, [key, val]) => { - return !val.transformDeleted.success - ? [ - ...acc, - val?.transformDeleted?.error?.reason - ? `${key}: ${val?.transformDeleted?.error?.reason}` - : key, - ] - : acc; - }, []); - const errorMessageTitle = errorMessage ?? TRANSFORM_DELETION_ERROR_MESSAGE(failedIds.length); - - if (failedIds.length > 0) { - notifications.toasts.addError(new Error(errorMessageTitle), { - title: errorMessageTitle, - toastMessage: getErrorToastMessage({ - messageBody: failedIds.join(', '), - renderDocLink, - }), - toastLifeTimeMs, - }); - } - - return result; - }) - .catch((e) => { - notifications.toasts.addError(e, { - title: errorMessage ?? TRANSFORM_DELETION_ERROR_MESSAGE(transformIds.length), - toastMessage: getErrorToastMessage({ - messageBody: e?.body?.message, - renderDocLink, - }), - toastLifeTimeMs, - }); - }); - - return res; -} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/translations.ts deleted file mode 100644 index 4af4a3f373ef1..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/translations.ts +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const INGEST_PIPELINE_CREATION_ERROR_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.ingestPipeline.create.errorMessageTitle', - { - defaultMessage: 'Failed to create Ingest pipeline', - } -); - -export const INGEST_PIPELINE_DELETION_ERROR_MESSAGE = (totalCount: number) => - i18n.translate('xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle', { - values: { totalCount }, - defaultMessage: `Failed to delete Ingest {totalCount, plural, =1 {pipeline} other {pipelines}}`, - }); - -export const STORED_SCRIPT_CREATION_ERROR_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.storedScript.create.errorMessageTitle', - { - defaultMessage: 'Failed to create stored script', - } -); - -export const STORED_SCRIPT_DELETION_ERROR_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.storedScript.delete.errorMessageTitle', - { - defaultMessage: `Failed to delete stored script`, - } -); - -export const TRANSFORM_CREATION_ERROR_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.transforms.create.errorMessageTitle', - { - defaultMessage: 'Failed to create Transform', - } -); - -export const TRANSFORM_DELETION_ERROR_MESSAGE = (totalCount: number) => - i18n.translate('xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle', { - values: { totalCount }, - defaultMessage: `Failed to delete {totalCount, plural, =1 {Transform} other {Transforms}}`, - }); - -export const GET_TRANSFORM_STATE_ERROR_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.transforms.getState.errorMessageTitle', - { - defaultMessage: `Failed to get Transform state`, - } -); - -export const GET_TRANSFORM_STATE_NOT_FOUND_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.api.transforms.getState.notFoundMessageTitle', - { - defaultMessage: `Transform not found`, - } -); - -export const START_TRANSFORMS_ERROR_MESSAGE = (totalCount: number) => - i18n.translate('xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle', { - values: { totalCount }, - defaultMessage: `Failed to start {totalCount, plural, =1 {Transform} other {Transforms}}`, - }); - -export const STOP_TRANSFORMS_ERROR_MESSAGE = (totalCount: number) => - i18n.translate('xpack.securitySolution.riskScore.api.transforms.stop.errorMessageTitle', { - values: { totalCount }, - defaultMessage: `Failed to stop {totalCount, plural, =1 {Transform} other {Transforms}}`, - }); - -export const INSTALLATION_ERROR = i18n.translate( - 'xpack.securitySolution.riskScore.install.errorMessageTitle', - { - defaultMessage: 'Installation error', - } -); - -export const UNINSTALLATION_ERROR = i18n.translate( - 'xpack.securitySolution.riskScore.uninstall.errorMessageTitle', - { - defaultMessage: 'Uninstallation error', - } -); - -export const IMPORT_SAVED_OBJECTS_SUCCESS = (totalCount: number) => - i18n.translate('xpack.securitySolution.riskScore.savedObjects.bulkCreateSuccessTitle', { - values: { totalCount }, - defaultMessage: `{totalCount} {totalCount, plural, =1 {saved object} other {saved objects}} imported successfully`, - }); - -export const IMPORT_SAVED_OBJECTS_FAILURE = i18n.translate( - 'xpack.securitySolution.riskScore.savedObjects.bulkCreateFailureTitle', - { - defaultMessage: `Failed to import saved objects`, - } -); - -export const DELETE_SAVED_OBJECTS_FAILURE = i18n.translate( - 'xpack.securitySolution.riskScore.savedObjects.bulkDeleteFailureTitle', - { - defaultMessage: `Failed to delete saved objects`, - } -); - -export const HOST_RISK_SCORES_ENABLED_TITLE = i18n.translate( - 'xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle', - { - defaultMessage: `Host Risk Scores enabled`, - } -); - -export const USER_RISK_SCORES_ENABLED_TITLE = i18n.translate( - 'xpack.securitySolution.riskScore.userRiskScoresEnabledTitle', - { - defaultMessage: `User Risk Scores enabled`, - } -); - -export const RISK_SCORES_ENABLED_TEXT = (items: string) => - i18n.translate('xpack.securitySolution.riskScore.savedObjects.enableRiskScoreSuccessTitle', { - values: { items }, - defaultMessage: `{items} imported successfully`, - }); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/types.ts b/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/types.ts deleted file mode 100644 index a6c91f47d60a5..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/deprecated_risk_engine/api/types.ts +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { HttpSetup } from '@kbn/core/public'; -import type { StartRenderServices } from '../../../types'; - -interface RiskyScoreApiBase { - errorMessage?: string; - http: HttpSetup; - renderDocLink?: (message: string) => React.ReactNode; - signal?: AbortSignal; - startServices: StartRenderServices; -} -export interface CreateIngestPipeline extends RiskyScoreApiBase { - options: { - name: string; - processors: string | Array>; - }; -} - -export interface DeleteIngestPipeline extends RiskyScoreApiBase { - names: string; -} - -export interface CreateStoredScript extends RiskyScoreApiBase { - options: { - id: string; - script: { - lang: string | 'painless' | 'expression' | 'mustache' | 'java'; - options?: Record; - source: string; - }; - }; -} - -export interface DeleteStoredScript extends RiskyScoreApiBase { - options: { - id: string; - }; -} - -export interface DeleteStoredScripts extends RiskyScoreApiBase { - ids: string[]; -} - -export interface CreateTransform extends RiskyScoreApiBase { - transformId: string; - options: string | Record; -} - -export interface CreateTransformResult { - transformsCreated: string[]; - errors?: Array<{ - id: string; - error?: { name: string; output?: { payload?: { cause?: string } } }; - }>; -} - -export interface StartTransforms extends RiskyScoreApiBase { - transformIds: string[]; -} - -interface TransformResult { - success: boolean; - error?: { root_cause?: unknown; type?: string; reason?: string }; -} - -export type StartTransformsResult = Record; - -export interface StopTransforms extends RiskyScoreApiBase { - transformIds: string[]; -} - -export type StopTransformsResult = Record; - -export interface GetTransformState extends RiskyScoreApiBase { - transformId: string; -} - -export interface GetTransformsState extends RiskyScoreApiBase { - transformIds: string[]; -} - -export interface DeleteTransforms extends RiskyScoreApiBase { - transformIds: string[]; - options?: { - deleteDestIndex?: boolean; - deleteDestDataView?: boolean; - forceDelete?: boolean; - }; -} - -export type DeleteTransformsResult = Record< - string, - { - transformDeleted: TransformResult; - destIndexDeleted: { - success: boolean; - }; - destDataViewDeleted: { - success: boolean; - }; - } ->; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/hooks/use_get_default_risk_index.ts b/x-pack/plugins/security_solution/public/entity_analytics/hooks/use_get_default_risk_index.ts new file mode 100644 index 0000000000000..7a042cd5ab8d6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/entity_analytics/hooks/use_get_default_risk_index.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + RiskScoreEntity, + getHostRiskIndex, + getUserRiskIndex, +} from '../../../common/search_strategy'; +import { useSpaceId } from '../../common/hooks/use_space_id'; + +export const useGetDefaulRiskIndex = ( + riskEntity: RiskScoreEntity, + onlyLatest: boolean = true +): string | undefined => { + const spaceId = useSpaceId(); + + if (!spaceId) { + return undefined; + } + + return riskEntity === RiskScoreEntity.host + ? getHostRiskIndex(spaceId, onlyLatest) + : getUserRiskIndex(spaceId, onlyLatest); +}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts index ea06d4dcdb567..311ee0240ec5d 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_donut.ts @@ -131,14 +131,14 @@ export const getRiskScoreDonutAttributes: GetLensAttributes = ( adHocDataViews: { [internalReferenceId]: { id: internalReferenceId, - title: `ml_${stackByField}_risk_score_latest_${extraOptions.spaceId}`, + title: `ea_${stackByField}_risk_score_latest_${extraOptions.spaceId}`, timeFieldName: '', sourceFilters: [], fieldFormats: {}, runtimeFieldMap: {}, fieldAttrs: {}, allowNoIndex: false, - name: `ml_${stackByField}_risk_score_latest_${extraOptions.spaceId}_no_timestamp`, + name: `ea_${stackByField}_risk_score_latest_${extraOptions.spaceId}_no_timestamp`, }, }, }, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx index 2fbc4f67ab6ef..2aeb9a9fd1acc 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/pages/entity_analytics_dashboard.tsx @@ -18,9 +18,6 @@ import { EmptyPrompt } from '../../common/components/empty_prompt'; import { SiemSearchBar } from '../../common/components/search_bar'; import { InputsModelId } from '../../common/store/inputs/constants'; import { FiltersGlobal } from '../../common/components/filters_global'; -import { useRiskEngineStatus } from '../api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from '../components/risk_score_update_panel'; -import { useHasSecurityCapability } from '../../helper_hooks'; import { EntityAnalyticsHeader } from '../components/entity_analytics_header'; import { EntityAnalyticsAnomalies } from '../components/entity_analytics_anomalies'; @@ -29,9 +26,7 @@ import { EntityAnalyticsRiskScores } from '../components/entity_analytics_risk_s import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features'; const EntityAnalyticsComponent = () => { - const { data: riskScoreEngineStatus } = useRiskEngineStatus(); const { indicesExist, loading: isSourcererLoading, sourcererDataView } = useSourcererDataView(); - const isRiskScoreModuleLicenseAvailable = useHasSecurityCapability('entity-analytics'); const isEntityStoreFeatureFlagDisabled = useIsExperimentalFeatureEnabled('entityStoreDisabled'); return ( @@ -49,12 +44,6 @@ const EntityAnalyticsComponent = () => { ) : ( - {riskScoreEngineStatus?.isUpdateAvailable && isRiskScoreModuleLicenseAvailable && ( - - - - )} - diff --git a/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.test.tsx b/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.test.tsx index 456caaf0d01c5..cec6ad108632b 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.test.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.test.tsx @@ -15,11 +15,6 @@ jest.mock('../../../../common/containers/use_search_strategy', () => ({ useSearchStrategy: jest.fn(), })); -jest.mock('../../../../entity_analytics/api/hooks/use_risk_engine_status', () => ({ - useIsNewRiskScoreModuleInstalled: jest - .fn() - .mockReturnValue({ isLoading: false, installed: true }), -})); const mockUseSearchStrategy = useSearchStrategy as jest.Mock; const mockSearch = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.tsx b/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.tsx index a2dcf337f2cd4..01b5cfb6422c3 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/containers/hosts/index.tsx @@ -22,7 +22,6 @@ import type { ESTermQuery } from '../../../../../common/typed_json'; import * as i18n from './translations'; import type { InspectResponse } from '../../../../types'; import { useSearchStrategy } from '../../../../common/containers/use_search_strategy'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; export const ID = 'hostsAllQuery'; @@ -62,9 +61,6 @@ export const useAllHost = ({ getHostsSelector(state, type) ); - const { installed: isNewRiskScoreModuleInstalled, isLoading: riskScoreStatusLoading } = - useIsNewRiskScoreModuleInstalled(); - const [hostsRequest, setHostRequest] = useState(null); const wrappedLoadMore = useCallback( @@ -130,9 +126,6 @@ export const useAllHost = ({ ); useEffect(() => { - if (riskScoreStatusLoading) { - return; - } setHostRequest((prevRequest) => { const myRequest: HostsRequestOptionsInput = { ...(prevRequest ?? {}), @@ -149,25 +142,13 @@ export const useAllHost = ({ direction, field: sortField, }, - isNewRiskScoreModuleInstalled, }; if (!deepEqual(prevRequest, myRequest)) { return myRequest; } return prevRequest; }); - }, [ - activePage, - direction, - endDate, - filterQuery, - indexNames, - limit, - startDate, - sortField, - isNewRiskScoreModuleInstalled, - riskScoreStatusLoading, - ]); + }, [activePage, direction, endDate, filterQuery, indexNames, limit, startDate, sortField]); useEffect(() => { if (!skip && hostsRequest) { diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx index 5e6c8d8778f80..ccd44230a9d16 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx @@ -8,6 +8,7 @@ import React, { useEffect, useMemo, useState } from 'react'; import { EuiPanel } from '@elastic/eui'; import { noop } from 'lodash/fp'; +import { RiskScoresNoDataDetected } from '../../../../entity_analytics/components/risk_score_no_data_detected'; import { useUpsellingComponent } from '../../../../common/hooks/use_upselling'; import { RiskEnginePrivilegesCallOut } from '../../../../entity_analytics/components/risk_engine_privileges_callout'; import { useMissingRiskEnginePrivileges } from '../../../../entity_analytics/hooks/use_missing_risk_engine_privileges'; @@ -23,9 +24,6 @@ import { hostsModel, hostsSelectors } from '../../store'; import type { State } from '../../../../common/store'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; import { EMPTY_SEVERITY_COUNT, RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RiskScoresNoDataDetected } from '../../../../entity_analytics/components/risk_score_onboarding/risk_score_no_data_detected'; -import { useRiskEngineStatus } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; -import { RiskScoreUpdatePanel } from '../../../../entity_analytics/components/risk_score_update_panel'; const HostRiskScoreTableManage = manageQuery(HostRiskScoreTable); @@ -50,8 +48,6 @@ export const HostRiskScoreQueryTabBody = ({ getHostRiskScoreFilterQuerySelector(state, hostsModel.HostsType.page) ); - const { data: riskScoreEngineStatus } = useRiskEngineStatus(); - const pagination = useMemo( () => ({ cursorStart: activePage * limit, @@ -68,23 +64,15 @@ export const HostRiskScoreQueryTabBody = ({ const timerange = useMemo(() => ({ from, to }), [from, to]); const privileges = useMissingRiskEnginePrivileges(); - const { - data, - inspect, - isDeprecated, - isInspected, - isModuleEnabled, - loading, - refetch, - totalCount, - } = useRiskScore({ - filterQuery, - pagination, - riskEntity: RiskScoreEntity.host, - skip: querySkip, - sort, - timerange, - }); + const { data, inspect, isInspected, isEngineEnabled, loading, refetch, totalCount } = + useRiskScore({ + filterQuery, + pagination, + riskEntity: RiskScoreEntity.host, + skip: querySkip, + sort, + timerange, + }); const { severityCount, loading: isKpiLoading } = useRiskScoreKpi({ filterQuery, @@ -92,11 +80,7 @@ export const HostRiskScoreQueryTabBody = ({ riskEntity: RiskScoreEntity.host, }); - const status = { - isDisabled: !isModuleEnabled && !loading, - isDeprecated: isDeprecated && !loading, - }; - + const isDisabled = !isEngineEnabled && !loading; const RiskScoreUpsell = useUpsellingComponent('entity_analytics_panel'); if (RiskScoreUpsell) { @@ -111,11 +95,11 @@ export const HostRiskScoreQueryTabBody = ({ ); } - if (status.isDisabled || status.isDeprecated) { + if (isDisabled) { return ( ; + return ; } return ( <> - {riskScoreEngineStatus?.isUpdateAvailable && } ({ - useIsNewRiskScoreModuleInstalled: jest - .fn() - .mockReturnValue({ isLoading: false, installed: true }), -})); const mockSearch = jest.fn(); diff --git a/x-pack/plugins/security_solution/public/explore/users/pages/navigation/all_users_query_tab_body.tsx b/x-pack/plugins/security_solution/public/explore/users/pages/navigation/all_users_query_tab_body.tsx index f33b57752ff60..e503684aa500b 100644 --- a/x-pack/plugins/security_solution/public/explore/users/pages/navigation/all_users_query_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/explore/users/pages/navigation/all_users_query_tab_body.tsx @@ -19,7 +19,6 @@ import { generateTablePaginationOptions } from '../../../components/paginated_ta import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; import { usersSelectors } from '../../store'; import { useQueryToggle } from '../../../../common/containers/query_toggle'; -import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status'; const UsersTableManage = manageQuery(UsersTable); @@ -43,8 +42,6 @@ export const AllUsersQueryTabBody = ({ const getUsersSelector = useMemo(() => usersSelectors.allUsersSelector(), []); const { activePage, limit, sort } = useDeepEqualSelector((state) => getUsersSelector(state)); - const { installed: isNewRiskScoreModuleInstalled, isLoading: riskScoreStatusLoading } = - useIsNewRiskScoreModuleInstalled(); const { loading, @@ -68,7 +65,7 @@ export const AllUsersQueryTabBody = ({ }); useEffect(() => { - if (!querySkip && !riskScoreStatusLoading) { + if (!querySkip) { search({ filterQuery, defaultIndex: indexNames, @@ -79,22 +76,9 @@ export const AllUsersQueryTabBody = ({ }, pagination: generateTablePaginationOptions(activePage, limit), sort, - isNewRiskScoreModuleInstalled, }); } - }, [ - search, - startDate, - endDate, - filterQuery, - indexNames, - querySkip, - activePage, - limit, - sort, - isNewRiskScoreModuleInstalled, - riskScoreStatusLoading, - ]); + }, [search, startDate, endDate, filterQuery, indexNames, querySkip, activePage, limit, sort]); return ( - {riskScoreState.isModuleEnabled && riskScoreState.data?.length !== 0 && ( + {riskScoreState.isEngineEnabled && riskScoreState.data?.length !== 0 && ( <> = { isInspected: false, refetch: () => {}, totalCount: 0, - isModuleEnabled: true, isAuthorized: true, - isDeprecated: false, + isEngineEnabled: true, loading: false, error: undefined, }; @@ -111,9 +110,8 @@ export const mockHostRiskScoreState: RiskScoreState = { isInspected: false, refetch: () => {}, totalCount: 0, - isModuleEnabled: true, isAuthorized: true, - isDeprecated: false, + isEngineEnabled: true, loading: false, error: undefined, }; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx index 08295038a1bd8..3a23fd6cb8b0e 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx @@ -57,7 +57,7 @@ export const UserPanelContent = ({ return ( - {riskScoreState.isModuleEnabled && riskScoreState.data?.length !== 0 && ( + {riskScoreState.isEngineEnabled && riskScoreState.data?.length !== 0 && ( <> {}, totalCount: 0, - isModuleEnabled: true, + isEngineEnabled: true, isAuthorized: true, isDeprecated: false, loading: false, diff --git a/x-pack/plugins/security_solution/public/overview/components/common.tsx b/x-pack/plugins/security_solution/public/overview/components/common.tsx index 078b2bbe17fa2..8483d4849b121 100644 --- a/x-pack/plugins/security_solution/public/overview/components/common.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/common.tsx @@ -8,7 +8,7 @@ import { EuiButtonIcon, EuiPopover, EuiPopoverTitle, EuiText } from '@elastic/eui'; import React, { useCallback, useState } from 'react'; import * as i18n from './translations'; -import { EntityAnalyticsLearnMoreLink } from '../../entity_analytics/components/risk_score_onboarding/entity_analytics_doc_link'; +import { EntityAnalyticsLearnMoreLink } from '../../entity_analytics/components/entity_analytics_learn_more_link'; export const RiskScoreInfoTooltip: React.FC<{ toolTipContent: React.ReactNode; diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx index 3dfeb6a47ae94..cf760f93588e6 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.tsx @@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th import { getOr } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_header_title'; import { useGlobalTime } from '../../../common/containers/use_global_time'; import { useQueryInspector } from '../../../common/components/page/manage_query'; import { FIRST_RECORD_PAGINATION } from '../../../entity_analytics/common'; @@ -37,7 +38,6 @@ import * as i18n from './translations'; import { EndpointOverview } from './endpoint_overview'; import { OverviewDescriptionList } from '../../../common/components/overview_description_list'; import { RiskScoreLevel } from '../../../entity_analytics/components/severity/common'; -import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_onboarding/risk_score_header_title'; import { RiskScoreDocTooltip } from '../common'; interface HostSummaryProps { diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx index 3d10ad4b77e76..043a7d67aa928 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.tsx @@ -10,6 +10,7 @@ import { euiDarkVars as darkTheme, euiLightVars as lightTheme } from '@kbn/ui-th import { getOr } from 'lodash/fp'; import React, { useCallback, useMemo } from 'react'; import styled from 'styled-components'; +import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_header_title'; import { useGlobalTime } from '../../../common/containers/use_global_time'; import { FIRST_RECORD_PAGINATION } from '../../../entity_analytics/common'; import { useQueryInspector } from '../../../common/components/page/manage_query'; @@ -37,7 +38,6 @@ import * as i18n from './translations'; import { OverviewDescriptionList } from '../../../common/components/overview_description_list'; import { RiskScoreLevel } from '../../../entity_analytics/components/severity/common'; import type { UserItem } from '../../../../common/search_strategy/security_solution/users/common'; -import { RiskScoreHeaderTitle } from '../../../entity_analytics/components/risk_score_onboarding/risk_score_header_title'; import { RiskScoreDocTooltip } from '../common'; export interface UserSummaryProps { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts index 7599cf28e9183..22e0e858db99b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/host_risk.ts @@ -21,11 +21,10 @@ export const createHostRiskEnrichments: CreateRiskEnrichment = async ({ logger, events, spaceId, - isNewRiskScoreModuleInstalled, }) => { return createSingleFieldMatchEnrichment({ name: 'Host Risk', - index: [getHostRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled)], + index: [getHostRiskIndex(spaceId, true)], services, logger, events, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts index ad4ca20b140ac..d96678eaf397c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/enrichment_by_type/user_risk.ts @@ -21,11 +21,10 @@ export const createUserRiskEnrichments: CreateRiskEnrichment = async ({ logger, events, spaceId, - isNewRiskScoreModuleInstalled, }) => { return createSingleFieldMatchEnrichment({ name: 'User Risk', - index: [getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled)], + index: [getUserRiskIndex(spaceId, true)], services, logger, events, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts index 7f0c797bc6743..e2dab7d528502 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.ts @@ -34,24 +34,15 @@ export const enrichEvents: EnrichEventsFunction = async ({ const enrichments: Array> = []; logger.debug('Alert enrichments started'); - const isNewRiskScoreModuleAvailable = experimentalFeatures?.riskScoringRoutesEnabled ?? false; - - let isNewRiskScoreModuleInstalled = false; - if (isNewRiskScoreModuleAvailable) { - isNewRiskScoreModuleInstalled = await isIndexExist({ - services, - index: getHostRiskIndex(spaceId, true, true), - }); - } const [isHostRiskScoreIndexExist, isUserRiskScoreIndexExist] = await Promise.all([ isIndexExist({ services, - index: getHostRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled), + index: getHostRiskIndex(spaceId, true), }), isIndexExist({ services, - index: getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled), + index: getUserRiskIndex(spaceId, true), }), ]); @@ -62,7 +53,6 @@ export const enrichEvents: EnrichEventsFunction = async ({ logger, events, spaceId, - isNewRiskScoreModuleInstalled, }) ); } @@ -74,7 +64,6 @@ export const enrichEvents: EnrichEventsFunction = async ({ logger, events, spaceId, - isNewRiskScoreModuleInstalled, }) ); } diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts index 70f710630da37..d13d42291dc34 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/types.ts @@ -72,7 +72,6 @@ export type SearchEnrichments = (params: { export type GetIsRiskScoreAvailable = (params: { spaceId: string; services: RuleServices; - isNewRiskScoreModuleInstalled: boolean; }) => Promise; export type IsIndexExist = (params: { services: RuleServices; index: string }) => Promise; @@ -80,7 +79,6 @@ export type IsIndexExist = (params: { services: RuleServices; index: string }) = export type CreateRiskEnrichment = ( params: BasedEnrichParamters & { spaceId: string; - isNewRiskScoreModuleInstalled: boolean; } ) => Promise; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/audit.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/audit.ts index 9ade355d54bf3..a16c1ab6a1b01 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/audit.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/audit.ts @@ -10,11 +10,9 @@ export enum RiskEngineAuditActions { RISK_ENGINE_START = 'risk_engine_start', RISK_ENGINE_DISABLE = 'risk_engine_disable', RISK_ENGINE_INIT = 'risk_engine_init', - RISK_ENGINE_GET_LEGACY_ENGINE_STATUS_GET = 'risk_engine_get_legacy_engine_status_get', RISK_ENGINE_STATUS_FOR_ALL_SPACES_GET = 'risk_engine_status_for_all_spaces_get', RISK_ENGINE_STATUS_GET = 'risk_engine_status_get', RISK_ENGINE_CONFIGURATION_GET = 'risk_engine_configuration_get', - RISK_ENGINE_DISABLE_LEGACY_ENGINE = 'risk_engine_disable_legacy_engine', RISK_ENGINE_REMOVE_TASK = 'risk_engine_remove_task', RISK_ENGINE_SCHEDULE_NOW = 'risk_engine_schedule_now', } diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.mock.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.mock.ts index e9819c5b290d3..14e75d3ae0b60 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.mock.ts @@ -9,7 +9,6 @@ import type { RiskEngineDataClient } from './risk_engine_data_client'; const createRiskEngineDataClientMock = () => ({ - disableLegacyRiskEngine: jest.fn(), disableRiskEngine: jest.fn(), enableRiskEngine: jest.fn(), getConfiguration: jest.fn(), diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.test.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.test.ts index 0f807ebe22265..351fd10ae97c0 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.test.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.test.ts @@ -209,18 +209,12 @@ describe('RiskEngineDataClient', () => { let mockTaskManagerStart: ReturnType; let initRiskScore: jest.SpyInstance; let enableRiskEngineMock: jest.SpyInstance; - let disableLegacyRiskEngineMock: jest.SpyInstance; beforeEach(() => { initRiskScore = jest.spyOn(RiskScoreDataClient.prototype, 'init'); enableRiskEngineMock = jest.spyOn(RiskEngineDataClient.prototype, 'enableRiskEngine'); - disableLegacyRiskEngineMock = jest.spyOn( - RiskEngineDataClient.prototype, - 'disableLegacyRiskEngine' - ); mockTaskManagerStart = taskManagerMock.createStart(); - disableLegacyRiskEngineMock.mockImplementation(() => Promise.resolve(true)); initRiskScore.mockImplementation(() => { return Promise.resolve(); @@ -238,7 +232,6 @@ describe('RiskEngineDataClient', () => { afterEach(() => { initRiskScore.mockReset(); enableRiskEngineMock.mockReset(); - disableLegacyRiskEngineMock.mockReset(); }); it('success', async () => { @@ -250,46 +243,6 @@ describe('RiskEngineDataClient', () => { expect(initResult).toEqual({ errors: [], - legacyRiskEngineDisabled: true, - riskEngineConfigurationCreated: true, - riskEngineEnabled: true, - riskEngineResourcesInstalled: true, - }); - }); - - it('should catch error for disableLegacyRiskEngine, but continue', async () => { - disableLegacyRiskEngineMock.mockImplementation(() => { - throw new Error('Error disableLegacyRiskEngineMock'); - }); - const initResult = await riskEngineDataClient.init({ - namespace: 'default', - taskManager: mockTaskManagerStart, - riskScoreDataClient: riskScoreDataClientMock.create(), - }); - - expect(initResult).toEqual({ - errors: ['Error disableLegacyRiskEngineMock'], - legacyRiskEngineDisabled: false, - riskEngineConfigurationCreated: true, - riskEngineEnabled: true, - riskEngineResourcesInstalled: true, - }); - }); - - it('should catch error for resource init', async () => { - disableLegacyRiskEngineMock.mockImplementationOnce(() => { - throw new Error('Error disableLegacyRiskEngineMock'); - }); - - const initResult = await riskEngineDataClient.init({ - namespace: 'default', - taskManager: mockTaskManagerStart, - riskScoreDataClient: riskScoreDataClientMock.create(), - }); - - expect(initResult).toEqual({ - errors: ['Error disableLegacyRiskEngineMock'], - legacyRiskEngineDisabled: false, riskEngineConfigurationCreated: true, riskEngineEnabled: true, riskEngineResourcesInstalled: true, @@ -310,7 +263,6 @@ describe('RiskEngineDataClient', () => { expect(initResult).toEqual({ errors: ['Error riskScoreDataClient'], - legacyRiskEngineDisabled: true, riskEngineConfigurationCreated: false, riskEngineEnabled: false, riskEngineResourcesInstalled: false, @@ -330,7 +282,6 @@ describe('RiskEngineDataClient', () => { expect(initResult).toEqual({ errors: ['Error initSavedObjects'], - legacyRiskEngineDisabled: true, riskEngineConfigurationCreated: false, riskEngineEnabled: false, riskEngineResourcesInstalled: true, @@ -350,7 +301,6 @@ describe('RiskEngineDataClient', () => { expect(initResult).toEqual({ errors: ['Error enableRiskEngineMock'], - legacyRiskEngineDisabled: true, riskEngineConfigurationCreated: true, riskEngineEnabled: false, riskEngineResourcesInstalled: true, diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.ts index 241523f62e12c..6a3cdf9ce70dd 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/risk_engine_data_client.ts @@ -10,15 +10,12 @@ import type { TaskManagerStartContract } from '@kbn/task-manager-plugin/server'; import type { AuditLogger } from '@kbn/security-plugin-types-server'; import { RiskEngineStatusEnum } from '../../../../common/api/entity_analytics'; import type { InitRiskEngineResult } from '../../../../common/entity_analytics/risk_engine'; -import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; -import { removeLegacyTransforms, getLegacyTransforms } from '../utils/transforms'; import { updateSavedObjectAttribute, getConfiguration, initSavedObjects, deleteSavedObjects, } from './utils/saved_object_configuration'; -import { bulkDeleteSavedObjects } from '../../risk_score/prebuilt_saved_objects/helpers/bulk_delete_saved_objects'; import type { RiskScoreDataClient } from '../risk_score/risk_score_data_client'; import { removeRiskScoringTask, startRiskScoringTask } from '../risk_score/tasks'; import { RiskEngineAuditActions } from './audit'; @@ -50,29 +47,12 @@ export class RiskEngineDataClient { public async init({ namespace, taskManager, riskScoreDataClient }: InitOpts) { const result: InitRiskEngineResult = { - legacyRiskEngineDisabled: false, riskEngineResourcesInstalled: false, riskEngineConfigurationCreated: false, riskEngineEnabled: false, errors: [] as string[], }; - try { - result.legacyRiskEngineDisabled = await this.disableLegacyRiskEngine({ namespace }); - this.options.auditLogger?.log({ - message: 'System disabled the legacy risk engine.', - event: { - action: RiskEngineAuditActions.RISK_ENGINE_DISABLE_LEGACY_ENGINE, - category: AUDIT_CATEGORY.DATABASE, - type: AUDIT_TYPE.CHANGE, - outcome: AUDIT_OUTCOME.SUCCESS, - }, - }); - } catch (e) { - result.legacyRiskEngineDisabled = false; - result.errors.push(e.message); - } - try { await riskScoreDataClient.init(); result.riskEngineResourcesInstalled = true; @@ -117,7 +97,6 @@ export class RiskEngineDataClient { taskManager?: TaskManagerStartContract; }) { const riskEngineStatus = await this.getCurrentStatus(); - const legacyRiskEngineStatus = await this.getLegacyStatus({ namespace }); const taskStatus = riskEngineStatus === 'ENABLED' && taskManager @@ -136,7 +115,6 @@ export class RiskEngineDataClient { return { riskEngineStatus, - legacyRiskEngineStatus, taskStatus, }; } @@ -262,34 +240,6 @@ export class RiskEngineDataClient { return errors.concat(riskScoreErrors); } - public async disableLegacyRiskEngine({ namespace }: { namespace: string }) { - const legacyRiskEngineStatus = await this.getLegacyStatus({ namespace }); - - if (legacyRiskEngineStatus === RiskEngineStatusEnum.NOT_INSTALLED) { - return true; - } - - await removeLegacyTransforms({ - esClient: this.options.esClient, - namespace, - }); - - const deleteDashboardsPromises = [RiskScoreEntity.host, RiskScoreEntity.user].map((entity) => - bulkDeleteSavedObjects({ - deleteAll: true, - savedObjectsClient: this.options.soClient, - spaceId: namespace, - savedObjectTemplate: `${entity}RiskScoreDashboards`, - }) - ); - - await Promise.all(deleteDashboardsPromises); - - const newlegacyRiskEngineStatus = await this.getLegacyStatus({ namespace }); - - return newlegacyRiskEngineStatus === RiskEngineStatusEnum.NOT_INSTALLED; - } - private async getCurrentStatus() { const configuration = await this.getConfiguration(); @@ -299,24 +249,4 @@ export class RiskEngineDataClient { return RiskEngineStatusEnum.NOT_INSTALLED; } - - private async getLegacyStatus({ namespace }: { namespace: string }) { - const transforms = await getLegacyTransforms({ namespace, esClient: this.options.esClient }); - - this.options.auditLogger?.log({ - message: 'System checked if the legacy risk engine is enabled', - event: { - action: RiskEngineAuditActions.RISK_ENGINE_GET_LEGACY_ENGINE_STATUS_GET, - category: AUDIT_CATEGORY.DATABASE, - type: AUDIT_TYPE.ACCESS, - outcome: AUDIT_OUTCOME.SUCCESS, - }, - }); - - if (transforms.length === 0) { - return RiskEngineStatusEnum.NOT_INSTALLED; - } - - return RiskEngineStatusEnum.ENABLED; - } } diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/init.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/init.ts index 67edb78b740c5..740ee309a5113 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/init.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/init.ts @@ -73,7 +73,6 @@ export const riskEngineInitRoute = ( risk_engine_enabled: initResult.riskEngineEnabled, risk_engine_resources_installed: initResult.riskEngineResourcesInstalled, risk_engine_configuration_created: initResult.riskEngineConfigurationCreated, - legacy_risk_engine_disabled: initResult.legacyRiskEngineDisabled, errors: initResult.errors, }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/status.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/status.ts index 5ece4cbf48e43..cb8865af86f9a 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/status.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/status.ts @@ -37,15 +37,13 @@ export const riskEngineStatusRoute = ( const [_, { taskManager }] = await getStartServices(); try { - const { riskEngineStatus, legacyRiskEngineStatus, taskStatus } = - await riskEngineClient.getStatus({ - namespace: spaceId, - taskManager, - }); + const { riskEngineStatus, taskStatus } = await riskEngineClient.getStatus({ + namespace: spaceId, + taskManager, + }); const body: RiskEngineStatusResponse = { risk_engine_status: riskEngineStatus, - legacy_risk_engine_status: legacyRiskEngineStatus, risk_engine_task_status: taskStatus, }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts index 4282e0a793f47..ec499bfcce48f 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/utils/saved_object_configuration.ts @@ -6,9 +6,9 @@ */ import type { SavedObject, SavedObjectsClientContract } from '@kbn/core/server'; -import { getAlertsIndex } from '../../../../../common/utils/risk_score_modules'; import type { RiskEngineConfiguration } from '../../types'; import { riskEngineConfigurationTypeName } from '../saved_object'; +import { getAlertsIndex } from '../../utils/get_alerts_index'; export interface SavedObjectsClientArg { savedObjectsClient: SavedObjectsClientContract; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_indices/delete_indices_route.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/get_alerts_index.ts similarity index 61% rename from x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_indices/delete_indices_route.ts rename to x-pack/plugins/security_solution/server/lib/entity_analytics/utils/get_alerts_index.ts index b773a52917a73..8f4fc2befa638 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_score/delete_indices/delete_indices_route.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/get_alerts_index.ts @@ -5,8 +5,6 @@ * 2.0. */ -import { schema } from '@kbn/config-schema'; +import { DEFAULT_ALERTS_INDEX } from '../../../../common/constants'; -export const deleteIndicesRequestBody = schema.object({ - indices: schema.arrayOf(schema.string()), -}); +export const getAlertsIndex = (spaceId = 'default') => `${DEFAULT_ALERTS_INDEX}-${spaceId}`; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/transforms.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/transforms.ts index 35a7f7113bfa5..8b49dc487d274 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/transforms.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/utils/transforms.ts @@ -7,7 +7,6 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import type { - TransformGetTransformResponse, TransformStartTransformResponse, TransformPutTransformResponse, TransformGetTransformTransformSummary, @@ -18,66 +17,9 @@ import { getRiskScoreLatestIndex, getRiskScoreTimeSeriesIndex, } from '../../../../common/entity_analytics/risk_engine'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; -import { - getRiskScorePivotTransformId, - getRiskScoreLatestTransformId, -} from '../../../../common/utils/risk_score_modules'; import type { TransformOptions } from '../risk_score/configurations'; import { getTransformOptions } from '../risk_score/configurations'; -export const getLegacyTransforms = async ({ - namespace, - esClient, -}: { - namespace: string; - esClient: ElasticsearchClient; -}) => { - const getTransformStatsRequests: Array> = []; - [RiskScoreEntity.host, RiskScoreEntity.user].forEach((entity) => { - getTransformStatsRequests.push( - esClient.transform.getTransform({ - transform_id: getRiskScorePivotTransformId(entity, namespace), - }) - ); - getTransformStatsRequests.push( - esClient.transform.getTransform({ - transform_id: getRiskScoreLatestTransformId(entity, namespace), - }) - ); - }); - - const results = await Promise.allSettled(getTransformStatsRequests); - - const transforms = results.reduce((acc, result) => { - if (result.status === 'fulfilled' && result.value?.transforms?.length > 0) { - acc.push(...result.value.transforms); - } - return acc; - }, [] as TransformGetTransformTransformSummary[]); - - return transforms; -}; - -export const removeLegacyTransforms = async ({ - namespace, - esClient, -}: { - namespace: string; - esClient: ElasticsearchClient; -}): Promise => { - const transforms = await getLegacyTransforms({ namespace, esClient }); - - const stopTransformRequests = transforms.map((t) => - esClient.transform.deleteTransform({ - transform_id: t.id, - force: true, - }) - ); - - await Promise.allSettled(stopTransformRequests); -}; - export const createTransform = async ({ esClient, transform, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.test.ts deleted file mode 100644 index 77adf7e0efef6..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.test.ts +++ /dev/null @@ -1,85 +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 { getRiskScoreIndexStatusRoute } from '.'; -import { - requestMock, - serverMock, - requestContextMock, -} from '../../detection_engine/routes/__mocks__'; - -import { RISK_SCORE_INDEX_STATUS_API_URL } from '../../../../common/constants'; - -const fieldCaps = { - indices: ['not_important'], - fields: { - 'host.risk.calculated_level': { - text: { - type: 'text', - metadata_field: false, - searchable: true, - aggregatable: false, - }, - }, - }, -}; -describe('risk score index status route', () => { - let server: ReturnType; - let { clients, context } = requestContextMock.createTools(); - const getRequest = (entity: string) => - requestMock.create({ - method: 'get', - path: RISK_SCORE_INDEX_STATUS_API_URL, - query: { indexName: 'hi', entity }, - }); - - beforeEach(() => { - server = serverMock.create(); - ({ clients, context } = requestContextMock.createTools()); - }); - - test('If new fields are not available, isDeprecated = true', async () => { - clients.clusterClient.asCurrentUser.fieldCaps.mockResolvedValue(fieldCaps); - getRiskScoreIndexStatusRoute(server.router); - const response = await server.inject( - getRequest('user'), - requestContextMock.convertContext(context) - ); - expect(response.body).toEqual({ isDeprecated: true, isEnabled: true }); - }); - test('If new fields are available, isDeprecated = false', async () => { - clients.clusterClient.asCurrentUser.fieldCaps.mockResolvedValue(fieldCaps); - getRiskScoreIndexStatusRoute(server.router); - const response = await server.inject( - getRequest('host'), - requestContextMock.convertContext(context) - ); - expect(response.body).toEqual({ isDeprecated: false, isEnabled: true }); - }); - - test('404 error does not throw, returns isEnabled = false', async () => { - const notFoundError: Error & { statusCode?: number } = new Error('not found'); - notFoundError.statusCode = 404; - clients.clusterClient.asCurrentUser.fieldCaps.mockRejectedValue(notFoundError); - getRiskScoreIndexStatusRoute(server.router); - const response = await server.inject( - getRequest('host'), - requestContextMock.convertContext(context) - ); - expect(response.body).toEqual({ isDeprecated: false, isEnabled: false }); - }); - - test('any other error throws', async () => { - clients.clusterClient.asCurrentUser.fieldCaps.mockRejectedValue(new Error('any other error')); - getRiskScoreIndexStatusRoute(server.router); - const response = await server.inject( - getRequest('host'), - requestContextMock.convertContext(context) - ); - expect(response.body).toEqual({ message: 'any other error', status_code: 500 }); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts deleted file mode 100644 index c53039367dfbe..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; - -import { APP_ID, RISK_SCORE_INDEX_STATUS_API_URL } from '../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../types'; -import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; -import { buildSiemResponse } from '../../detection_engine/routes/utils'; -import { indexStatusRequestQuery } from '../../../../common/api/entity_analytics/risk_score'; - -export const getRiskScoreIndexStatusRoute = (router: SecuritySolutionPluginRouter) => { - router.versioned - .get({ - access: 'internal', - path: RISK_SCORE_INDEX_STATUS_API_URL, - security: { - authz: { - requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`], - }, - }, - }) - .addVersion( - { - validate: { - request: { - query: buildRouteValidation(indexStatusRequestQuery), - }, - }, - version: '1', - }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const coreContext = await context.core; - const { indexName, entity } = request.query; - try { - const newFieldName = `${entity}.risk.calculated_level`; - const res = await coreContext.elasticsearch.client.asCurrentUser.fieldCaps({ - index: indexName, - fields: newFieldName, - ignore_unavailable: true, - allow_no_indices: false, - }); - const isDeprecated = !Object.keys(res.fields).includes(newFieldName); - - return response.ok({ - body: { isDeprecated, isEnabled: true }, - }); - } catch (err) { - const error = transformError(err); - if (error.statusCode === 404) { - // index does not exist, therefore cannot be deprecated - return response.ok({ - body: { isDeprecated: false, isEnabled: false }, - }); - } - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.test.ts deleted file mode 100644 index bdc97de6cee17..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.test.ts +++ /dev/null @@ -1,84 +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. - */ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { Logger } from '@kbn/core/server'; -import { - serverMock, - requestContextMock, - requestMock, -} from '../../detection_engine/routes/__mocks__'; -import { createEsIndexRoute } from './create_index_route'; -import { RISK_SCORE_CREATE_INDEX } from '../../../../common/constants'; -import { createIndex } from './lib/create_index'; -import { transformError } from '@kbn/securitysolution-es-utils'; -const testIndex = 'test-index'; - -jest.mock('./lib/create_index', () => { - const actualModule = jest.requireActual('./lib/create_index'); - return { - ...actualModule, - createIndex: jest.fn().mockResolvedValue({ [testIndex]: { success: true, error: null } }), - }; -}); - -describe('createEsIndexRoute', () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - const logger = { error: jest.fn() } as unknown as Logger; - beforeEach(() => { - jest.clearAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - - createEsIndexRoute(server.router, logger); - }); - - it('create index', async () => { - const request = requestMock.create({ - method: 'put', - path: RISK_SCORE_CREATE_INDEX, - body: { index: testIndex, mappings: {} }, - }); - - const response = await server.inject(request, requestContextMock.convertContext(context)); - expect(createIndex).toHaveBeenCalled(); - expect(response.status).toEqual(200); - }); - - it('Create index - should validate input', async () => { - const invalidRequest = requestMock.create({ - method: 'put', - path: RISK_SCORE_CREATE_INDEX, - }); - await server.inject(invalidRequest, requestContextMock.convertContext(context)); - const result = server.validate(invalidRequest); - - expect(result.ok).not.toHaveBeenCalled(); - }); - - it('return error if failed to create index', async () => { - (createIndex as jest.Mock).mockResolvedValue({ - [testIndex]: { success: false, error: transformError(new Error('unknown error')) }, - }); - const request = requestMock.create({ - method: 'put', - path: RISK_SCORE_CREATE_INDEX, - body: { index: testIndex, mappings: {} }, - }); - - const response = await server.inject(request, requestContextMock.convertContext(context)); - expect(createIndex).toHaveBeenCalled(); - expect(response.status).toEqual(500); - expect(response.body).toEqual({ message: 'unknown error', status_code: 500 }); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts deleted file mode 100644 index d029d098b03bf..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; -import type { Logger } from '@kbn/core/server'; - -import { transformError } from '@kbn/securitysolution-es-utils'; -import { RISK_SCORE_CREATE_INDEX } from '../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../types'; -import { createIndex } from './lib/create_index'; -import { createEsIndexRequestBody } from '../../../../common/api/entity_analytics/risk_score'; - -export const createEsIndexRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { - router.versioned - .put({ - access: 'internal', - path: RISK_SCORE_CREATE_INDEX, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { - validate: { - request: { body: createEsIndexRequestBody }, - }, - version: '1', - }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { client } = (await context.core).elasticsearch; - const esClient = client.asCurrentUser; - const options = request.body; - - try { - const result = await createIndex({ - esClient, - logger, - options, - }); - const error = result[options.index].error; - - if (error != null) { - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } else { - return response.ok({ body: options }); - } - } catch (e) { - const error = transformError(e); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.test.ts deleted file mode 100644 index 701fa8286b073..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.test.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 { - serverMock, - requestContextMock, - requestMock, -} from '../../detection_engine/routes/__mocks__'; -import { deleteEsIndicesRoute } from './delete_indices_route'; -import { RISK_SCORE_DELETE_INDICES } from '../../../../common/constants'; -import { deleteEsIndices } from './lib/delete_indices'; - -jest.mock('./lib/delete_indices', () => { - const actualModule = jest.requireActual('./lib/delete_indices'); - return { - ...actualModule, - deleteEsIndices: jest.fn(), - }; -}); - -describe('deleteEsIndicesRoute', () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - - beforeEach(() => { - jest.resetModules(); - jest.resetAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - - deleteEsIndicesRoute(server.router); - }); - - it('delete indices', async () => { - const request = requestMock.create({ - method: 'post', - path: RISK_SCORE_DELETE_INDICES, - body: ['test'], - }); - const response = await server.inject(request, requestContextMock.convertContext(context)); - expect(deleteEsIndices).toHaveBeenCalled(); - expect(response.status).toEqual(200); - }); - - it('delete indices - should validate input', async () => { - const invalidRequest = requestMock.create({ - method: 'post', - path: RISK_SCORE_DELETE_INDICES, - }); - await server.inject(invalidRequest, requestContextMock.convertContext(context)); - const result = server.validate(invalidRequest); - - expect(result.ok).not.toHaveBeenCalled(); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts deleted file mode 100644 index 4e7f8ed0975f1..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { transformError } from '@kbn/securitysolution-es-utils'; -import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; - -import { RISK_SCORE_DELETE_INDICES } from '../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../types'; -import { deleteEsIndices } from './lib/delete_indices'; -import { deleteIndicesRequestBody } from '../../../../common/api/entity_analytics/risk_score'; - -export const deleteEsIndicesRoute = (router: SecuritySolutionPluginRouter) => { - router.versioned - .post({ - access: 'internal', - path: RISK_SCORE_DELETE_INDICES, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { validate: { request: { body: deleteIndicesRequestBody } }, version: '1' }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - - const { client } = (await context.core).elasticsearch; - const { indices } = request.body; - - try { - await deleteEsIndices({ client, indices }); - return response.ok({ body: { deleted: indices } }); - } catch (err) { - const error = transformError(err); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/index.ts deleted file mode 100644 index 77f0aff32543f..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/index.ts +++ /dev/null @@ -1,9 +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. - */ - -export * from './delete_indices_route'; -export * from './create_index_route'; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts deleted file mode 100644 index 4104c97812e0a..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { CreateEsIndexRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -export const createIndex = async ({ - esClient, - logger, - options, -}: { - esClient: ElasticsearchClient; - logger: Logger; - options: CreateEsIndexRequestBody; -}) => { - try { - await esClient.indices.create({ - index: options.index, - mappings: - typeof options.mappings === 'string' ? JSON.parse(options.mappings) : options.mappings, - }); - return { [options.index]: { success: true, error: null } }; - } catch (err) { - const error = transformError(err); - logger.error(`Failed to create index: ${options.index}: ${error.message}`); - - return { [options.index]: { success: false, error } }; - } -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/delete_indices.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/delete_indices.ts deleted file mode 100644 index c60b5c3fb7fe7..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/delete_indices.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 { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; - -export const deleteEsIndices = async ({ - client, - indices, -}: { - client: IScopedClusterClient; - indices: string[]; -}) => { - const params = { - expand_wildcards: 'none' as const, - format: 'json', - index: indices, - }; - await client.asCurrentUser.indices.delete(params); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/ingest_pipeline.ts b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/ingest_pipeline.ts deleted file mode 100644 index 4b4158aa3af01..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/ingest_pipeline.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; -import type { Pipeline } from '../../../../../common/types/risk_scores'; - -export const createIngestPipeline = async ({ - esClient, - logger, - options, -}: { - esClient: ElasticsearchClient; - logger: Logger; - options: Pipeline; -}) => { - const processors = - typeof options.processors === 'string' ? JSON.parse(options.processors) : options.processors; - // eslint-disable-next-line @typescript-eslint/naming-convention - const { name, description, version, on_failure } = options; - - try { - await esClient.ingest.putPipeline({ - id: name, - body: { - description, - processors, - version, - on_failure, - }, - }); - - return { [name]: { success: true, error: null } }; - } catch (err) { - const error = transformError(err); - logger.error(`Failed to create ingest pipeline: ${name}: ${error.message}`); - - return { [name]: { success: false, error } }; - } -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/install_risk_score_module.ts b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/install_risk_score_module.ts deleted file mode 100644 index 1b4a8c583b8b5..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/helpers/install_risk_score_module.ts +++ /dev/null @@ -1,313 +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 { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { - getCreateLatestTransformOptions, - getCreateMLHostPivotTransformOptions, - getCreateMLUserPivotTransformOptions, - getCreateRiskScoreIndicesOptions, - getCreateRiskScoreLatestIndicesOptions, - getRiskHostCreateInitScriptOptions, - getRiskHostCreateLevelScriptOptions, - getRiskHostCreateMapScriptOptions, - getRiskHostCreateReduceScriptOptions, - getRiskScoreIngestPipelineOptions, - getRiskScoreLatestTransformId, - getRiskScorePivotTransformId, - getRiskUserCreateLevelScriptOptions, - getRiskUserCreateMapScriptOptions, - getRiskUserCreateReduceScriptOptions, -} from '../../../../../common/utils/risk_score_modules'; -import { createIndex } from '../../indices/lib/create_index'; -import { createStoredScript } from '../../stored_scripts/lib/create_script'; -import { createAndStartTransform } from '../../transform/helpers/transforms'; -import { createIngestPipeline } from './ingest_pipeline'; - -interface InstallRiskScoreModule { - esClient: ElasticsearchClient; - logger: Logger; - riskScoreEntity: RiskScoreEntity; - spaceId: string; -} - -const createHostRiskScoreIngestPipelineGrouping = ({ - esClient, - logger, - riskScoreEntity, - spaceId, -}: InstallRiskScoreModule) => { - /** - * console_templates/enable_host_risk_score.console - * Step 1 Upload script: ml_hostriskscore_levels_script_{spaceId} - */ - const createLevelScriptOptions = getRiskHostCreateLevelScriptOptions(spaceId); - - return createStoredScript({ - esClient, - logger, - options: createLevelScriptOptions, - }).then((createStoredScriptResult) => { - if (createStoredScriptResult[createLevelScriptOptions.id].success) { - /** - * console_templates/enable_host_risk_score.console - * Step 5 Upload the ingest pipeline: ml_hostriskscore_ingest_pipeline_{spaceId} - */ - const createIngestPipelineOptions = getRiskScoreIngestPipelineOptions( - riskScoreEntity, - spaceId - ); - return createIngestPipeline({ - esClient, - logger, - options: createIngestPipelineOptions, - }).then((createIngestPipelineResult) => { - return [createStoredScriptResult, createIngestPipelineResult]; - }); - } else { - return [createStoredScriptResult]; - } - }); -}; - -const installHostRiskScoreModule = async ({ - esClient, - riskScoreEntity, - logger, - spaceId, -}: InstallRiskScoreModule) => { - const result = await Promise.all([ - /** - * console_templates/enable_host_risk_score.console - * Step 1 Upload script: ml_hostriskscore_levels_script_{spaceId} - * Step 5 Upload the ingest pipeline: ml_hostriskscore_ingest_pipeline_{spaceId} - */ - createHostRiskScoreIngestPipelineGrouping({ - esClient, - logger, - riskScoreEntity, - spaceId, - }), - /** - * console_templates/enable_host_risk_score.console - * Step 2 Upload script: ml_hostriskscore_init_script_{spaceId} - */ - createStoredScript({ - esClient, - logger, - options: getRiskHostCreateInitScriptOptions(spaceId), - }), - - /** - * console_templates/enable_host_risk_score.console - * Step 3 Upload script: ml_hostriskscore_map_script_{spaceId} - */ - createStoredScript({ - esClient, - logger, - options: getRiskHostCreateMapScriptOptions(spaceId), - }), - - /** - * console_templates/enable_host_risk_score.console - * Step 4 Upload script: ml_hostriskscore_reduce_script_{spaceId} - */ - createStoredScript({ - esClient, - logger, - options: getRiskHostCreateReduceScriptOptions(spaceId), - }), - - /** - * console_templates/enable_host_risk_score.console - * Step 6 create ml_host_risk_score_{spaceId} index - */ - createIndex({ - esClient, - logger, - options: getCreateRiskScoreIndicesOptions({ - spaceId, - riskScoreEntity, - }), - }), - - /** - * console_templates/enable_host_risk_score.console - * Step 9 create ml_host_risk_score_latest_{spaceId} index - */ - createIndex({ - esClient, - logger, - options: getCreateRiskScoreLatestIndicesOptions({ - spaceId, - riskScoreEntity, - }), - }), - ]); - - /** - * console_templates/enable_host_risk_score.console - * Step 7 create transform: ml_hostriskscore_pivot_transform_{spaceId} - * Step 8 Start the pivot transform - */ - const createAndStartPivotTransformResult = await createAndStartTransform({ - esClient, - logger, - transformId: getRiskScorePivotTransformId(riskScoreEntity, spaceId), - options: getCreateMLHostPivotTransformOptions({ spaceId }), - }); - - /** - * console_templates/enable_host_risk_score.console - * Step 10 create transform: ml_hostriskscore_latest_transform_{spaceId} - * Step 11 Start the latest transform - */ - const createAndStartLatestTransformResult = await createAndStartTransform({ - esClient, - logger, - transformId: getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - options: getCreateLatestTransformOptions({ riskScoreEntity, spaceId }), - }); - - return [ - ...result, - createAndStartPivotTransformResult, - createAndStartLatestTransformResult, - ].flat(); -}; - -const createUserRiskScoreIngestPipelineGrouping = async ({ - esClient, - logger, - riskScoreEntity, - spaceId, -}: InstallRiskScoreModule) => { - /** - * console_templates/enable_user_risk_score.console - * Step 1 Upload script: ml_userriskscore_levels_script_{spaceId} - */ - const createLevelScriptOptions = getRiskUserCreateLevelScriptOptions(spaceId); - - const createStoredScriptResult = await createStoredScript({ - esClient, - logger, - options: createLevelScriptOptions, - }); - - /** - * console_templates/enable_user_risk_score.console - * Step 4 Upload ingest pipeline: ml_userriskscore_ingest_pipeline_{spaceId} - */ - const createIngestPipelineOptions = getRiskScoreIngestPipelineOptions(riskScoreEntity, spaceId); - const createIngestPipelineResult = await createIngestPipeline({ - esClient, - logger, - options: createIngestPipelineOptions, - }); - - return [createStoredScriptResult, createIngestPipelineResult]; -}; - -const installUserRiskScoreModule = async ({ - esClient, - logger, - riskScoreEntity, - spaceId, -}: InstallRiskScoreModule) => { - const result = await Promise.all([ - /** - * console_templates/enable_user_risk_score.console - * Step 1 Upload script: ml_userriskscore_levels_script_{spaceId} - * Step 4 Upload ingest pipeline: ml_userriskscore_ingest_pipeline_{spaceId} - */ - createUserRiskScoreIngestPipelineGrouping({ esClient, logger, riskScoreEntity, spaceId }), - /** - * console_templates/enable_user_risk_score.console - * Step 2 Upload script: ml_userriskscore_map_script_{spaceId} - */ - createStoredScript({ - esClient, - logger, - options: getRiskUserCreateMapScriptOptions(spaceId), - }), - - /** - * console_templates/enable_user_risk_score.console - * Step 3 Upload script: ml_userriskscore_reduce_script_{spaceId} - */ - createStoredScript({ - esClient, - logger, - options: getRiskUserCreateReduceScriptOptions(spaceId), - }), - - /** - * console_templates/enable_user_risk_score.console - * Step 5 create ml_user_risk_score_{spaceId} index - */ - createIndex({ - esClient, - logger, - options: getCreateRiskScoreIndicesOptions({ - spaceId, - riskScoreEntity, - }), - }), - /** - * console_templates/enable_user_risk_score.console - * Step 8 create ml_user_risk_score_latest_{spaceId} index - */ - createIndex({ - esClient, - logger, - options: getCreateRiskScoreLatestIndicesOptions({ - spaceId, - riskScoreEntity, - }), - }), - ]); - - /** - * console_templates/enable_user_risk_score.console - * Step 6 create Transform: ml_userriskscore_pivot_transform_{spaceId} - * Step 7 Start the pivot transform - */ - const createAndStartPivotTransformResult = await createAndStartTransform({ - esClient, - logger, - transformId: getRiskScorePivotTransformId(riskScoreEntity, spaceId), - options: getCreateMLUserPivotTransformOptions({ spaceId }), - }); - - /** - * console_templates/enable_user_risk_score.console - * Step 9 create Transform: ml_userriskscore_latest_transform_{spaceId} - * Step 10 Start the latest transform - */ - const createAndStartLatestTransformResult = await createAndStartTransform({ - esClient, - logger, - transformId: getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - options: getCreateLatestTransformOptions({ riskScoreEntity, spaceId }), - }); - - return [ - ...result, - createAndStartPivotTransformResult, - createAndStartLatestTransformResult, - ].flat(); -}; - -export const installRiskScoreModule = async (settings: InstallRiskScoreModule) => { - if (settings.riskScoreEntity === RiskScoreEntity.user) { - const result = await installUserRiskScoreModule(settings); - return result; - } else { - const result = await installHostRiskScoreModule(settings); - return result; - } -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/__snapshots__/install_risk_scores.test.ts.snap b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/__snapshots__/install_risk_scores.test.ts.snap deleted file mode 100644 index 523cc405eb294..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/__snapshots__/install_risk_scores.test.ts.snap +++ /dev/null @@ -1,736 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`installRiskScoresRoute - host Create Index: ml_host_risk_score_latest_mockSpaceId 1`] = ` -Object { - "index": "ml_host_risk_score_latest_default", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "host": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - "ingest_timestamp": Object { - "type": "date", - }, - }, - }, -} -`; - -exports[`installRiskScoresRoute - host Create Index: ml_host_risk_score_mockSpaceId 1`] = ` -Object { - "index": "ml_host_risk_score_default", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "host": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - "ingest_timestamp": Object { - "type": "date", - }, - }, - }, -} -`; - -exports[`installRiskScoresRoute - host Create IngestPipeline: ml_hostriskscore_ingest_pipeline_mockSpaceId 1`] = ` -Object { - "name": "ml_hostriskscore_ingest_pipeline_default", - "processors": Array [ - Object { - "set": Object { - "field": "ingest_timestamp", - "value": "{{_ingest.timestamp}}", - }, - }, - Object { - "fingerprint": Object { - "fields": Array [ - "@timestamp", - "_id", - ], - "method": "SHA-256", - "target_field": "_id", - }, - }, - Object { - "script": Object { - "id": "ml_hostriskscore_levels_script_default", - "params": Object { - "risk_score": "host.risk.calculated_score_norm", - }, - }, - }, - ], -} -`; - -exports[`installRiskScoresRoute - host Create and start Transform: ml_hostriskscore_latest_transform_mockSpaceId 1`] = ` -Object { - "dest": Object { - "index": "ml_host_risk_score_latest_default", - }, - "frequency": "1h", - "latest": Object { - "sort": "@timestamp", - "unique_key": Array [ - "host.name", - ], - }, - "source": Object { - "index": Array [ - "ml_host_risk_score_default", - ], - }, - "sync": Object { - "time": Object { - "delay": "2s", - "field": "ingest_timestamp", - }, - }, -} -`; - -exports[`installRiskScoresRoute - host Create and start Transform: ml_hostriskscore_pivot_transform_mockSpaceId 1`] = ` -Object { - "dest": Object { - "index": "ml_host_risk_score_default", - "pipeline": "ml_hostriskscore_ingest_pipeline_default", - }, - "frequency": "1h", - "pivot": Object { - "aggregations": Object { - "@timestamp": Object { - "max": Object { - "field": "@timestamp", - }, - }, - "host.risk": Object { - "scripted_metric": Object { - "combine_script": "return state", - "init_script": Object { - "id": "ml_hostriskscore_init_script_default", - }, - "map_script": Object { - "id": "ml_hostriskscore_map_script_default", - }, - "params": Object { - "lookback_time": 72, - "max_risk": 100, - "p": 1.5, - "server_multiplier": 1.5, - "tactic_base_multiplier": 0.25, - "tactic_weights": Object { - "TA0001": 1, - "TA0002": 2, - "TA0003": 3, - "TA0004": 4, - "TA0005": 4, - "TA0006": 4, - "TA0007": 4, - "TA0008": 5, - "TA0009": 6, - "TA0010": 7, - "TA0011": 6, - "TA0040": 8, - "TA0042": 1, - "TA0043": 1, - }, - "time_decay_constant": 6, - "zeta_constant": 2.612, - }, - "reduce_script": Object { - "id": "ml_hostriskscore_reduce_script_default", - }, - }, - }, - }, - "group_by": Object { - "host.name": Object { - "terms": Object { - "field": "host.name", - }, - }, - }, - }, - "source": Object { - "index": Array [ - ".alerts-security.alerts-default", - ], - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "range": Object { - "@timestamp": Object { - "gte": "now-5d", - }, - }, - }, - ], - }, - }, - }, - "sync": Object { - "time": Object { - "delay": "120s", - "field": "@timestamp", - }, - }, -} -`; - -exports[`installRiskScoresRoute - host Create script: ml_hostriskscore_init_script_mockSpaceId 1`] = ` -Object { - "id": "ml_hostriskscore_init_script_default", - "script": Object { - "lang": "painless", - "source": "state.rule_risk_stats = new HashMap(); -state.host_variant_set = false; -state.host_variant = new String(); -state.tactic_ids = new HashSet();", - }, -} -`; - -exports[`installRiskScoresRoute - host Create script: ml_hostriskscore_levels_script_mockSpaceId 1`] = ` -Object { - "id": "ml_hostriskscore_levels_script_default", - "script": Object { - "lang": "painless", - "source": "double risk_score = (def)ctx.getByPath(params.risk_score); -if (risk_score < 20) { - ctx['host']['risk']['calculated_level'] = 'Unknown' -} -else if (risk_score >= 20 && risk_score < 40) { - ctx['host']['risk']['calculated_level'] = 'Low' -} -else if (risk_score >= 40 && risk_score < 70) { - ctx['host']['risk']['calculated_level'] = 'Moderate' -} -else if (risk_score >= 70 && risk_score < 90) { - ctx['host']['risk']['calculated_level'] = 'High' -} -else if (risk_score >= 90) { - ctx['host']['risk']['calculated_level'] = 'Critical' -}", - }, -} -`; - -exports[`installRiskScoresRoute - host Create script: ml_hostriskscore_map_script_mockSpaceId 1`] = ` -Object { - "id": "ml_hostriskscore_map_script_default", - "script": Object { - "lang": "painless", - "source": "// Get the host variant -if (state.host_variant_set == false) { - if (doc.containsKey(\\"host.os.full\\") && doc[\\"host.os.full\\"].size() != 0) { - state.host_variant = doc[\\"host.os.full\\"].value; - state.host_variant_set = true; - } -} -// Aggregate all the tactics seen on the host -if (doc.containsKey(\\"signal.rule.threat.tactic.id\\") && doc[\\"signal.rule.threat.tactic.id\\"].size() != 0) { - state.tactic_ids.add(doc[\\"signal.rule.threat.tactic.id\\"].value); -} -// Get running sum of time-decayed risk score per rule name per shard -String rule_name = doc[\\"signal.rule.name\\"].value; -def stats = state.rule_risk_stats.getOrDefault(rule_name, [0.0,\\"\\",false]); -int time_diff = (int)((System.currentTimeMillis() - doc[\\"@timestamp\\"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0)); -double risk_derate = Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant)); -stats[0] = Math.max(stats[0], doc[\\"signal.rule.risk_score\\"].value * risk_derate); -if (stats[2] == false) { - stats[1] = doc[\\"kibana.alert.rule.uuid\\"].value; - stats[2] = true; -} -state.rule_risk_stats.put(rule_name, stats);", - }, -} -`; - -exports[`installRiskScoresRoute - host Create script: ml_hostriskscore_reduce_script_mockSpaceId 1`] = ` -Object { - "id": "ml_hostriskscore_reduce_script_default", - "script": Object { - "lang": "painless", - "source": "// Consolidating time decayed risks and tactics from across all shards -Map total_risk_stats = new HashMap(); -String host_variant = new String(); -def tactic_ids = new HashSet(); -for (state in states) { - for (key in state.rule_risk_stats.keySet()) { - def rule_stats = state.rule_risk_stats.get(key); - def stats = total_risk_stats.getOrDefault(key, [0.0,\\"\\",false]); - stats[0] = Math.max(stats[0], rule_stats[0]); - if (stats[2] == false) { - stats[1] = rule_stats[1]; - stats[2] = true; - } - total_risk_stats.put(key, stats); - } - if (host_variant.length() == 0) { - host_variant = state.host_variant; - } - tactic_ids.addAll(state.tactic_ids); -} -// Consolidating individual rule risks and arranging them in decreasing order -List risks = new ArrayList(); -for (key in total_risk_stats.keySet()) { - risks.add(total_risk_stats[key][0]) -} -Collections.sort(risks, Collections.reverseOrder()); -// Calculating total host risk score -double total_risk = 0.0; -double risk_cap = params.max_risk * params.zeta_constant; -for (int i=0;i= 40 && total_norm_risk < 50) { - total_norm_risk = 85 + (total_norm_risk - 40); -} -else { - total_norm_risk = 95 + (total_norm_risk - 50) / 10; -} -// Calculating multipliers to the host risk score -double risk_multiplier = 1.0; -List multipliers = new ArrayList(); -// Add a multiplier if host is a server -if (host_variant.toLowerCase().contains(\\"server\\")) { - risk_multiplier *= params.server_multiplier; - multipliers.add(\\"Host is a server\\"); -} -// Add multipliers based on number and diversity of tactics seen on the host -for (String tactic : tactic_ids) { - multipliers.add(\\"Tactic \\"+tactic); - risk_multiplier *= 1 + params.tactic_base_multiplier * params.tactic_weights.getOrDefault(tactic, 0); -} -// Calculating final risk -double final_risk = total_norm_risk; -if (risk_multiplier > 1.0) { - double prior_odds = (total_norm_risk) / (100 - total_norm_risk); - double updated_odds = prior_odds * risk_multiplier; - final_risk = 100 * updated_odds / (1 + updated_odds); -} -// Adding additional metadata -List rule_stats = new ArrayList(); -for (key in total_risk_stats.keySet()) { - Map temp = new HashMap(); - temp[\\"rule_name\\"] = key; - temp[\\"rule_risk\\"] = total_risk_stats[key][0]; - temp[\\"rule_id\\"] = total_risk_stats[key][1]; - rule_stats.add(temp); -} - -return [\\"calculated_score_norm\\": final_risk, \\"rule_risks\\": rule_stats, \\"multipliers\\": multipliers];", - }, -} -`; - -exports[`installRiskScoresRoute - user Create Index: ml_user_risk_score_latest_mockSpaceId 1`] = ` -Object { - "index": "ml_user_risk_score_latest_default", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "ingest_timestamp": Object { - "type": "date", - }, - "user": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - }, - }, -} -`; - -exports[`installRiskScoresRoute - user Create Index: ml_user_risk_score_mockSpaceId 1`] = ` -Object { - "index": "ml_user_risk_score_default", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "ingest_timestamp": Object { - "type": "date", - }, - "user": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - }, - }, -} -`; - -exports[`installRiskScoresRoute - user Create IngestPipeline: ml_userriskscore_ingest_pipeline_mockSpaceId 1`] = ` -Object { - "name": "ml_userriskscore_ingest_pipeline_default", - "processors": Array [ - Object { - "set": Object { - "field": "ingest_timestamp", - "value": "{{_ingest.timestamp}}", - }, - }, - Object { - "fingerprint": Object { - "fields": Array [ - "@timestamp", - "_id", - ], - "method": "SHA-256", - "target_field": "_id", - }, - }, - Object { - "script": Object { - "id": "ml_userriskscore_levels_script_default", - "params": Object { - "risk_score": "user.risk.calculated_score_norm", - }, - }, - }, - ], -} -`; - -exports[`installRiskScoresRoute - user Create Transform: ml_userriskscore_latest_transform_mockSpaceId 1`] = ` -Object { - "dest": Object { - "index": "ml_user_risk_score_latest_default", - }, - "frequency": "1h", - "latest": Object { - "sort": "@timestamp", - "unique_key": Array [ - "user.name", - ], - }, - "source": Object { - "index": Array [ - "ml_user_risk_score_default", - ], - }, - "sync": Object { - "time": Object { - "delay": "2s", - "field": "ingest_timestamp", - }, - }, -} -`; - -exports[`installRiskScoresRoute - user Create Transform: ml_userriskscore_pivot_transform_mockSpaceId 1`] = ` -Object { - "dest": Object { - "index": "ml_user_risk_score_default", - "pipeline": "ml_userriskscore_ingest_pipeline_default", - }, - "frequency": "1h", - "pivot": Object { - "aggregations": Object { - "@timestamp": Object { - "max": Object { - "field": "@timestamp", - }, - }, - "user.risk": Object { - "scripted_metric": Object { - "combine_script": "return state", - "init_script": "state.rule_risk_stats = new HashMap();", - "map_script": Object { - "id": "ml_userriskscore_map_script_default", - }, - "params": Object { - "max_risk": 100, - "p": 1.5, - "zeta_constant": 2.612, - }, - "reduce_script": Object { - "id": "ml_userriskscore_reduce_script_default", - }, - }, - }, - }, - "group_by": Object { - "user.name": Object { - "terms": Object { - "field": "user.name", - }, - }, - }, - }, - "source": Object { - "index": Array [ - ".alerts-security.alerts-default", - ], - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "range": Object { - "@timestamp": Object { - "gte": "now-90d", - }, - }, - }, - Object { - "match": Object { - "signal.status": "open", - }, - }, - ], - }, - }, - }, - "sync": Object { - "time": Object { - "delay": "120s", - "field": "@timestamp", - }, - }, -} -`; - -exports[`installRiskScoresRoute - user Create script: ml_userriskscore_levels_script_mockSpaceId 1`] = ` -Object { - "id": "ml_userriskscore_levels_script_default", - "script": Object { - "lang": "painless", - "source": "double risk_score = (def)ctx.getByPath(params.risk_score); -if (risk_score < 20) { - ctx['user']['risk']['calculated_level'] = 'Unknown' -} -else if (risk_score >= 20 && risk_score < 40) { - ctx['user']['risk']['calculated_level'] = 'Low' -} -else if (risk_score >= 40 && risk_score < 70) { - ctx['user']['risk']['calculated_level'] = 'Moderate' -} -else if (risk_score >= 70 && risk_score < 90) { - ctx['user']['risk']['calculated_level'] = 'High' -} -else if (risk_score >= 90) { - ctx['user']['risk']['calculated_level'] = 'Critical' -}", - }, -} -`; - -exports[`installRiskScoresRoute - user Create script: ml_userriskscore_map_script_mockSpaceId 1`] = ` -Object { - "id": "ml_userriskscore_map_script_default", - "script": Object { - "lang": "painless", - "source": "// Get running sum of risk score per rule name per shard\\\\\\\\ -String rule_name = doc[\\"signal.rule.name\\"].value; -def stats = state.rule_risk_stats.getOrDefault(rule_name, 0.0); -stats = doc[\\"signal.rule.risk_score\\"].value; -state.rule_risk_stats.put(rule_name, stats);", - }, -} -`; - -exports[`installRiskScoresRoute - user Create script: ml_userriskscore_reduce_script_mockSpaceId 1`] = ` -Object { - "id": "ml_userriskscore_reduce_script_default", - "script": Object { - "lang": "painless", - "source": "// Consolidating time decayed risks from across all shards -Map total_risk_stats = new HashMap(); -for (state in states) { - for (key in state.rule_risk_stats.keySet()) { - def rule_stats = state.rule_risk_stats.get(key); - def stats = total_risk_stats.getOrDefault(key, 0.0); - stats = rule_stats; - total_risk_stats.put(key, stats); - } -} -// Consolidating individual rule risks and arranging them in decreasing order -List risks = new ArrayList(); -for (key in total_risk_stats.keySet()) { - risks.add(total_risk_stats[key]) -} -Collections.sort(risks, Collections.reverseOrder()); -// Calculating total risk and normalizing it to a range -double total_risk = 0.0; -double risk_cap = params.max_risk * params.zeta_constant; -for (int i=0;i= 40 && total_norm_risk < 50) { - total_norm_risk = 85 + (total_norm_risk - 40); -} -else { - total_norm_risk = 95 + (total_norm_risk - 50) / 10; -} - -List rule_stats = new ArrayList(); -for (key in total_risk_stats.keySet()) { - Map temp = new HashMap(); - temp[\\"rule_name\\"] = key; - temp[\\"rule_risk\\"] = total_risk_stats[key]; - rule_stats.add(temp); -} - -return [\\"calculated_score_norm\\": total_norm_risk, \\"rule_risks\\": rule_stats];", - }, -} -`; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.test.ts deleted file mode 100644 index 114d51bfae6a4..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.test.ts +++ /dev/null @@ -1,176 +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 { Logger } from '@kbn/core/server'; -import { - serverMock, - requestContextMock, - requestMock, -} from '../../../detection_engine/routes/__mocks__'; -import { INTERNAL_RISK_SCORE_URL } from '../../../../../common/constants'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { installRiskScoresRoute } from './install_risk_scores'; -import { createIngestPipeline } from '../helpers/ingest_pipeline'; -import { createStoredScript } from '../../stored_scripts/lib/create_script'; -import { createIndex } from '../../indices/lib/create_index'; -import { createAndStartTransform } from '../../transform/helpers/transforms'; - -jest.mock('../../stored_scripts/lib/create_script', () => ({ - createStoredScript: jest - .fn() - .mockImplementation(({ options }) => - Promise.resolve({ [options.id]: { success: true, error: null } }) - ), -})); - -jest.mock('../helpers/ingest_pipeline', () => ({ - createIngestPipeline: jest - .fn() - .mockImplementation(({ options }) => - Promise.resolve({ [options.name]: { success: true, error: null } }) - ), -})); - -jest.mock('../../indices/lib/create_index', () => ({ - createIndex: jest - .fn() - .mockImplementation(({ options }) => - Promise.resolve({ [options.index]: { success: true, error: null } }) - ), -})); - -jest.mock('../../transform/helpers/transforms', () => ({ - createAndStartTransform: jest - .fn() - .mockImplementation(({ transformId }) => - Promise.resolve({ [transformId]: { success: true, error: null } }) - ), -})); - -describe(`installRiskScoresRoute - ${RiskScoreEntity.host}`, () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - const logger = { error: jest.fn() } as unknown as Logger; - const mockSpaceId = 'mockSpaceId'; - - beforeAll(async () => { - jest.clearAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - const request = requestMock.create({ - method: 'post', - path: INTERNAL_RISK_SCORE_URL, - body: { - riskScoreEntity: RiskScoreEntity.host, - }, - }); - - installRiskScoresRoute(server.router, logger); - await server.inject(request, requestContextMock.convertContext(context)); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - it(`Create script: ml_${RiskScoreEntity.host}riskscore_levels_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create IngestPipeline: ml_${RiskScoreEntity.host}riskscore_ingest_pipeline_${mockSpaceId}`, async () => { - expect((createIngestPipeline as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create script: ml_${RiskScoreEntity.host}riskscore_init_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[1][0].options).toMatchSnapshot(); - }); - - it(`Create script: ml_${RiskScoreEntity.host}riskscore_map_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[2][0].options).toMatchSnapshot(); - }); - - it(`Create script: ml_${RiskScoreEntity.host}riskscore_reduce_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[3][0].options).toMatchSnapshot(); - }); - - it(`Create Index: ml_${RiskScoreEntity.host}_risk_score_${mockSpaceId}`, async () => { - expect((createIndex as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create Index: ml_${RiskScoreEntity.host}_risk_score_latest_${mockSpaceId}`, async () => { - expect((createIndex as jest.Mock).mock.calls[1][0].options).toMatchSnapshot(); - }); - - it(`Create and start Transform: ml_${RiskScoreEntity.host}riskscore_pivot_transform_${mockSpaceId}`, async () => { - expect((createAndStartTransform as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create and start Transform: ml_${RiskScoreEntity.host}riskscore_latest_transform_${mockSpaceId}`, async () => { - expect((createAndStartTransform as jest.Mock).mock.calls[1][0].options).toMatchSnapshot(); - }); -}); - -describe(`installRiskScoresRoute - ${RiskScoreEntity.user}`, () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - const logger = { error: jest.fn() } as unknown as Logger; - const mockSpaceId = 'mockSpaceId'; - - beforeAll(async () => { - jest.clearAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - const request = requestMock.create({ - method: 'post', - path: INTERNAL_RISK_SCORE_URL, - body: { - riskScoreEntity: RiskScoreEntity.user, - }, - }); - - installRiskScoresRoute(server.router, logger); - await server.inject(request, requestContextMock.convertContext(context)); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - it(`Create script: ml_${RiskScoreEntity.user}riskscore_levels_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create IngestPipeline: ml_${RiskScoreEntity.user}riskscore_ingest_pipeline_${mockSpaceId}`, async () => { - expect((createIngestPipeline as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create script: ml_${RiskScoreEntity.user}riskscore_map_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[1][0].options).toMatchSnapshot(); - }); - - it(`Create script: ml_${RiskScoreEntity.user}riskscore_reduce_script_${mockSpaceId}`, async () => { - expect((createStoredScript as jest.Mock).mock.calls[2][0].options).toMatchSnapshot(); - }); - - it(`Create Index: ml_${RiskScoreEntity.user}_risk_score_${mockSpaceId}`, async () => { - expect((createIndex as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create Index: ml_${RiskScoreEntity.user}_risk_score_latest_${mockSpaceId}`, async () => { - expect((createIndex as jest.Mock).mock.calls[1][0].options).toMatchSnapshot(); - }); - - it(`Create Transform: ml_${RiskScoreEntity.user}riskscore_pivot_transform_${mockSpaceId}`, async () => { - expect((createAndStartTransform as jest.Mock).mock.calls[0][0].options).toMatchSnapshot(); - }); - - it(`Create Transform: ml_${RiskScoreEntity.user}riskscore_latest_transform_${mockSpaceId}`, async () => { - expect((createAndStartTransform as jest.Mock).mock.calls[1][0].options).toMatchSnapshot(); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts deleted file mode 100644 index 342ae7a0c577b..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { Logger } from '@kbn/core/server'; - -import { APP_ID, INTERNAL_RISK_SCORE_URL } from '../../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; - -import { buildSiemResponse } from '../../../detection_engine/routes/utils'; - -import { installRiskScoreModule } from '../helpers/install_risk_score_module'; -import { onboardingRiskScoreRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -export const installRiskScoresRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { - router.versioned - .post({ - access: 'internal', - path: INTERNAL_RISK_SCORE_URL, - security: { - authz: { - requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`], - }, - }, - }) - .addVersion( - { validate: { request: onboardingRiskScoreRequestBody }, version: '1' }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { riskScoreEntity } = request.body; - - try { - const securitySolution = await context.securitySolution; - - const spaceId = securitySolution?.getSpaceId(); - - const { client } = (await context.core).elasticsearch; - const esClient = client.asCurrentUser; - const res = await installRiskScoreModule({ - esClient, - logger, - riskScoreEntity, - spaceId, - }); - - return response.ok({ - body: res, - }); - } catch (err) { - const error = transformError(err); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_mappings.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_mappings.ts deleted file mode 100644 index c35c84d065a41..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_mappings.ts +++ /dev/null @@ -1,11 +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. - */ - -export const consoleMappings = { - enable_host_risk_score: 'enable_host_risk_score.mustache', - enable_user_risk_score: 'enable_user_risk_score.mustache', -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_host_risk_score.mustache b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_host_risk_score.mustache deleted file mode 100644 index 0e563d5a08821..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_host_risk_score.mustache +++ /dev/null @@ -1,86 +0,0 @@ -# Click the run button of each step to enable the module -# Upload scripts -# 1. Script to assign risk level based on risk score -PUT _scripts/{{createLevelScriptOptions.id}} -{ - "script": { - "lang": "{{createLevelScriptOptions.script.lang}}", - "source": {{createLevelScriptOptions.script.source}} - } -} - -# 2. Script to setup initial state for the Host Risk Score scripted metric aggregation -PUT _scripts/{{createInitScriptOptions.id}} -{ - "script": { - "lang": "{{createInitScriptOptions.script.lang}}", - "source": {{createInitScriptOptions.script.source}} - } -} - -# 3. Map script for the Host Risk Score transform -PUT _scripts/{{createMapScriptOptions.id}} -{ - "script": { - "lang": "{{createMapScriptOptions.script.lang}}", - "source": {{createMapScriptOptions.script.source}} - } -} - -# 4. Reduce script for the Host Risk Score transform -PUT _scripts/{{createReduceScriptOptions.id}} -{ - "script": { - "lang": "{{createReduceScriptOptions.script.lang}}", - "source": {{createReduceScriptOptions.script.source}} - } -} - -# 5. Upload the ingest pipeline -# Ingest pipeline to add ingest timestamp and risk level to documents -PUT _ingest/pipeline/{{createIngestPipelineOptions.name}} -{ - "processors": {{createIngestPipelineOptions.processors}} -} - -# 6. Create mappings for the destination index of the Host Risk Score pivot transform -PUT {{createRiskScoreIndicesOptions.index}} -{ - "mappings": {{createRiskScoreIndicesOptions.mappings}} -} - -# 7. Upload the Host Risk Score pivot transform -# This transform runs hourly and calculates a risk score and risk level for hosts in a Kibana space -PUT _transform/{{pivotTransformId}} -{{pivotTransformOptions}} - - -# 8. Start the pivot transform -POST _transform/{{pivotTransformId}}/_start - -# 9. Create mappings for the destination index of the Host Risk Score latest transform -PUT {{createRiskScoreLatestIndicesOptions.index}} -{ - "mappings": {{createRiskScoreLatestIndicesOptions.mappings}} -} - -# 10. Upload the latest transform -# This transform gets the latest risk information about hosts in a Kibana space -PUT _transform/{{latestTransformId}} -{{latestTransformOptions}} - -# 11. Start the latest transform -POST _transform/{{latestTransformId}}/_start - -# Hint: If you don't see data after running any of the transforms, stop and restart the transforms -# Stop the pivot transform -POST _transform/{{pivotTransformId}}/_stop - -# Start the pivot transform -POST _transform/{{pivotTransformId}}/_start - -# Stop the latest transform -POST _transform/{{latestTransformId}}/_stop - -# Start the latest transform -POST _transform/{{latestTransformId}}/_start diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_user_risk_score.mustache b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_user_risk_score.mustache deleted file mode 100644 index 2e6e948296aac..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/console_templates/enable_user_risk_score.mustache +++ /dev/null @@ -1,78 +0,0 @@ -# Click the run button of each step to enable the module -# Upload scripts -# 1. Script to assign risk level based on risk score -PUT _scripts/{{createLevelScriptOptions.id}} -{ - "script": { - "lang": "{{createLevelScriptOptions.script.lang}}", - "source": {{createLevelScriptOptions.script.source}} - } -} - -# 2. Map script for the User Risk Score transform -PUT _scripts/{{createMapScriptOptions.id}} -{ - "script": { - "lang": "{{createMapScriptOptions.script.lang}}", - "source": {{createMapScriptOptions.script.source}} - } -} - -# 3. Reduce script for the User Risk Score transform -PUT _scripts/{{createReduceScriptOptions.id}} -{ - "script": { - "lang": "{{createReduceScriptOptions.script.lang}}", - "source": {{createReduceScriptOptions.script.source}} - } -} - -# 4. Upload ingest pipeline -# Ingest pipeline to add ingest timestamp and risk level to documents -PUT _ingest/pipeline/{{createIngestPipelineOptions.name}} -{ - "processors": {{createIngestPipelineOptions.processors}} -} - -# 5. Create mappings for the destination index of the User Risk Score pivot transform -PUT {{createRiskScoreIndicesOptions.index}} -{ - "mappings": {{createRiskScoreIndicesOptions.mappings}} -} - -# 6. Upload the User Risk Score pivot transform -# This transform runs hourly and calculates a risk score and risk level for users in a Kibana space -PUT _transform/{{pivotTransformId}} -{{pivotTransformOptions}} - - -# 7. start the pivot transform -POST _transform/{{pivotTransformId}}/_start - -# 8. Create mappings for the destination index of the User Risk Score latest transform -PUT {{createRiskScoreLatestIndicesOptions.index}} -{ - "mappings": {{createRiskScoreLatestIndicesOptions.mappings}} -} - -# 9. Upload the latest transform -# This transform gets the latest risk information about users in a Kibana space -PUT _transform/{{latestTransformId}} -{{latestTransformOptions}} - - -# 10. Start the latest transform -POST _transform/{{latestTransformId}}/_start - -# Hint: If you don't see data after running any of the transforms, stop and restart the transforms -# Stop the pivot transform -POST _transform/{{pivotTransformId}}/_stop - -# Start the pivot transform -POST _transform/{{pivotTransformId}}/_start - -# Stop the latest transform -POST _transform/{{latestTransformId}}/_stop - -# Start the latest transform -POST _transform/{{latestTransformId}}/_start diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/__snapshots__/read_prebuilt_dev_tool_content_route.test.ts.snap b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/__snapshots__/read_prebuilt_dev_tool_content_route.test.ts.snap deleted file mode 100644 index 2b9c18fe47afd..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/__snapshots__/read_prebuilt_dev_tool_content_route.test.ts.snap +++ /dev/null @@ -1,173 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`readPrebuiltDevToolContentRoute should read content from "enable_host_risk_score" template 1`] = ` -"# Click the run button of each step to enable the module -# Upload scripts -# 1. Script to assign risk level based on risk score -PUT _scripts/ml_hostriskscore_levels_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"double risk_score = (def)ctx.getByPath(params.risk_score);\\\\nif (risk_score < 20) {\\\\n ctx['host']['risk']['calculated_level'] = 'Unknown'\\\\n}\\\\nelse if (risk_score >= 20 && risk_score < 40) {\\\\n ctx['host']['risk']['calculated_level'] = 'Low'\\\\n}\\\\nelse if (risk_score >= 40 && risk_score < 70) {\\\\n ctx['host']['risk']['calculated_level'] = 'Moderate'\\\\n}\\\\nelse if (risk_score >= 70 && risk_score < 90) {\\\\n ctx['host']['risk']['calculated_level'] = 'High'\\\\n}\\\\nelse if (risk_score >= 90) {\\\\n ctx['host']['risk']['calculated_level'] = 'Critical'\\\\n}\\" - } -} - -# 2. Script to setup initial state for the Host Risk Score scripted metric aggregation -PUT _scripts/ml_hostriskscore_init_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"state.rule_risk_stats = new HashMap();\\\\nstate.host_variant_set = false;\\\\nstate.host_variant = new String();\\\\nstate.tactic_ids = new HashSet();\\" - } -} - -# 3. Map script for the Host Risk Score transform -PUT _scripts/ml_hostriskscore_map_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"// Get the host variant\\\\nif (state.host_variant_set == false) {\\\\n if (doc.containsKey(\\\\\\"host.os.full\\\\\\") && doc[\\\\\\"host.os.full\\\\\\"].size() != 0) {\\\\n state.host_variant = doc[\\\\\\"host.os.full\\\\\\"].value;\\\\n state.host_variant_set = true;\\\\n }\\\\n}\\\\n// Aggregate all the tactics seen on the host\\\\nif (doc.containsKey(\\\\\\"signal.rule.threat.tactic.id\\\\\\") && doc[\\\\\\"signal.rule.threat.tactic.id\\\\\\"].size() != 0) {\\\\n state.tactic_ids.add(doc[\\\\\\"signal.rule.threat.tactic.id\\\\\\"].value);\\\\n}\\\\n// Get running sum of time-decayed risk score per rule name per shard\\\\nString rule_name = doc[\\\\\\"signal.rule.name\\\\\\"].value;\\\\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, [0.0,\\\\\\"\\\\\\",false]);\\\\nint time_diff = (int)((System.currentTimeMillis() - doc[\\\\\\"@timestamp\\\\\\"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0));\\\\ndouble risk_derate = Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant));\\\\nstats[0] = Math.max(stats[0], doc[\\\\\\"signal.rule.risk_score\\\\\\"].value * risk_derate);\\\\nif (stats[2] == false) {\\\\n stats[1] = doc[\\\\\\"kibana.alert.rule.uuid\\\\\\"].value;\\\\n stats[2] = true;\\\\n}\\\\nstate.rule_risk_stats.put(rule_name, stats);\\" - } -} - -# 4. Reduce script for the Host Risk Score transform -PUT _scripts/ml_hostriskscore_reduce_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"// Consolidating time decayed risks and tactics from across all shards\\\\nMap total_risk_stats = new HashMap();\\\\nString host_variant = new String();\\\\ndef tactic_ids = new HashSet();\\\\nfor (state in states) {\\\\n for (key in state.rule_risk_stats.keySet()) {\\\\n def rule_stats = state.rule_risk_stats.get(key);\\\\n def stats = total_risk_stats.getOrDefault(key, [0.0,\\\\\\"\\\\\\",false]);\\\\n stats[0] = Math.max(stats[0], rule_stats[0]);\\\\n if (stats[2] == false) {\\\\n stats[1] = rule_stats[1];\\\\n stats[2] = true;\\\\n } \\\\n total_risk_stats.put(key, stats);\\\\n }\\\\n if (host_variant.length() == 0) {\\\\n host_variant = state.host_variant;\\\\n }\\\\n tactic_ids.addAll(state.tactic_ids);\\\\n}\\\\n// Consolidating individual rule risks and arranging them in decreasing order\\\\nList risks = new ArrayList();\\\\nfor (key in total_risk_stats.keySet()) {\\\\n risks.add(total_risk_stats[key][0])\\\\n}\\\\nCollections.sort(risks, Collections.reverseOrder());\\\\n// Calculating total host risk score\\\\ndouble total_risk = 0.0;\\\\ndouble risk_cap = params.max_risk * params.zeta_constant;\\\\nfor (int i=0;i= 40 && total_norm_risk < 50) {\\\\n total_norm_risk = 85 + (total_norm_risk - 40);\\\\n}\\\\nelse {\\\\n total_norm_risk = 95 + (total_norm_risk - 50) / 10;\\\\n}\\\\n// Calculating multipliers to the host risk score\\\\ndouble risk_multiplier = 1.0;\\\\nList multipliers = new ArrayList();\\\\n// Add a multiplier if host is a server\\\\nif (host_variant.toLowerCase().contains(\\\\\\"server\\\\\\")) {\\\\n risk_multiplier *= params.server_multiplier;\\\\n multipliers.add(\\\\\\"Host is a server\\\\\\");\\\\n}\\\\n// Add multipliers based on number and diversity of tactics seen on the host\\\\nfor (String tactic : tactic_ids) {\\\\n multipliers.add(\\\\\\"Tactic \\\\\\"+tactic);\\\\n risk_multiplier *= 1 + params.tactic_base_multiplier * params.tactic_weights.getOrDefault(tactic, 0);\\\\n}\\\\n// Calculating final risk\\\\ndouble final_risk = total_norm_risk;\\\\nif (risk_multiplier > 1.0) {\\\\n double prior_odds = (total_norm_risk) / (100 - total_norm_risk);\\\\n double updated_odds = prior_odds * risk_multiplier; \\\\n final_risk = 100 * updated_odds / (1 + updated_odds);\\\\n}\\\\n// Adding additional metadata\\\\nList rule_stats = new ArrayList();\\\\nfor (key in total_risk_stats.keySet()) {\\\\n Map temp = new HashMap();\\\\n temp[\\\\\\"rule_name\\\\\\"] = key;\\\\n temp[\\\\\\"rule_risk\\\\\\"] = total_risk_stats[key][0];\\\\n temp[\\\\\\"rule_id\\\\\\"] = total_risk_stats[key][1];\\\\n rule_stats.add(temp);\\\\n}\\\\n\\\\nreturn [\\\\\\"calculated_score_norm\\\\\\": final_risk, \\\\\\"rule_risks\\\\\\": rule_stats, \\\\\\"multipliers\\\\\\": multipliers];\\" - } -} - -# 5. Upload the ingest pipeline -# Ingest pipeline to add ingest timestamp and risk level to documents -PUT _ingest/pipeline/ml_hostriskscore_ingest_pipeline_default -{ - \\"processors\\": [{\\"set\\":{\\"field\\":\\"ingest_timestamp\\",\\"value\\":\\"{{_ingest.timestamp}}\\"}},{\\"fingerprint\\":{\\"fields\\":[\\"@timestamp\\",\\"_id\\"],\\"method\\":\\"SHA-256\\",\\"target_field\\":\\"_id\\"}},{\\"script\\":{\\"id\\":\\"ml_hostriskscore_levels_script_default\\",\\"params\\":{\\"risk_score\\":\\"host.risk.calculated_score_norm\\"}}}] -} - -# 6. Create mappings for the destination index of the Host Risk Score pivot transform -PUT ml_host_risk_score_default -{ - \\"mappings\\": {\\"properties\\":{\\"host\\":{\\"properties\\":{\\"name\\":{\\"type\\":\\"keyword\\"},\\"risk\\":{\\"properties\\":{\\"calculated_score_norm\\":{\\"type\\":\\"float\\"},\\"calculated_level\\":{\\"type\\":\\"keyword\\"},\\"multipliers\\":{\\"type\\":\\"keyword\\"},\\"rule_risks\\":{\\"properties\\":{\\"rule_name\\":{\\"type\\":\\"text\\",\\"fields\\":{\\"keyword\\":{\\"type\\":\\"keyword\\"}}},\\"rule_risk\\":{\\"type\\":\\"float\\"},\\"rule_id\\":{\\"type\\":\\"keyword\\"}}}}}}},\\"ingest_timestamp\\":{\\"type\\":\\"date\\"},\\"@timestamp\\":{\\"type\\":\\"date\\"}}} -} - -# 7. Upload the Host Risk Score pivot transform -# This transform runs hourly and calculates a risk score and risk level for hosts in a Kibana space -PUT _transform/ml_hostriskscore_pivot_transform_default -{\\"dest\\":{\\"index\\":\\"ml_host_risk_score_default\\",\\"pipeline\\":\\"ml_hostriskscore_ingest_pipeline_default\\"},\\"frequency\\":\\"1h\\",\\"pivot\\":{\\"aggregations\\":{\\"@timestamp\\":{\\"max\\":{\\"field\\":\\"@timestamp\\"}},\\"host.risk\\":{\\"scripted_metric\\":{\\"combine_script\\":\\"return state\\",\\"init_script\\":{\\"id\\":\\"ml_hostriskscore_init_script_default\\"},\\"map_script\\":{\\"id\\":\\"ml_hostriskscore_map_script_default\\"},\\"params\\":{\\"lookback_time\\":72,\\"max_risk\\":100,\\"p\\":1.5,\\"server_multiplier\\":1.5,\\"tactic_base_multiplier\\":0.25,\\"tactic_weights\\":{\\"TA0001\\":1,\\"TA0002\\":2,\\"TA0003\\":3,\\"TA0004\\":4,\\"TA0005\\":4,\\"TA0006\\":4,\\"TA0007\\":4,\\"TA0008\\":5,\\"TA0009\\":6,\\"TA0010\\":7,\\"TA0011\\":6,\\"TA0040\\":8,\\"TA0042\\":1,\\"TA0043\\":1},\\"time_decay_constant\\":6,\\"zeta_constant\\":2.612},\\"reduce_script\\":{\\"id\\":\\"ml_hostriskscore_reduce_script_default\\"}}}},\\"group_by\\":{\\"host.name\\":{\\"terms\\":{\\"field\\":\\"host.name\\"}}}},\\"source\\":{\\"index\\":[\\".alerts-security.alerts-default\\"],\\"query\\":{\\"bool\\":{\\"filter\\":[{\\"range\\":{\\"@timestamp\\":{\\"gte\\":\\"now-5d\\"}}}]}}},\\"sync\\":{\\"time\\":{\\"delay\\":\\"120s\\",\\"field\\":\\"@timestamp\\"}}} - - -# 8. Start the pivot transform -POST _transform/ml_hostriskscore_pivot_transform_default/_start - -# 9. Create mappings for the destination index of the Host Risk Score latest transform -PUT ml_host_risk_score_latest_default -{ - \\"mappings\\": {\\"properties\\":{\\"host\\":{\\"properties\\":{\\"name\\":{\\"type\\":\\"keyword\\"},\\"risk\\":{\\"properties\\":{\\"calculated_score_norm\\":{\\"type\\":\\"float\\"},\\"calculated_level\\":{\\"type\\":\\"keyword\\"},\\"multipliers\\":{\\"type\\":\\"keyword\\"},\\"rule_risks\\":{\\"properties\\":{\\"rule_name\\":{\\"type\\":\\"text\\",\\"fields\\":{\\"keyword\\":{\\"type\\":\\"keyword\\"}}},\\"rule_risk\\":{\\"type\\":\\"float\\"},\\"rule_id\\":{\\"type\\":\\"keyword\\"}}}}}}},\\"ingest_timestamp\\":{\\"type\\":\\"date\\"},\\"@timestamp\\":{\\"type\\":\\"date\\"}}} -} - -# 10. Upload the latest transform -# This transform gets the latest risk information about hosts in a Kibana space -PUT _transform/ml_hostriskscore_latest_transform_default -{\\"dest\\":{\\"index\\":\\"ml_host_risk_score_latest_default\\"},\\"frequency\\":\\"1h\\",\\"latest\\":{\\"sort\\":\\"@timestamp\\",\\"unique_key\\":[\\"host.name\\"]},\\"source\\":{\\"index\\":[\\"ml_host_risk_score_default\\"]},\\"sync\\":{\\"time\\":{\\"delay\\":\\"2s\\",\\"field\\":\\"ingest_timestamp\\"}}} - -# 11. Start the latest transform -POST _transform/ml_hostriskscore_latest_transform_default/_start - -# Hint: If you don't see data after running any of the transforms, stop and restart the transforms -# Stop the pivot transform -POST _transform/ml_hostriskscore_pivot_transform_default/_stop - -# Start the pivot transform -POST _transform/ml_hostriskscore_pivot_transform_default/_start - -# Stop the latest transform -POST _transform/ml_hostriskscore_latest_transform_default/_stop - -# Start the latest transform -POST _transform/ml_hostriskscore_latest_transform_default/_start -" -`; - -exports[`readPrebuiltDevToolContentRoute should read content from "enable_user_risk_score" template 1`] = ` -"# Click the run button of each step to enable the module -# Upload scripts -# 1. Script to assign risk level based on risk score -PUT _scripts/ml_userriskscore_levels_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"double risk_score = (def)ctx.getByPath(params.risk_score);\\\\nif (risk_score < 20) {\\\\n ctx['user']['risk']['calculated_level'] = 'Unknown'\\\\n}\\\\nelse if (risk_score >= 20 && risk_score < 40) {\\\\n ctx['user']['risk']['calculated_level'] = 'Low'\\\\n}\\\\nelse if (risk_score >= 40 && risk_score < 70) {\\\\n ctx['user']['risk']['calculated_level'] = 'Moderate'\\\\n}\\\\nelse if (risk_score >= 70 && risk_score < 90) {\\\\n ctx['user']['risk']['calculated_level'] = 'High'\\\\n}\\\\nelse if (risk_score >= 90) {\\\\n ctx['user']['risk']['calculated_level'] = 'Critical'\\\\n}\\" - } -} - -# 2. Map script for the User Risk Score transform -PUT _scripts/ml_userriskscore_map_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"// Get running sum of risk score per rule name per shard\\\\\\\\\\\\\\\\\\\\nString rule_name = doc[\\\\\\"signal.rule.name\\\\\\"].value;\\\\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, 0.0);\\\\nstats = doc[\\\\\\"signal.rule.risk_score\\\\\\"].value;\\\\nstate.rule_risk_stats.put(rule_name, stats);\\" - } -} - -# 3. Reduce script for the User Risk Score transform -PUT _scripts/ml_userriskscore_reduce_script_default -{ - \\"script\\": { - \\"lang\\": \\"painless\\", - \\"source\\": \\"// Consolidating time decayed risks from across all shards\\\\nMap total_risk_stats = new HashMap();\\\\nfor (state in states) {\\\\n for (key in state.rule_risk_stats.keySet()) {\\\\n def rule_stats = state.rule_risk_stats.get(key);\\\\n def stats = total_risk_stats.getOrDefault(key, 0.0);\\\\n stats = rule_stats;\\\\n total_risk_stats.put(key, stats);\\\\n }\\\\n}\\\\n// Consolidating individual rule risks and arranging them in decreasing order\\\\nList risks = new ArrayList();\\\\nfor (key in total_risk_stats.keySet()) {\\\\n risks.add(total_risk_stats[key])\\\\n}\\\\nCollections.sort(risks, Collections.reverseOrder());\\\\n// Calculating total risk and normalizing it to a range\\\\ndouble total_risk = 0.0;\\\\ndouble risk_cap = params.max_risk * params.zeta_constant;\\\\nfor (int i=0;i= 40 && total_norm_risk < 50) {\\\\n total_norm_risk = 85 + (total_norm_risk - 40);\\\\n}\\\\nelse {\\\\n total_norm_risk = 95 + (total_norm_risk - 50) / 10;\\\\n}\\\\n\\\\nList rule_stats = new ArrayList();\\\\nfor (key in total_risk_stats.keySet()) {\\\\n Map temp = new HashMap();\\\\n temp[\\\\\\"rule_name\\\\\\"] = key;\\\\n temp[\\\\\\"rule_risk\\\\\\"] = total_risk_stats[key];\\\\n rule_stats.add(temp);\\\\n}\\\\n\\\\nreturn [\\\\\\"calculated_score_norm\\\\\\": total_norm_risk, \\\\\\"rule_risks\\\\\\": rule_stats];\\" - } -} - -# 4. Upload ingest pipeline -# Ingest pipeline to add ingest timestamp and risk level to documents -PUT _ingest/pipeline/ml_userriskscore_ingest_pipeline_default -{ - \\"processors\\": [{\\"set\\":{\\"field\\":\\"ingest_timestamp\\",\\"value\\":\\"{{_ingest.timestamp}}\\"}},{\\"fingerprint\\":{\\"fields\\":[\\"@timestamp\\",\\"_id\\"],\\"method\\":\\"SHA-256\\",\\"target_field\\":\\"_id\\"}},{\\"script\\":{\\"id\\":\\"ml_userriskscore_levels_script_default\\",\\"params\\":{\\"risk_score\\":\\"user.risk.calculated_score_norm\\"}}}] -} - -# 5. Create mappings for the destination index of the User Risk Score pivot transform -PUT ml_user_risk_score_default -{ - \\"mappings\\": {\\"properties\\":{\\"user\\":{\\"properties\\":{\\"name\\":{\\"type\\":\\"keyword\\"},\\"risk\\":{\\"properties\\":{\\"calculated_score_norm\\":{\\"type\\":\\"float\\"},\\"calculated_level\\":{\\"type\\":\\"keyword\\"},\\"multipliers\\":{\\"type\\":\\"keyword\\"},\\"rule_risks\\":{\\"properties\\":{\\"rule_name\\":{\\"type\\":\\"text\\",\\"fields\\":{\\"keyword\\":{\\"type\\":\\"keyword\\"}}},\\"rule_risk\\":{\\"type\\":\\"float\\"},\\"rule_id\\":{\\"type\\":\\"keyword\\"}}}}}}},\\"ingest_timestamp\\":{\\"type\\":\\"date\\"},\\"@timestamp\\":{\\"type\\":\\"date\\"}}} -} - -# 6. Upload the User Risk Score pivot transform -# This transform runs hourly and calculates a risk score and risk level for users in a Kibana space -PUT _transform/ml_userriskscore_pivot_transform_default -{\\"dest\\":{\\"index\\":\\"ml_user_risk_score_default\\",\\"pipeline\\":\\"ml_userriskscore_ingest_pipeline_default\\"},\\"frequency\\":\\"1h\\",\\"pivot\\":{\\"aggregations\\":{\\"@timestamp\\":{\\"max\\":{\\"field\\":\\"@timestamp\\"}},\\"user.risk\\":{\\"scripted_metric\\":{\\"combine_script\\":\\"return state\\",\\"init_script\\":\\"state.rule_risk_stats = new HashMap();\\",\\"map_script\\":{\\"id\\":\\"ml_userriskscore_map_script_default\\"},\\"params\\":{\\"max_risk\\":100,\\"p\\":1.5,\\"zeta_constant\\":2.612},\\"reduce_script\\":{\\"id\\":\\"ml_userriskscore_reduce_script_default\\"}}}},\\"group_by\\":{\\"user.name\\":{\\"terms\\":{\\"field\\":\\"user.name\\"}}}},\\"source\\":{\\"index\\":[\\".alerts-security.alerts-default\\"],\\"query\\":{\\"bool\\":{\\"filter\\":[{\\"range\\":{\\"@timestamp\\":{\\"gte\\":\\"now-90d\\"}}},{\\"match\\":{\\"signal.status\\":\\"open\\"}}]}}},\\"sync\\":{\\"time\\":{\\"delay\\":\\"120s\\",\\"field\\":\\"@timestamp\\"}}} - - -# 7. start the pivot transform -POST _transform/ml_userriskscore_pivot_transform_default/_start - -# 8. Create mappings for the destination index of the User Risk Score latest transform -PUT ml_user_risk_score_latest_default -{ - \\"mappings\\": {\\"properties\\":{\\"user\\":{\\"properties\\":{\\"name\\":{\\"type\\":\\"keyword\\"},\\"risk\\":{\\"properties\\":{\\"calculated_score_norm\\":{\\"type\\":\\"float\\"},\\"calculated_level\\":{\\"type\\":\\"keyword\\"},\\"multipliers\\":{\\"type\\":\\"keyword\\"},\\"rule_risks\\":{\\"properties\\":{\\"rule_name\\":{\\"type\\":\\"text\\",\\"fields\\":{\\"keyword\\":{\\"type\\":\\"keyword\\"}}},\\"rule_risk\\":{\\"type\\":\\"float\\"},\\"rule_id\\":{\\"type\\":\\"keyword\\"}}}}}}},\\"ingest_timestamp\\":{\\"type\\":\\"date\\"},\\"@timestamp\\":{\\"type\\":\\"date\\"}}} -} - -# 9. Upload the latest transform -# This transform gets the latest risk information about users in a Kibana space -PUT _transform/ml_userriskscore_latest_transform_default -{\\"dest\\":{\\"index\\":\\"ml_user_risk_score_latest_default\\"},\\"frequency\\":\\"1h\\",\\"latest\\":{\\"sort\\":\\"@timestamp\\",\\"unique_key\\":[\\"user.name\\"]},\\"source\\":{\\"index\\":[\\"ml_user_risk_score_default\\"]},\\"sync\\":{\\"time\\":{\\"delay\\":\\"2s\\",\\"field\\":\\"ingest_timestamp\\"}}} - - -# 10. Start the latest transform -POST _transform/ml_userriskscore_latest_transform_default/_start - -# Hint: If you don't see data after running any of the transforms, stop and restart the transforms -# Stop the pivot transform -POST _transform/ml_userriskscore_pivot_transform_default/_stop - -# Start the pivot transform -POST _transform/ml_userriskscore_pivot_transform_default/_start - -# Stop the latest transform -POST _transform/ml_userriskscore_latest_transform_default/_stop - -# Start the latest transform -POST _transform/ml_userriskscore_latest_transform_default/_start -" -`; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.test.ts deleted file mode 100644 index d1b05736beb49..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.test.ts +++ /dev/null @@ -1,49 +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 { - serverMock, - requestContextMock, - requestMock, -} from '../../../detection_engine/routes/__mocks__'; -import { DEV_TOOL_PREBUILT_CONTENT } from '../../../../../common/constants'; -import { readPrebuiltDevToolContentRoute } from './read_prebuilt_dev_tool_content_route'; - -const readPrebuiltDevToolContentRequest = (consoleId: string) => - requestMock.create({ - method: 'get', - path: DEV_TOOL_PREBUILT_CONTENT, - params: { console_id: consoleId }, - }); - -describe('readPrebuiltDevToolContentRoute', () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - - beforeEach(() => { - jest.resetModules(); - jest.resetAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - - readPrebuiltDevToolContentRoute(server.router); - }); - - it.each([['enable_host_risk_score'], ['enable_user_risk_score']])( - 'should read content from %p template', - async (object) => { - const response = await server.inject( - readPrebuiltDevToolContentRequest(object), - requestContextMock.convertContext(context) - ); - - expect(response.status).toEqual(200); - expect(response.body).toMatchSnapshot(); - } - ); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts deleted file mode 100644 index 81a7694ba79e9..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import mustache from 'mustache'; -import path, { join, resolve } from 'path'; -import fs from 'fs'; - -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { CustomHttpResponseOptions, KibanaResponseFactory } from '@kbn/core/server'; -import { DEV_TOOL_PREBUILT_CONTENT } from '../../../../../common/constants'; - -import type { SecuritySolutionPluginRouter } from '../../../../types'; -import { consoleMappings } from '../console_mappings'; -import { readConsoleRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { getView } from '../utils'; - -const getReadables = (dataPath: string) => fs.promises.readFile(dataPath, { encoding: 'utf-8' }); - -class ConsoleResponseFactory { - constructor(private response: KibanaResponseFactory) {} - - // @ts-expect-error upgrade typescript v4.9.5 - error({ statusCode, body, headers }: CustomHttpResponseOptions) { - // @ts-expect-error upgrade typescript v4.9.5 - const contentType: CustomHttpResponseOptions['headers'] = { - 'content-type': 'text/plain; charset=utf-8', - }; - // @ts-expect-error upgrade typescript v4.9.5 - const defaultedHeaders: CustomHttpResponseOptions['headers'] = { - ...contentType, - ...(headers ?? {}), - }; - - return this.response.custom({ - headers: defaultedHeaders, - statusCode, - // @ts-expect-error upgrade typescript v4.9.5 - body, - }); - } -} - -const buildConsoleResponse = (response: KibanaResponseFactory) => - new ConsoleResponseFactory(response); - -export const readPrebuiltDevToolContentRoute = (router: SecuritySolutionPluginRouter) => { - router.versioned - .get({ - access: 'internal', - path: DEV_TOOL_PREBUILT_CONTENT, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { validate: { request: readConsoleRequestBody }, version: '1' }, - async (context, request, response) => { - const siemResponse = buildConsoleResponse(response); - const { console_id: consoleId } = request.params; - - try { - const securitySolution = await context.securitySolution; - const spaceId = securitySolution.getSpaceId(); - - const fileName = consoleMappings[consoleId] ?? null; - - if (!fileName) { - return siemResponse.error({ statusCode: 500, body: 'No such file or directory' }); - } - - const filePath = '../console_templates'; - const dir = resolve(join(__dirname, filePath)); - - const dataPath = path.join(dir, fileName); - const template = await getReadables(dataPath); - - const riskScoreEntity = - consoleId === 'enable_host_risk_score' ? RiskScoreEntity.host : RiskScoreEntity.user; - const view = getView({ spaceId, riskScoreEntity }); - - // override the mustache.js escape function to not escape special characters - mustache.escape = (text) => text; - const output = mustache.render(template, view); - return response.ok({ body: output }); - } catch (err) { - const error = transformError(err); - - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts deleted file mode 100644 index d5856c31a5121..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.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 { readConsoleRequestBody } from '../../../../common/api/entity_analytics/risk_score'; - -describe('ReadConsoleRequestSchema', () => { - it('should throw error', () => { - expect(() => readConsoleRequestBody.params.validate({ console_id: '123' })).toThrow(); - }); - - it.each([['enable_host_risk_score', 'enable_user_risk_score']])( - 'should allow console_id %p', - async (template) => { - expect(readConsoleRequestBody.params.validate({ console_id: template })).toEqual({ - console_id: template, - }); - } - ); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/utils.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/utils.ts deleted file mode 100644 index 5e9b892e43a48..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/utils.ts +++ /dev/null @@ -1,114 +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 { RiskScoreEntity } from '../../../../common/search_strategy'; -import { - getCreateLatestTransformOptions, - getCreateMLHostPivotTransformOptions, - getCreateMLUserPivotTransformOptions, - getCreateRiskScoreIndicesOptions, - getCreateRiskScoreLatestIndicesOptions, - getRiskScoreIngestPipelineOptions, - getRiskScoreLatestTransformId, - getRiskScorePivotTransformId, - getRiskHostCreateInitScriptOptions, - getRiskHostCreateLevelScriptOptions, - getRiskHostCreateMapScriptOptions, - getRiskHostCreateReduceScriptOptions, - getRiskUserCreateLevelScriptOptions, - getRiskUserCreateMapScriptOptions, - getRiskUserCreateReduceScriptOptions, -} from '../../../../common/utils/risk_score_modules'; - -const getRiskyHostPrebuiltDevToolsContent = ({ spaceId = 'default' }: { spaceId?: string }) => { - const riskScoreEntity = RiskScoreEntity.host; - const stringifyScript = true; - return { - spaceId, - createLevelScriptOptions: getRiskHostCreateLevelScriptOptions(spaceId, stringifyScript), - createInitScriptOptions: getRiskHostCreateInitScriptOptions(spaceId, stringifyScript), - createMapScriptOptions: getRiskHostCreateMapScriptOptions(spaceId, stringifyScript), - createReduceScriptOptions: getRiskHostCreateReduceScriptOptions(spaceId, stringifyScript), - createIngestPipelineOptions: getRiskScoreIngestPipelineOptions( - riskScoreEntity, - spaceId, - stringifyScript - ), - createRiskScoreIndicesOptions: getCreateRiskScoreIndicesOptions({ - spaceId, - riskScoreEntity, - stringifyScript, - }), - createRiskScoreLatestIndicesOptions: getCreateRiskScoreLatestIndicesOptions({ - spaceId, - riskScoreEntity, - stringifyScript, - }), - pivotTransformId: getRiskScorePivotTransformId(riskScoreEntity, spaceId), - pivotTransformOptions: getCreateMLHostPivotTransformOptions({ - spaceId, - stringifyScript, - }), - latestTransformId: getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - latestTransformOptions: getCreateLatestTransformOptions({ - spaceId, - riskScoreEntity, - stringifyScript, - }), - }; -}; - -const getRiskyUserPrebuiltDevToolsContent = ({ spaceId = 'default' }: { spaceId?: string }) => { - const riskScoreEntity = RiskScoreEntity.user; - const stringifyScript = true; - return { - spaceId, - createLevelScriptOptions: getRiskUserCreateLevelScriptOptions(spaceId, stringifyScript), - createMapScriptOptions: getRiskUserCreateMapScriptOptions(spaceId, stringifyScript), - createReduceScriptOptions: getRiskUserCreateReduceScriptOptions(spaceId, stringifyScript), - createIngestPipelineOptions: getRiskScoreIngestPipelineOptions( - riskScoreEntity, - spaceId, - stringifyScript - ), - createRiskScoreIndicesOptions: getCreateRiskScoreIndicesOptions({ - spaceId, - riskScoreEntity, - stringifyScript, - }), - createRiskScoreLatestIndicesOptions: getCreateRiskScoreLatestIndicesOptions({ - spaceId, - riskScoreEntity, - stringifyScript, - }), - pivotTransformId: getRiskScorePivotTransformId(riskScoreEntity, spaceId), - pivotTransformOptions: getCreateMLUserPivotTransformOptions({ - spaceId, - stringifyScript, - }), - latestTransformId: getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - latestTransformOptions: getCreateLatestTransformOptions({ - spaceId, - riskScoreEntity, - stringifyScript, - }), - }; -}; - -export const getView = ({ - spaceId = 'default', - riskScoreEntity, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; -}) => { - if (riskScoreEntity === RiskScoreEntity.user) { - return getRiskyUserPrebuiltDevToolsContent({ spaceId }); - } - - return getRiskyHostPrebuiltDevToolsContent({ spaceId }); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_create_saved_objects.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_create_saved_objects.ts deleted file mode 100644 index 2d83570c0fce8..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_create_saved_objects.ts +++ /dev/null @@ -1,121 +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 { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { Logger } from '@kbn/core/server'; - -import { v4 as uuidv4 } from 'uuid'; -import { i18n } from '@kbn/i18n'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import * as savedObjectsToCreate from '../saved_object'; -import type { BulkCreateSavedObjectsResult, SavedObjectTemplate } from '../types'; -import { createRiskScoreTag } from './create_risk_score_tag'; - -export const bulkCreateSavedObjects = async ({ - logger, - savedObjectsClient, - spaceId, - savedObjectTemplate, -}: { - logger: Logger; - savedObjectsClient: SavedObjectsClientContract; - spaceId?: string; - savedObjectTemplate: SavedObjectTemplate; -}): Promise => { - const regex = //g; - - const riskScoreEntity = - savedObjectTemplate === 'userRiskScoreDashboards' ? RiskScoreEntity.user : RiskScoreEntity.host; - - const tagResponse = await createRiskScoreTag({ - riskScoreEntity, - logger, - savedObjectsClient, - spaceId, - }); - - const riskScoreTagResult = - tagResponse?.hostRiskScoreDashboards ?? tagResponse?.userRiskScoreDashboards; - - if (!riskScoreTagResult?.success) { - return tagResponse; - } - - const mySavedObjects = savedObjectsToCreate[savedObjectTemplate]; - - if (!mySavedObjects) { - logger.error(`${savedObjectTemplate} template not found`); - return { - [savedObjectTemplate]: { - success: false, - error: transformError( - new Error( - i18n.translate('xpack.securitySolution.riskScore.savedObjects.templateNotFoundTitle', { - values: { savedObjectTemplate }, - defaultMessage: `Failed to import saved objects: {savedObjectTemplate} were not created as template not found`, - }) - ) - ), - }, - }; - } - - const idReplaceMappings: Record = {}; - mySavedObjects.forEach((so) => { - if (so.id.startsWith(' { - const references = - so.references?.map((ref) => { - return { ...ref, id: idReplaceMappings[ref.id] ?? ref.id }; - }) ?? []; - return { - ...so, - id: idReplaceMappings[so.id] ?? so.id, - references: [ - ...references, - { - id: riskScoreTagResult?.body?.id, - name: riskScoreTagResult?.body?.name, - type: riskScoreTagResult?.body?.type, - }, - ], - }; - }); - - const savedObjects = JSON.stringify(mySavedObjectsWithRef); - - const replacedSO = spaceId ? savedObjects.replace(regex, spaceId) : savedObjects; - - try { - const result = await savedObjectsClient.bulkCreate<{ - title: string; - name: string; - }>(JSON.parse(replacedSO), { - overwrite: true, - }); - - return { - [savedObjectTemplate]: { - success: true, - error: null, - body: result.saved_objects.map(({ id, type, attributes: { title, name } }) => ({ - id, - type, - title, - name, - })), - }, - }; - } catch (error) { - const err = transformError(error); - logger.error(`Failed to create saved object: ${savedObjectTemplate}: ${err.message}`); - return { [savedObjectTemplate]: { success: false, error: err } }; - } -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_delete_saved_objects.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_delete_saved_objects.ts deleted file mode 100644 index c53acfaafc327..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/bulk_delete_saved_objects.ts +++ /dev/null @@ -1,145 +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 { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { findTagsByName } from '../../../tags/saved_objects'; -import * as savedObjectsToCreate from '../saved_object'; -import type { SavedObjectTemplate } from '../types'; -import { findSavedObjectsWithTagReference } from './create_risk_score_tag'; -import { RISK_SCORE_REPLACE_ID_MAPPINGS, getRiskScoreTagName } from './utils'; - -const deleteSavedObject = async ({ - checkObjectExists, - savedObjectsClient, - options: { type, id }, -}: { - checkObjectExists?: boolean; - savedObjectsClient: SavedObjectsClientContract; - options: { type: string; id: string }; -}) => { - try { - if (checkObjectExists) { - await savedObjectsClient.get(type, id); - } - await savedObjectsClient.delete(type, id); - return `Deleted saved object: ${id}`; - } catch (e) { - return e?.output?.payload?.message ?? `Failed to delete saved object: ${id}`; - } -}; - -const deleteSavedObjects = async ({ - checkObjectExists, - savedObjects, - savedObjectsClient, -}: { - checkObjectExists?: boolean; - savedObjectsClient: SavedObjectsClientContract; - savedObjects: Array<{ id: string; type: string }>; -}) => { - const result = await Promise.all( - savedObjects.map((so) => { - return deleteSavedObject({ - checkObjectExists, - savedObjectsClient, - options: { type: so.type, id: so.id }, - }); - }) - ); - - return result; -}; - -const deleteSavedObjectsWithTag = async ({ - savedObjectsClient, - savedObjectTypes, - tagId, -}: { - savedObjectsClient: SavedObjectsClientContract; - savedObjectTypes: string[]; - tagId: string; -}) => { - const linkedSavedObjects = await findSavedObjectsWithTagReference({ - savedObjectsClient, - savedObjectTypes, - tagId, - }); - - const deletedIds = await deleteSavedObjects({ - checkObjectExists: false, - savedObjectsClient, - savedObjects: linkedSavedObjects, - }); - const deletedTagId = await deleteSavedObject({ - savedObjectsClient, - options: { type: 'tag', id: tagId }, - }); - - return [...deletedIds, deletedTagId]; -}; - -export const bulkDeleteSavedObjects = async ({ - deleteAll, - savedObjectsClient, - spaceId, - savedObjectTemplate, -}: { - deleteAll?: boolean; - savedObjectsClient: SavedObjectsClientContract; - spaceId?: string; - savedObjectTemplate: SavedObjectTemplate; -}) => { - const savedObjects = savedObjectsToCreate[savedObjectTemplate]; - const idReplaceMappings = RISK_SCORE_REPLACE_ID_MAPPINGS[savedObjectTemplate]; - const riskScoreEntity = - savedObjectTemplate === 'userRiskScoreDashboards' ? RiskScoreEntity.user : RiskScoreEntity.host; - - if (savedObjects == null) { - return new Error('Template not found.'); - } - - const tagName = getRiskScoreTagName(riskScoreEntity, spaceId); - const [tag] = await findTagsByName({ savedObjectsClient, tagName }); - - /** - * This is to delete the saved objects installed before 8.5 - * These saved objects were created according to these mappings: - * prebuilt_saved_objects/helpers/utils.ts RISK_SCORE_REPLACE_ID_MAPPINGS - * */ - const regex = //g; - - const deleteLegacySavedObjectResults = await deleteSavedObjects({ - checkObjectExists: true, - savedObjectsClient, - savedObjects: savedObjects.map((so) => { - const legacyId = idReplaceMappings[so.id] ?? so.id; - return { - id: spaceId ? legacyId.replace(regex, spaceId) : legacyId, - type: so.type, - }; - }), - }); - - let deleteSavedObjectResults: string[] = []; - if (tag && deleteAll) { - /** - * Since 8.5 all the saved objects are created with dynamic ids and all link to a tag. - * (As create saved objects with static ids causes conflict across different spaces) - * so just need to delete all the objects that links to the tag - * and the tag itself - * */ - const savedObjectsTypes = new Set(savedObjects.map((so) => so.type)); - deleteSavedObjectResults = await deleteSavedObjectsWithTag({ - savedObjectsClient, - tagId: tag.id, - savedObjectTypes: Array.from(savedObjectsTypes), - }); - } - - return [...deleteLegacySavedObjectResults, ...deleteSavedObjectResults]; -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/create_risk_score_tag.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/create_risk_score_tag.ts deleted file mode 100644 index 5de2b10475468..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/create_risk_score_tag.ts +++ /dev/null @@ -1,124 +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 { Logger } from '@kbn/core/server'; -import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import { i18n } from '@kbn/i18n'; -import type { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RISK_SCORE_TAG_DESCRIPTION, getRiskScoreTagName } from './utils'; -import type { BulkCreateSavedObjectsResult } from '../types'; -import { createTag, findTagsByName } from '../../../tags/saved_objects'; - -export const createRiskScoreTag = async ({ - riskScoreEntity, - logger, - savedObjectsClient, - spaceId = 'default', -}: { - logger: Logger; - riskScoreEntity: RiskScoreEntity; - savedObjectsClient: SavedObjectsClientContract; - spaceId?: string; -}): Promise => { - const tagName = getRiskScoreTagName(riskScoreEntity, spaceId); - const savedObjectTemplate = `${riskScoreEntity}RiskScoreDashboards`; - - try { - // check the tag does not already exist - const [existingRiskScoreTag] = await findTagsByName({ savedObjectsClient, tagName }); - if (existingRiskScoreTag?.id != null) { - logger.error(`${savedObjectTemplate} already exists`); - return { - [savedObjectTemplate]: { - success: false, - error: i18n.translate( - 'xpack.securitySolution.riskScore.savedObjects.templateAlreadyExistsTitle', - { - values: { savedObjectTemplate }, - defaultMessage: `Failed to import saved objects: {savedObjectTemplate} were not created as already exist`, - } - ), - }, - }; - } - } catch (err) { - const error = transformError(err); - logger.error( - `${savedObjectTemplate} cannot be installed as failed to find the tag: ${tagName} - ${error?.message}` - ); - return { - [savedObjectTemplate]: { - success: false, - error: i18n.translate( - 'xpack.securitySolution.riskScore.savedObjects.failedToFindTagTitle', - { - values: { savedObjectTemplate, tagName }, - defaultMessage: `Failed to import saved objects: {savedObjectTemplate} were not created as failed to find the tag: {tagName}`, - } - ), - }, - }; - } - - try { - const createTagResponse = await createTag({ - savedObjectsClient, - tagName, - description: RISK_SCORE_TAG_DESCRIPTION, - color: '#6edb7f', - }); - return { - [savedObjectTemplate]: { - success: true, - error: null, - body: { - type: 'tag', - id: createTagResponse?.id, - name: createTagResponse.attributes.name, - description: createTagResponse.attributes.description, - }, - }, - }; - } catch (err) { - const error = transformError(err); - logger.error( - `${savedObjectTemplate} cannot be installed as failed to create the tag: ${tagName} - ${error?.message}` - ); - return { - [savedObjectTemplate]: { - success: false, - error: i18n.translate( - 'xpack.securitySolution.riskScore.savedObjects.failedToCreateTagTitle', - { - values: { savedObjectTemplate, tagName }, - defaultMessage: `Failed to import saved objects: {savedObjectTemplate} were not created as failed to create the tag: {tagName}`, - } - ), - }, - }; - } -}; - -export const findSavedObjectsWithTagReference = async ({ - savedObjectsClient, - savedObjectTypes, - tagId, -}: { - savedObjectsClient: SavedObjectsClientContract; - savedObjectTypes: string | string[]; - tagId: string; -}) => { - const linkedSavedObjects = await savedObjectsClient.find({ - type: savedObjectTypes, - hasReference: { - type: 'tag', - id: tagId, - }, - }); - - return linkedSavedObjects?.saved_objects; -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/utils.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/utils.ts deleted file mode 100644 index 9392b157e6d56..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/helpers/utils.ts +++ /dev/null @@ -1,53 +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 { RiskScoreEntity } from '../../../../../common/search_strategy'; -import type { SavedObjectTemplate } from '../types'; - -export const HOST_RISK_SCORE = 'Host Risk Score'; -export const USER_RISK_SCORE = 'User Risk Score'; - -export const RISK_SCORE_TAG_DESCRIPTION = - 'Security Solution Risk Score auto-generated tag' as const; - -const getRiskScore = (riskScoreEntity: RiskScoreEntity) => - riskScoreEntity === RiskScoreEntity.user ? USER_RISK_SCORE : HOST_RISK_SCORE; -export const getRiskScoreTagName = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `${getRiskScore(riskScoreEntity)} - ${spaceId}`; - -/** - * These mappings are for keeping track of the saved objects installed before 8.5 release, - * so we can delete them when upgrading. - */ -export const RISK_SCORE_REPLACE_ID_MAPPINGS: Record> = { - hostRiskScoreDashboards: { - '': 'd3f72670-d3a0-11eb-bd37-7bb50422e346', - '': '42371d00-cf7a-11eb-9a96-05d89f94ad96', - '': 'a62d3ed0-cf92-11eb-a0ff-1763d16cbda7', - '': 'b2dbc9b0-cf94-11eb-bd37-7bb50422e346', - '': '1d00ebe0-f3b2-11eb-beb2-b91666445a94', - '': '6f05c8c0-cf77-11eb-9a96-05d89f94ad96', - '': 'dc289c10-d4ff-11eb-a0ff-1763d16cbda7', - '': '27b483b0-d500-11eb-a0ff-1763d16cbda7', - '': 'ml-host-risk-score-latest--index-pattern', - '': 'ml-host-risk-score--index-pattern', - '': 'alerts--index-pattern', - }, - userRiskScoreDashboards: { - '': '54dadd60-1a57-11ed-bb53-ad8c26f4d942', - '': '60454070-9a5d-11ec-9633-5f782d122340', - '': 'a62d3ed0-cf92-11eb-a0ff-1763d16cbda7', - '': '42371d00-cf7a-11eb-9a96-05d89f94ad96', - '': '183d32f0-9a5e-11ec-90d3-1109ed409ab5', - '': '93fc0f00-1a57-11ed-bb53-ad8c26f4d942', - '': '8ac3ad30-1a57-11ed-bb53-ad8c26f4d942', - '': '1355b030-ca2b-11ec-962f-a3a018b7d10f', - '': 'ml-user-risk-score-latest--index-pattern', - '': 'ml-user-risk-score--index-pattern', - '': 'alerts--index-pattern', - }, -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/__snapshots__/create_prebuilt_saved_objects.test.ts.snap b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/__snapshots__/create_prebuilt_saved_objects.test.ts.snap deleted file mode 100644 index 014e7ccc66ade..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/__snapshots__/create_prebuilt_saved_objects.test.ts.snap +++ /dev/null @@ -1,1056 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`createPrebuiltSavedObjects should create saved objects from given template - "hostRiskScoreDashboards" 1`] = ` -Array [ - Object { - "attributes": Object { - "fieldAttrs": "{}", - "fields": "[]", - "runtimeFieldMap": "{}", - "timeFieldName": "@timestamp", - "title": "ml_host_risk_score_default", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-1", - "migrationVersion": Object { - "index-pattern": "7.11.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "index-pattern", - "updated_at": "2021-08-18T18:37:41.486Z", - }, - Object { - "attributes": Object { - "description": null, - "state": Object { - "datasourceStates": Object { - "indexpattern": Object { - "layers": Object { - "b885eaad-3c68-49ad-9891-70158d912dbd": Object { - "columnOrder": Array [ - "8dcda7ec-1a1a-43b3-b0b8-e702943eed5c", - "e82aed80-ee04-4ad1-9b9d-fde4a25be58a", - "aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b", - ], - "columns": Object { - "8dcda7ec-1a1a-43b3-b0b8-e702943eed5c": Object { - "customLabel": true, - "dataType": "string", - "isBucketed": true, - "label": "Host Name", - "operationType": "terms", - "params": Object { - "missingBucket": false, - "orderBy": Object { - "columnId": "aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b", - "type": "column", - }, - "orderDirection": "desc", - "otherBucket": true, - "size": 20, - }, - "scale": "ordinal", - "sourceField": "host.name", - }, - "aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b": Object { - "customLabel": true, - "dataType": "number", - "isBucketed": false, - "label": "Cumulative Risk Score", - "operationType": "max", - "scale": "ratio", - "sourceField": "host.risk.calculated_score_norm", - }, - "e82aed80-ee04-4ad1-9b9d-fde4a25be58a": Object { - "dataType": "date", - "isBucketed": true, - "label": "@timestamp", - "operationType": "date_histogram", - "params": Object { - "interval": "1h", - }, - "scale": "interval", - "sourceField": "@timestamp", - }, - }, - "incompleteColumns": Object {}, - }, - }, - }, - }, - "filters": Array [], - "query": Object { - "language": "kuery", - "query": "", - }, - "visualization": Object { - "layers": Array [ - Object { - "accessors": Array [ - "aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b", - ], - "layerId": "b885eaad-3c68-49ad-9891-70158d912dbd", - "palette": Object { - "name": "default", - "type": "palette", - }, - "position": "top", - "seriesType": "bar_stacked", - "showGridlines": false, - "splitAccessor": "8dcda7ec-1a1a-43b3-b0b8-e702943eed5c", - "xAccessor": "e82aed80-ee04-4ad1-9b9d-fde4a25be58a", - }, - ], - "legend": Object { - "isVisible": true, - "position": "right", - }, - "preferredSeriesType": "bar_stacked", - "title": "Empty XY chart", - "valueLabels": "hide", - }, - }, - "title": "Host Risk Score (Max Risk Score Histogram)", - "visualizationType": "lnsXY", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-2", - "migrationVersion": Object { - "lens": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-1", - "name": "indexpattern-datasource-current-indexpattern", - "type": "index-pattern", - }, - Object { - "id": "id-1", - "name": "indexpattern-datasource-layer-b885eaad-3c68-49ad-9891-70158d912dbd", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "lens", - "updated_at": "2021-08-18T18:48:30.689Z", - }, - Object { - "attributes": Object { - "fieldAttrs": "{\\"signal.rule.type\\":{\\"count\\":1}}", - "fields": "[]", - "runtimeFieldMap": "{}", - "timeFieldName": "@timestamp", - "title": ".alerts-security.alerts-default", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-3", - "migrationVersion": Object { - "index-pattern": "7.11.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "index-pattern", - "updated_at": "2021-08-18T16:27:39.980Z", - }, - Object { - "attributes": Object { - "description": "", - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[],\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", - }, - "title": "Host Risk Score (Rule Breakdown)", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\\"title\\":\\"Host Risk Score (Rule Breakdown)\\",\\"type\\":\\"table\\",\\"aggs\\":[{\\"id\\":\\"2\\",\\"enabled\\":true,\\"type\\":\\"sum\\",\\"params\\":{\\"field\\":\\"signal.rule.risk_score\\",\\"customLabel\\":\\"Total Risk Score\\"},\\"schema\\":\\"metric\\"},{\\"id\\":\\"1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"params\\":{\\"customLabel\\":\\"Number of Hits\\"},\\"schema\\":\\"metric\\"},{\\"id\\":\\"3\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"host.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Host\\"},\\"schema\\":\\"split\\"},{\\"id\\":\\"4\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Name\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"5\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.type\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Type\\"},\\"schema\\":\\"bucket\\"}],\\"params\\":{\\"perPage\\":10,\\"showPartialRows\\":false,\\"showMetricsAtAllLevels\\":false,\\"showTotal\\":false,\\"showToolbar\\":false,\\"totalFunc\\":\\"sum\\",\\"percentageCol\\":\\"\\",\\"row\\":true}}", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-4", - "migrationVersion": Object { - "visualization": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-3", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "visualization", - "updated_at": "2021-08-18T16:27:39.980Z", - }, - Object { - "attributes": Object { - "description": "", - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"not user.name: *$\\",\\"language\\":\\"kuery\\"},\\"filter\\":[],\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", - }, - "title": "Associated Users (Rule Breakdown)", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\\"title\\":\\"Associated Users (Rule Breakdown)\\",\\"type\\":\\"table\\",\\"aggs\\":[{\\"id\\":\\"2\\",\\"enabled\\":true,\\"type\\":\\"sum\\",\\"params\\":{\\"field\\":\\"signal.rule.risk_score\\",\\"customLabel\\":\\"Total Risk Score\\"},\\"schema\\":\\"metric\\"},{\\"id\\":\\"1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"params\\":{\\"customLabel\\":\\"Number of Hits\\"},\\"schema\\":\\"metric\\"},{\\"id\\":\\"3\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"user.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"User\\"},\\"schema\\":\\"split\\"},{\\"id\\":\\"4\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Name\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"5\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.type\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Type\\"},\\"schema\\":\\"bucket\\"}],\\"params\\":{\\"perPage\\":10,\\"showPartialRows\\":false,\\"showMetricsAtAllLevels\\":false,\\"showTotal\\":false,\\"showToolbar\\":false,\\"totalFunc\\":\\"sum\\",\\"percentageCol\\":\\"\\",\\"row\\":true}}", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-5", - "migrationVersion": Object { - "visualization": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-3", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "visualization", - "updated_at": "2021-08-18T16:27:39.980Z", - }, - Object { - "attributes": Object { - "description": "", - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[],\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", - }, - "title": "Host Risk Score (Tactic Breakdown)- Verbose", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\\"title\\":\\"Host Risk Score (Tactic Breakdown)- Verbose\\",\\"type\\":\\"table\\",\\"aggs\\":[{\\"id\\":\\"1\\",\\"enabled\\":true,\\"type\\":\\"sum\\",\\"params\\":{\\"field\\":\\"signal.rule.risk_score\\",\\"customLabel\\":\\"Total Risk Score\\"},\\"schema\\":\\"metric\\"},{\\"id\\":\\"3\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"host.name\\",\\"orderBy\\":\\"1\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Host\\"},\\"schema\\":\\"split\\"},{\\"id\\":\\"5\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.threat.tactic.name\\",\\"orderBy\\":\\"1\\",\\"order\\":\\"desc\\",\\"size\\":50,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":true,\\"missingBucketLabel\\":\\"Other\\",\\"customLabel\\":\\"Tactic\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"6\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.threat.technique.name\\",\\"orderBy\\":\\"1\\",\\"order\\":\\"desc\\",\\"size\\":50,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":true,\\"missingBucketLabel\\":\\"Other\\",\\"customLabel\\":\\"Technique\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"7\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"params\\":{\\"customLabel\\":\\"Number of Hits\\"},\\"schema\\":\\"metric\\"}],\\"params\\":{\\"perPage\\":10,\\"showPartialRows\\":false,\\"showMetricsAtAllLevels\\":false,\\"showTotal\\":false,\\"showToolbar\\":false,\\"totalFunc\\":\\"sum\\",\\"percentageCol\\":\\"\\",\\"row\\":true}}", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-6", - "migrationVersion": Object { - "visualization": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-3", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "visualization", - "updated_at": "2021-08-18T16:27:39.980Z", - }, - Object { - "attributes": Object { - "color": "#D36086", - "description": "", - "name": "experimental", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-7", - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "tag", - "updated_at": "2021-08-18T16:27:39.980Z", - }, - Object { - "attributes": Object { - "description": "This dashboard allows users to drill down further into the details of the risk components associated with a particular host.", - "hits": 0, - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"language\\":\\"kuery\\",\\"query\\":\\"\\"},\\"filter\\":[]}", - }, - "optionsJSON": "{\\"hidePanelTitles\\":false,\\"useMargins\\":true}", - "panelsJSON": "[{\\"version\\":\\"7.13.4\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":0,\\"w\\":48,\\"h\\":3,\\"i\\":\\"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195\\"},\\"panelIndex\\":\\"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195\\",\\"embeddableConfig\\":{\\"savedVis\\":{\\"title\\":\\"\\",\\"description\\":\\"\\",\\"type\\":\\"markdown\\",\\"params\\":{\\"fontSize\\":12,\\"openLinksInNewTab\\":false,\\"markdown\\":\\"The Host Risk Score capability is an experimental feature released in 7.14. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md).\\"},\\"uiState\\":{},\\"data\\":{\\"aggs\\":[],\\"searchSource\\":{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[]}}},\\"hidePanelTitles\\":true,\\"enhancements\\":{}}},{\\"version\\":\\"7.13.4\\",\\"type\\":\\"lens\\",\\"gridData\\":{\\"x\\":0,\\"y\\":3,\\"w\\":48,\\"h\\":15,\\"i\\":\\"e11ed08e-70d0-4c69-991a-12e20dc89440\\"},\\"panelIndex\\":\\"e11ed08e-70d0-4c69-991a-12e20dc89440\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[{\\"eventId\\":\\"339da811-5c23-4432-9649-53cb066e6aaf\\",\\"triggers\\":[\\"VALUE_CLICK_TRIGGER\\"],\\"action\\":{\\"factoryId\\":\\"URL_DRILLDOWN\\",\\"name\\":\\"Go to Host View\\",\\"config\\":{\\"url\\":{\\"template\\":\\"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}\\"},\\"openInNewTab\\":true,\\"encodeUrl\\":true}}}]}},\\"hidePanelTitles\\":false},\\"title\\":\\"Cumulative Host Risk Score (multiple hosts)\\",\\"panelRefName\\":\\"panel_e11ed08e-70d0-4c69-991a-12e20dc89440\\"},{\\"version\\":\\"7.13.4\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":18,\\"w\\":24,\\"h\\":28,\\"i\\":\\"cae82aa1-20c8-4354-94ab-3934ac53b8fe\\"},\\"panelIndex\\":\\"cae82aa1-20c8-4354-94ab-3934ac53b8fe\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[{\\"eventId\\":\\"0fd43778-bd5d-4b2b-85c3-47ac3b756434\\",\\"triggers\\":[\\"VALUE_CLICK_TRIGGER\\"],\\"action\\":{\\"factoryId\\":\\"URL_DRILLDOWN\\",\\"name\\":\\"Go to Host View\\",\\"config\\":{\\"url\\":{\\"template\\":\\"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}\\"},\\"openInNewTab\\":true,\\"encodeUrl\\":true}}}]}},\\"hidePanelTitles\\":false},\\"title\\":\\"Associated Rules of Risky Hosts\\",\\"panelRefName\\":\\"panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe\\"},{\\"version\\":\\"7.13.4\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":24,\\"y\\":18,\\"w\\":24,\\"h\\":28,\\"i\\":\\"8d09b97c-a023-4b7e-9e9d-1c46e726a487\\"},\\"panelIndex\\":\\"8d09b97c-a023-4b7e-9e9d-1c46e726a487\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[{\\"eventId\\":\\"593ff0e6-25da-47ad-b81d-9a0106c0e9aa\\",\\"triggers\\":[\\"VALUE_CLICK_TRIGGER\\"],\\"action\\":{\\"factoryId\\":\\"URL_DRILLDOWN\\",\\"name\\":\\"Go to Host View\\",\\"config\\":{\\"url\\":{\\"template\\":\\"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}\\"},\\"openInNewTab\\":true,\\"encodeUrl\\":true}}}]}},\\"hidePanelTitles\\":false},\\"title\\":\\"Associated Users of Risky Hosts\\",\\"panelRefName\\":\\"panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487\\"},{\\"version\\":\\"7.13.4\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":46,\\"w\\":48,\\"h\\":16,\\"i\\":\\"0c9c8318-ebb0-47fb-919a-1836ebf232ae\\"},\\"panelIndex\\":\\"0c9c8318-ebb0-47fb-919a-1836ebf232ae\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[{\\"eventId\\":\\"a76ea63c-da92-4bad-b3d6-6df823e1c04b\\",\\"triggers\\":[\\"VALUE_CLICK_TRIGGER\\"],\\"action\\":{\\"factoryId\\":\\"URL_DRILLDOWN\\",\\"name\\":\\"Go to Host View\\",\\"config\\":{\\"url\\":{\\"template\\":\\"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}\\"},\\"openInNewTab\\":true,\\"encodeUrl\\":true}}}]}},\\"hidePanelTitles\\":false},\\"title\\":\\"Tactic Breakdown of Risky Hosts (Verbose)\\",\\"panelRefName\\":\\"panel_0c9c8318-ebb0-47fb-919a-1836ebf232ae\\"}]", - "timeRestore": false, - "title": "Drilldown of Host Risk Score", - "version": 1, - }, - "coreMigrationVersion": "7.13.4", - "id": "id-8", - "migrationVersion": Object { - "dashboard": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-2", - "name": "e11ed08e-70d0-4c69-991a-12e20dc89440:panel_e11ed08e-70d0-4c69-991a-12e20dc89440", - "type": "lens", - }, - Object { - "id": "id-4", - "name": "cae82aa1-20c8-4354-94ab-3934ac53b8fe:panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe", - "type": "visualization", - }, - Object { - "id": "id-5", - "name": "8d09b97c-a023-4b7e-9e9d-1c46e726a487:panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487", - "type": "visualization", - }, - Object { - "id": "id-6", - "name": "0c9c8318-ebb0-47fb-919a-1836ebf232ae:panel_0c9c8318-ebb0-47fb-919a-1836ebf232ae", - "type": "visualization", - }, - Object { - "id": "id-7", - "name": "tag-1d00ebe0-f3b2-11eb-beb2-b91666445a94", - "type": "tag", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "dashboard", - "updated_at": "2021-08-18T17:09:15.576Z", - }, - Object { - "attributes": Object { - "fieldAttrs": "{}", - "fields": "[]", - "runtimeFieldMap": "{}", - "timeFieldName": "@timestamp", - "title": "ml_host_risk_score_latest_default", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-9", - "migrationVersion": Object { - "index-pattern": "7.11.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "index-pattern", - "updated_at": "2021-08-18T18:47:22.500Z", - }, - Object { - "attributes": Object { - "description": null, - "state": Object { - "datasourceStates": Object { - "indexpattern": Object { - "layers": Object { - "2f34d626-d0ee-4ade-9e75-13c480699485": Object { - "columnOrder": Array [ - "9c8c581f-6cb8-4ecf-8eb3-4c6df33edc5d", - "c547501b-fe04-4073-8b4e-dbbdc3a4ff04", - "e2444d64-721a-4532-9633-5b206eee76d6", - ], - "columns": Object { - "9c8c581f-6cb8-4ecf-8eb3-4c6df33edc5d": Object { - "customLabel": true, - "dataType": "string", - "isBucketed": true, - "label": "Host Name", - "operationType": "terms", - "params": Object { - "missingBucket": false, - "orderBy": Object { - "columnId": "c547501b-fe04-4073-8b4e-dbbdc3a4ff04", - "type": "column", - }, - "orderDirection": "desc", - "otherBucket": true, - "size": 20, - }, - "scale": "ordinal", - "sourceField": "host.name", - }, - "c547501b-fe04-4073-8b4e-dbbdc3a4ff04": Object { - "customLabel": true, - "dataType": "number", - "isBucketed": false, - "label": "Risk Score", - "operationType": "sum", - "scale": "ratio", - "sourceField": "host.risk.calculated_score_norm", - }, - "e2444d64-721a-4532-9633-5b206eee76d6": Object { - "customLabel": true, - "dataType": "string", - "isBucketed": false, - "label": "Current Risk", - "operationType": "last_value", - "params": Object { - "sortField": "@timestamp", - }, - "scale": "ordinal", - "sourceField": "host.risk.calculated_level", - }, - }, - "incompleteColumns": Object {}, - }, - }, - }, - }, - "filters": Array [], - "query": Object { - "language": "kuery", - "query": "", - }, - "visualization": Object { - "columns": Array [ - Object { - "columnId": "9c8c581f-6cb8-4ecf-8eb3-4c6df33edc5d", - "isTransposed": false, - }, - Object { - "alignment": "left", - "columnId": "c547501b-fe04-4073-8b4e-dbbdc3a4ff04", - "hidden": true, - "isTransposed": false, - }, - Object { - "columnId": "e2444d64-721a-4532-9633-5b206eee76d6", - "isTransposed": false, - }, - ], - "layerId": "2f34d626-d0ee-4ade-9e75-13c480699485", - }, - }, - "title": "Current Risk Score for Hosts", - "visualizationType": "lnsDatatable", - }, - "coreMigrationVersion": "7.13.4", - "id": "id-10", - "migrationVersion": Object { - "lens": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-9", - "name": "indexpattern-datasource-current-indexpattern", - "type": "index-pattern", - }, - Object { - "id": "id-9", - "name": "indexpattern-datasource-layer-2f34d626-d0ee-4ade-9e75-13c480699485", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "lens", - "updated_at": "2021-08-18T17:07:41.806Z", - }, - Object { - "attributes": Object { - "description": "This dashboard shows the most current list of risky hosts (Top 20) in an environment. ", - "hits": 0, - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"language\\":\\"kuery\\",\\"query\\":\\"\\"},\\"filter\\":[]}", - }, - "optionsJSON": "{\\"hidePanelTitles\\":false,\\"useMargins\\":true}", - "panelsJSON": "[{\\"version\\":\\"7.13.4\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":0,\\"w\\":48,\\"h\\":3,\\"i\\":\\"287b65e9-0aaa-42ee-ab7b-d60b3937d37a\\"},\\"panelIndex\\":\\"287b65e9-0aaa-42ee-ab7b-d60b3937d37a\\",\\"embeddableConfig\\":{\\"savedVis\\":{\\"title\\":\\"\\",\\"description\\":\\"\\",\\"type\\":\\"markdown\\",\\"params\\":{\\"fontSize\\":12,\\"openLinksInNewTab\\":false,\\"markdown\\":\\"The Host Risk Score capability is an experimental feature released in 7.14. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md).\\"},\\"uiState\\":{},\\"data\\":{\\"aggs\\":[],\\"searchSource\\":{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[]}}},\\"hidePanelTitles\\":true,\\"enhancements\\":{}},\\"title\\":\\"Note:\\"},{\\"version\\":\\"7.13.4\\",\\"type\\":\\"lens\\",\\"gridData\\":{\\"x\\":16,\\"y\\":3,\\"w\\":16,\\"h\\":15,\\"i\\":\\"654d55f8-f873-4348-96cd-5dce0b56ac32\\"},\\"panelIndex\\":\\"654d55f8-f873-4348-96cd-5dce0b56ac32\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[{\\"eventId\\":\\"b04e60d5-4e34-4589-af2e-8e9c3a15936f\\",\\"triggers\\":[\\"FILTER_TRIGGER\\"],\\"action\\":{\\"factoryId\\":\\"DASHBOARD_TO_DASHBOARD_DRILLDOWN\\",\\"name\\":\\"Go to Dashboard\\",\\"config\\":{\\"useCurrentFilters\\":true,\\"useCurrentDateRange\\":true}}}]}},\\"hidePanelTitles\\":false},\\"title\\":\\"Current Risk Scores for Hosts\\",\\"panelRefName\\":\\"panel_654d55f8-f873-4348-96cd-5dce0b56ac32\\"}]", - "timeRestore": false, - "title": "Current Risk Score for Hosts", - "version": 1, - }, - "coreMigrationVersion": "7.13.4", - "id": "id-11", - "migrationVersion": Object { - "dashboard": "7.13.1", - }, - "references": Array [ - Object { - "id": "id-10", - "name": "654d55f8-f873-4348-96cd-5dce0b56ac32:panel_654d55f8-f873-4348-96cd-5dce0b56ac32", - "type": "lens", - }, - Object { - "id": "id-8", - "name": "654d55f8-f873-4348-96cd-5dce0b56ac32:drilldown:DASHBOARD_TO_DASHBOARD_DRILLDOWN:b04e60d5-4e34-4589-af2e-8e9c3a15936f:dashboardId", - "type": "dashboard", - }, - Object { - "id": "id-7", - "name": "tag-1d00ebe0-f3b2-11eb-beb2-b91666445a94", - "type": "tag", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "dashboard", - "updated_at": "2021-08-18T17:08:00.467Z", - }, -] -`; - -exports[`createPrebuiltSavedObjects should create saved objects from given template - "userRiskScoreDashboards" 1`] = ` -Array [ - Object { - "attributes": Object { - "fieldAttrs": "{}", - "fields": "[]", - "runtimeFieldMap": "{}", - "timeFieldName": "@timestamp", - "title": "ml_user_risk_score_latest_default", - "typeMeta": "{}", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "index-pattern": "8.0.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "index-pattern", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "", - "state": Object { - "datasourceStates": Object { - "indexpattern": Object { - "layers": Object { - "b4c8cd6f-2499-4791-a0f7-01b0d3f75efc": Object { - "columnOrder": Array [ - "ba672ee7-0990-4277-9bc7-6361077efe18", - "6b6df37f-ad45-462c-aa2f-2d19af98ed98", - "daefb732-9f48-4017-a49a-979cfdeef127", - ], - "columns": Object { - "6b6df37f-ad45-462c-aa2f-2d19af98ed98": Object { - "customLabel": true, - "dataType": "number", - "isBucketed": false, - "label": "Risk Score", - "operationType": "sum", - "params": Object { - "emptyAsNull": true, - }, - "scale": "ratio", - "sourceField": "user.risk.calculated_score_norm", - }, - "ba672ee7-0990-4277-9bc7-6361077efe18": Object { - "customLabel": true, - "dataType": "string", - "isBucketed": true, - "label": "User Name", - "operationType": "terms", - "params": Object { - "missingBucket": false, - "orderBy": Object { - "columnId": "6b6df37f-ad45-462c-aa2f-2d19af98ed98", - "type": "column", - }, - "orderDirection": "desc", - "otherBucket": true, - "parentFormat": Object { - "id": "terms", - }, - "size": 30, - }, - "scale": "ordinal", - "sourceField": "user.name", - }, - "daefb732-9f48-4017-a49a-979cfdeef127": Object { - "customLabel": true, - "dataType": "string", - "filter": Object { - "language": "kuery", - "query": "", - }, - "isBucketed": false, - "label": "Current Risk", - "operationType": "last_value", - "params": Object { - "sortField": "@timestamp", - }, - "scale": "ordinal", - "sourceField": "user.risk.calculated_level", - }, - }, - "incompleteColumns": Object {}, - }, - }, - }, - }, - "filters": Array [], - "query": Object { - "language": "kuery", - "query": "", - }, - "visualization": Object { - "columns": Array [ - Object { - "columnId": "ba672ee7-0990-4277-9bc7-6361077efe18", - "isTransposed": false, - }, - Object { - "columnId": "6b6df37f-ad45-462c-aa2f-2d19af98ed98", - "hidden": true, - "isTransposed": false, - }, - Object { - "columnId": "daefb732-9f48-4017-a49a-979cfdeef127", - "isTransposed": false, - }, - ], - "layerId": "b4c8cd6f-2499-4791-a0f7-01b0d3f75efc", - "layerType": "data", - }, - }, - "title": "Current Risk Score for Users", - "visualizationType": "lnsDatatable", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "lens": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "indexpattern-datasource-layer-b4c8cd6f-2499-4791-a0f7-01b0d3f75efc", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "lens", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "fieldAttrs": "{}", - "fields": "[]", - "runtimeFieldMap": "{}", - "timeFieldName": "@timestamp", - "title": "ml_user_risk_score_default", - "typeMeta": "{}", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "index-pattern": "8.0.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "index-pattern", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "", - "state": Object { - "datasourceStates": Object { - "indexpattern": Object { - "layers": Object { - "b885eaad-3c68-49ad-9891-70158d912dbd": Object { - "columnOrder": Array [ - "1fced52d-7ba5-4254-8656-fe0d7ced586a", - "e82aed80-ee04-4ad1-9b9d-fde4a25be58a", - "3fadebce-2f31-4eed-9fc0-237249281a1a", - ], - "columns": Object { - "1fced52d-7ba5-4254-8656-fe0d7ced586a": Object { - "customLabel": true, - "dataType": "string", - "isBucketed": true, - "label": "User Name", - "operationType": "terms", - "params": Object { - "missingBucket": false, - "orderBy": Object { - "columnId": "3fadebce-2f31-4eed-9fc0-237249281a1a", - "type": "column", - }, - "orderDirection": "desc", - "otherBucket": false, - "parentFormat": Object { - "id": "terms", - }, - "size": 20, - }, - "scale": "ordinal", - "sourceField": "user.name", - }, - "3fadebce-2f31-4eed-9fc0-237249281a1a": Object { - "customLabel": true, - "dataType": "number", - "isBucketed": false, - "label": "Cumulative Risk Score", - "operationType": "max", - "params": Object { - "emptyAsNull": true, - }, - "scale": "ratio", - "sourceField": "user.risk.calculated_score_norm", - }, - "e82aed80-ee04-4ad1-9b9d-fde4a25be58a": Object { - "dataType": "date", - "isBucketed": true, - "label": "@timestamp", - "operationType": "date_histogram", - "params": Object { - "includeEmptyRows": true, - "interval": "1d", - }, - "scale": "interval", - "sourceField": "@timestamp", - }, - }, - "incompleteColumns": Object {}, - }, - }, - }, - }, - "filters": Array [], - "query": Object { - "language": "kuery", - "query": "not user.name: SYSTEM", - }, - "visualization": Object { - "layers": Array [ - Object { - "accessors": Array [ - "3fadebce-2f31-4eed-9fc0-237249281a1a", - ], - "layerId": "b885eaad-3c68-49ad-9891-70158d912dbd", - "layerType": "data", - "position": "top", - "seriesType": "bar_stacked", - "showGridlines": false, - "splitAccessor": "1fced52d-7ba5-4254-8656-fe0d7ced586a", - "xAccessor": "e82aed80-ee04-4ad1-9b9d-fde4a25be58a", - }, - ], - "legend": Object { - "isVisible": true, - "legendSize": "auto", - "position": "right", - }, - "preferredSeriesType": "bar_stacked", - "title": "Empty XY chart", - "valueLabels": "hide", - "yLeftExtent": Object { - "mode": "full", - }, - "yRightExtent": Object { - "mode": "full", - }, - }, - }, - "title": "User Risk Score (Max Risk Score Histogram)", - "visualizationType": "lnsXY", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "lens": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "indexpattern-datasource-layer-b885eaad-3c68-49ad-9891-70158d912dbd", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "lens", - "updated_at": "2022-08-12T16:31:30.450Z", - }, - Object { - "attributes": Object { - "fieldAttrs": "{}", - "fields": "[]", - "runtimeFieldMap": "{}", - "timeFieldName": "@timestamp", - "title": ".alerts-security.alerts-default", - "typeMeta": "{}", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "index-pattern": "8.0.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "index-pattern", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "", - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"user.name: root\\",\\"language\\":\\"kuery\\"},\\"filter\\":[],\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", - }, - "title": "Associated Users (Rule Breakdown)", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\\"title\\":\\"Associated Users (Rule Breakdown)\\",\\"type\\":\\"table\\",\\"aggs\\":[{\\"id\\":\\"2\\",\\"enabled\\":true,\\"type\\":\\"sum\\",\\"params\\":{\\"field\\":\\"signal.rule.risk_score\\",\\"customLabel\\":\\"Total Risk Score\\",\\"emptyAsNull\\":false},\\"schema\\":\\"metric\\"},{\\"id\\":\\"1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"params\\":{\\"customLabel\\":\\"Number of Hits\\",\\"emptyAsNull\\":false},\\"schema\\":\\"metric\\"},{\\"id\\":\\"3\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"user.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"User\\"},\\"schema\\":\\"split\\"},{\\"id\\":\\"4\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":50,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Name\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"5\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.type\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":50,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Type\\"},\\"schema\\":\\"bucket\\"}],\\"params\\":{\\"perPage\\":25,\\"showPartialRows\\":false,\\"showMetricsAtAllLevels\\":false,\\"showTotal\\":false,\\"showToolbar\\":false,\\"totalFunc\\":\\"sum\\",\\"percentageCol\\":\\"\\",\\"row\\":true,\\"autoFitRowToContent\\":true}}", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "visualization": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "visualization", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "", - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[],\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", - }, - "title": "Alerts by Hostname", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\\"title\\":\\"Alerts by Hostname\\",\\"type\\":\\"table\\",\\"aggs\\":[{\\"id\\":\\"2\\",\\"enabled\\":true,\\"type\\":\\"sum\\",\\"params\\":{\\"field\\":\\"signal.rule.risk_score\\",\\"customLabel\\":\\"Total Risk Score\\",\\"emptyAsNull\\":false},\\"schema\\":\\"metric\\"},{\\"id\\":\\"1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"params\\":{\\"customLabel\\":\\"Number of Hits\\",\\"emptyAsNull\\":false},\\"schema\\":\\"metric\\"},{\\"id\\":\\"3\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"host.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Host\\"},\\"schema\\":\\"split\\"},{\\"id\\":\\"4\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.name\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Name\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"5\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.type\\",\\"orderBy\\":\\"2\\",\\"order\\":\\"desc\\",\\"size\\":20,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Rule Type\\"},\\"schema\\":\\"bucket\\"}],\\"params\\":{\\"perPage\\":10,\\"showPartialRows\\":false,\\"showMetricsAtAllLevels\\":false,\\"showTotal\\":false,\\"showToolbar\\":false,\\"totalFunc\\":\\"sum\\",\\"percentageCol\\":\\"\\",\\"row\\":true,\\"autoFitRowToContent\\":false}}", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "visualization": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "visualization", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "", - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"not user.name : *$\\",\\"language\\":\\"kuery\\"},\\"filter\\":[],\\"indexRefName\\":\\"kibanaSavedObjectMeta.searchSourceJSON.index\\"}", - }, - "title": "User Risk Score (Tactic Breakdown)- Verbose", - "uiStateJSON": "{}", - "version": 1, - "visState": "{\\"title\\":\\"User Risk Score (Tactic Breakdown)- Verbose\\",\\"type\\":\\"table\\",\\"aggs\\":[{\\"id\\":\\"1\\",\\"enabled\\":true,\\"type\\":\\"sum\\",\\"params\\":{\\"field\\":\\"signal.rule.risk_score\\",\\"customLabel\\":\\"Total Risk Score\\",\\"emptyAsNull\\":false},\\"schema\\":\\"metric\\"},{\\"id\\":\\"3\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"user.name\\",\\"orderBy\\":\\"1\\",\\"order\\":\\"desc\\",\\"size\\":40,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":false,\\"missingBucketLabel\\":\\"Missing\\",\\"customLabel\\":\\"Username\\"},\\"schema\\":\\"split\\"},{\\"id\\":\\"5\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.threat.tactic.name\\",\\"orderBy\\":\\"1\\",\\"order\\":\\"desc\\",\\"size\\":100,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":true,\\"missingBucketLabel\\":\\"Other\\",\\"customLabel\\":\\"Tactic\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"6\\",\\"enabled\\":true,\\"type\\":\\"terms\\",\\"params\\":{\\"field\\":\\"signal.rule.threat.technique.name\\",\\"orderBy\\":\\"1\\",\\"order\\":\\"desc\\",\\"size\\":100,\\"otherBucket\\":false,\\"otherBucketLabel\\":\\"Other\\",\\"missingBucket\\":true,\\"missingBucketLabel\\":\\"Other\\",\\"customLabel\\":\\"Technique\\"},\\"schema\\":\\"bucket\\"},{\\"id\\":\\"7\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"params\\":{\\"customLabel\\":\\"Number of Hits\\",\\"emptyAsNull\\":false},\\"schema\\":\\"metric\\"}],\\"params\\":{\\"perPage\\":10,\\"showPartialRows\\":false,\\"showMetricsAtAllLevels\\":false,\\"showTotal\\":false,\\"showToolbar\\":false,\\"totalFunc\\":\\"sum\\",\\"percentageCol\\":\\"\\",\\"row\\":true,\\"autoFitRowToContent\\":false}}", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "visualization": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "kibanaSavedObjectMeta.searchSourceJSON.index", - "type": "index-pattern", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "visualization", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "color": "#6edb7f", - "description": "", - "name": "experimental", - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "tag": "8.0.0", - }, - "references": Array [ - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "tag", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "This dashboard allows users to drill down further into the details of the risk components associated with a particular user.", - "hits": 0, - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[]}", - }, - "optionsJSON": "{\\"hidePanelTitles\\":false,\\"useMargins\\":true}", - "panelsJSON": "[{\\"version\\":\\"8.3.0\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":0,\\"w\\":48,\\"h\\":3,\\"i\\":\\"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195\\"},\\"panelIndex\\":\\"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195\\",\\"embeddableConfig\\":{\\"savedVis\\":{\\"title\\":\\"\\",\\"description\\":\\"\\",\\"type\\":\\"markdown\\",\\"params\\":{\\"fontSize\\":12,\\"openLinksInNewTab\\":false,\\"markdown\\":\\"The User Risk Score capability is an experimental feature. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md).\\"},\\"uiState\\":{},\\"data\\":{\\"aggs\\":[],\\"searchSource\\":{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[]}}},\\"hidePanelTitles\\":true,\\"enhancements\\":{}}},{\\"version\\":\\"8.3.0\\",\\"type\\":\\"lens\\",\\"gridData\\":{\\"x\\":0,\\"y\\":3,\\"w\\":48,\\"h\\":15,\\"i\\":\\"b3fdccab-59c1-47c8-9393-fa043e0dff83\\"},\\"panelIndex\\":\\"b3fdccab-59c1-47c8-9393-fa043e0dff83\\",\\"embeddableConfig\\":{\\"enhancements\\":{},\\"hidePanelTitles\\":false},\\"title\\":\\"Cumulative User Risk Score (multiple users)\\",\\"panelRefName\\":\\"panel_b3fdccab-59c1-47c8-9393-fa043e0dff83\\"},{\\"version\\":\\"8.3.0\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":18,\\"w\\":24,\\"h\\":45,\\"i\\":\\"8d09b97c-a023-4b7e-9e9d-1c46e726a487\\"},\\"panelIndex\\":\\"8d09b97c-a023-4b7e-9e9d-1c46e726a487\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[]}},\\"hidePanelTitles\\":false,\\"vis\\":{\\"params\\":{\\"colWidth\\":[{\\"colIndex\\":0,\\"width\\":410.5}]}}},\\"title\\":\\"Alert Counts by User\\",\\"panelRefName\\":\\"panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487\\"},{\\"version\\":\\"8.3.0\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":24,\\"y\\":18,\\"w\\":24,\\"h\\":45,\\"i\\":\\"cae82aa1-20c8-4354-94ab-3934ac53b8fe\\"},\\"panelIndex\\":\\"cae82aa1-20c8-4354-94ab-3934ac53b8fe\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[]}},\\"hidePanelTitles\\":false,\\"vis\\":{\\"params\\":{\\"colWidth\\":[{\\"colIndex\\":0,\\"width\\":304}]}}},\\"title\\":\\"Alert Counts by Host\\",\\"panelRefName\\":\\"panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe\\"},{\\"version\\":\\"8.3.0\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":63,\\"w\\":48,\\"h\\":15,\\"i\\":\\"ca3c8903-be5d-4265-820c-cc3d67443af2\\"},\\"panelIndex\\":\\"ca3c8903-be5d-4265-820c-cc3d67443af2\\",\\"embeddableConfig\\":{\\"enhancements\\":{},\\"hidePanelTitles\\":false},\\"title\\":\\"Tactic Breakdown of Risky Users\\",\\"panelRefName\\":\\"panel_ca3c8903-be5d-4265-820c-cc3d67443af2\\"}]", - "refreshInterval": Object { - "pause": false, - "value": 0, - }, - "timeFrom": "now-1w", - "timeRestore": true, - "timeTo": "now", - "title": "Drilldown of User Risk Score", - "version": 1, - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "dashboard": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "b3fdccab-59c1-47c8-9393-fa043e0dff83:panel_b3fdccab-59c1-47c8-9393-fa043e0dff83", - "type": "lens", - }, - Object { - "id": "", - "name": "8d09b97c-a023-4b7e-9e9d-1c46e726a487:panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487", - "type": "visualization", - }, - Object { - "id": "", - "name": "cae82aa1-20c8-4354-94ab-3934ac53b8fe:panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe", - "type": "visualization", - }, - Object { - "id": "", - "name": "ca3c8903-be5d-4265-820c-cc3d67443af2:panel_ca3c8903-be5d-4265-820c-cc3d67443af2", - "type": "visualization", - }, - Object { - "id": "", - "name": "tag-93fc0f00-1a57-11ed-bb53-ad8c26f4d942", - "type": "tag", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "dashboard", - "updated_at": "2022-08-12T16:20:10.121Z", - }, - Object { - "attributes": Object { - "description": "", - "hits": 0, - "kibanaSavedObjectMeta": Object { - "searchSourceJSON": "{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[]}", - }, - "optionsJSON": "{\\"useMargins\\":true,\\"syncColors\\":false,\\"syncTooltips\\":false,\\"hidePanelTitles\\":false}", - "panelsJSON": "[{\\"version\\":\\"8.3.0\\",\\"type\\":\\"visualization\\",\\"gridData\\":{\\"x\\":0,\\"y\\":0,\\"w\\":48,\\"h\\":3,\\"i\\":\\"02f0548a-aae6-460f-9300-be42b4ae9a1e\\"},\\"panelIndex\\":\\"02f0548a-aae6-460f-9300-be42b4ae9a1e\\",\\"embeddableConfig\\":{\\"savedVis\\":{\\"id\\":\\"\\",\\"title\\":\\"\\",\\"description\\":\\"\\",\\"type\\":\\"markdown\\",\\"params\\":{\\"fontSize\\":12,\\"openLinksInNewTab\\":false,\\"markdown\\":\\"User Risk Score is an experimental feature. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md).\\"},\\"uiState\\":{},\\"data\\":{\\"aggs\\":[],\\"searchSource\\":{\\"query\\":{\\"query\\":\\"\\",\\"language\\":\\"kuery\\"},\\"filter\\":[]}}},\\"hidePanelTitles\\":true,\\"enhancements\\":{}}},{\\"version\\":\\"8.3.0\\",\\"type\\":\\"lens\\",\\"gridData\\":{\\"x\\":17,\\"y\\":3,\\"w\\":14,\\"h\\":15,\\"i\\":\\"1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5\\"},\\"panelIndex\\":\\"1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5\\",\\"embeddableConfig\\":{\\"enhancements\\":{\\"dynamicActions\\":{\\"events\\":[{\\"eventId\\":\\"d26cff88-a061-494e-abb1-958216009585\\",\\"triggers\\":[\\"FILTER_TRIGGER\\"],\\"action\\":{\\"factoryId\\":\\"DASHBOARD_TO_DASHBOARD_DRILLDOWN\\",\\"name\\":\\"Go to Dashboard\\",\\"config\\":{\\"useCurrentFilters\\":true,\\"useCurrentDateRange\\":true,\\"openInNewTab\\":false}}}]}},\\"hidePanelTitles\\":false},\\"title\\":\\"Current Risk Scores for Users\\",\\"panelRefName\\":\\"panel_1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5\\"}]", - "refreshInterval": Object { - "pause": false, - "value": 0, - }, - "timeFrom": "now-1w", - "timeRestore": true, - "timeTo": "now", - "title": "Current Risk Score for Users", - "version": 1, - }, - "coreMigrationVersion": "8.3.0", - "id": "", - "migrationVersion": Object { - "dashboard": "8.3.0", - }, - "references": Array [ - Object { - "id": "", - "name": "1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5:panel_1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5", - "type": "lens", - }, - Object { - "id": "", - "name": "1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5:drilldown:DASHBOARD_TO_DASHBOARD_DRILLDOWN:d26cff88-a061-494e-abb1-958216009585:dashboardId", - "type": "dashboard", - }, - Object { - "id": "", - "name": "tag-93fc0f00-1a57-11ed-bb53-ad8c26f4d942", - "type": "tag", - }, - Object { - "id": "mockTagId", - "name": "my tag", - "type": "tag", - }, - ], - "type": "dashboard", - "updated_at": "2022-08-12T16:20:10.121Z", - }, -] -`; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.test.ts deleted file mode 100644 index 300012738134d..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.test.ts +++ /dev/null @@ -1,93 +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 { Logger } from '@kbn/core/server'; -import { PREBUILT_SAVED_OBJECTS_BULK_CREATE } from '../../../../../common/constants'; -import { - serverMock, - requestContextMock, - requestMock, -} from '../../../detection_engine/routes/__mocks__'; -import { getEmptySavedObjectsResponse } from '../../../detection_engine/routes/__mocks__/request_responses'; -import { createRiskScoreTag } from '../helpers/create_risk_score_tag'; -import { createPrebuiltSavedObjectsRoute } from './create_prebuilt_saved_objects'; - -jest.mock('../helpers/create_risk_score_tag', () => { - const actual = jest.requireActual('../helpers/create_risk_score_tag'); - return { - ...actual, - createRiskScoreTag: jest.fn(), - }; -}); - -jest.mock('uuid', () => { - return { - v4: jest - .fn() - .mockReturnValueOnce('id-1') - .mockReturnValueOnce('id-2') - .mockReturnValueOnce('id-3') - .mockReturnValueOnce('id-4') - .mockReturnValueOnce('id-5') - .mockReturnValueOnce('id-6') - .mockReturnValueOnce('id-7') - .mockReturnValueOnce('id-8') - .mockReturnValueOnce('id-9') - .mockReturnValueOnce('id-10') - .mockReturnValueOnce('id-11'), - }; -}); - -const createPrebuiltSavedObjectsRequest = (savedObjectTemplate: string) => - requestMock.create({ - method: 'post', - path: PREBUILT_SAVED_OBJECTS_BULK_CREATE, - params: { template_name: savedObjectTemplate }, - }); - -describe('createPrebuiltSavedObjects', () => { - let server: ReturnType; - let { clients, context } = requestContextMock.createTools(); - const logger = { error: jest.fn() } as unknown as Logger; - - beforeEach(() => { - jest.clearAllMocks(); - - server = serverMock.create(); - ({ clients, context } = requestContextMock.createTools()); - - clients.savedObjectsClient.bulkCreate.mockResolvedValue(getEmptySavedObjectsResponse()); - - createPrebuiltSavedObjectsRoute(server.router, logger); - }); - - it.each([['hostRiskScoreDashboards'], ['userRiskScoreDashboards']])( - 'should create saved objects from given template - %p', - async (templateName) => { - (createRiskScoreTag as jest.Mock).mockResolvedValue({ - [templateName]: { - success: true, - error: null, - body: { - id: 'mockTagId', - name: 'my tag', - description: 'description', - type: 'tag', - }, - }, - }); - const response = await server.inject( - createPrebuiltSavedObjectsRequest(templateName), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.bulkCreate.mock.calls[0][1]).toEqual({ overwrite: true }); - expect(clients.savedObjectsClient.bulkCreate.mock.calls[0][0]).toMatchSnapshot(); - - expect(response.status).toEqual(200); - } - ); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts deleted file mode 100644 index 2ccccc4bab787..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Logger } from '@kbn/core/server'; - -import { PREBUILT_SAVED_OBJECTS_BULK_CREATE } from '../../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; - -import { buildSiemResponse } from '../../../detection_engine/routes/utils'; - -import { buildFrameworkRequest } from '../../../timeline/utils/common'; -import { bulkCreateSavedObjects } from '../helpers/bulk_create_saved_objects'; -import { createPrebuiltSavedObjectsRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -export const createPrebuiltSavedObjectsRoute = ( - router: SecuritySolutionPluginRouter, - logger: Logger -) => { - router.versioned - .post({ - access: 'internal', - path: PREBUILT_SAVED_OBJECTS_BULK_CREATE, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { - validate: { - request: createPrebuiltSavedObjectsRequestBody, - }, - version: '1', - }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { template_name: templateName } = request.params; - - const securitySolution = await context.securitySolution; - - const spaceId = securitySolution?.getSpaceId(); - - const frameworkRequest = await buildFrameworkRequest(context, request); - const savedObjectsClient = (await frameworkRequest.context.core).savedObjects.client; - const result = await bulkCreateSavedObjects({ - savedObjectsClient, - logger, - spaceId, - savedObjectTemplate: templateName, - }); - const error = - result?.hostRiskScoreDashboards?.error || result?.userRiskScoreDashboards?.error; - if (error != null) { - return siemResponse.error({ statusCode: error.statusCode, body: error.message }); - } else { - return response.ok({ body: result }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.test.ts deleted file mode 100644 index 37c2417340fcd..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.test.ts +++ /dev/null @@ -1,269 +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 { PREBUILT_SAVED_OBJECTS_BULK_DELETE } from '../../../../../common/constants'; -import { - serverMock, - requestContextMock, - requestMock, -} from '../../../detection_engine/routes/__mocks__'; -import { deletePrebuiltSavedObjectsRoute } from './delete_prebuilt_saved_objects'; - -jest.mock('../../../tags/saved_objects', () => { - return { - findTagsByName: jest.fn().mockResolvedValue([ - { - id: 'tagID', - name: 'my tag', - type: 'tag', - }, - ]), - }; -}); - -jest.mock('../helpers/create_risk_score_tag', () => { - const actual = jest.requireActual('../helpers/create_risk_score_tag'); - return { - ...actual, - findSavedObjectsWithTagReference: jest - .fn() - .mockResolvedValue([{ id: 'test-1', type: 'test-type' }]), - }; -}); - -const deletePrebuiltSavedObjectsRequest = (savedObjectTemplate: string) => - requestMock.create({ - method: 'post', - path: PREBUILT_SAVED_OBJECTS_BULK_DELETE, - params: { template_name: savedObjectTemplate }, - body: { - deleteAll: true, - }, - }); - -describe('deletePrebuiltSavedObjects', () => { - let server: ReturnType; - let { clients, context } = requestContextMock.createTools(); - - beforeEach(() => { - jest.clearAllMocks(); - - server = serverMock.create(); - ({ clients, context } = requestContextMock.createTools()); - - clients.savedObjectsClient.delete.mockResolvedValue(''); - - deletePrebuiltSavedObjectsRoute(server.router); - }); - - it('should delete legacy hostRiskScoreDashboards', async () => { - const response = await server.inject( - deletePrebuiltSavedObjectsRequest('hostRiskScoreDashboards'), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.delete.mock.calls[0][1]).toMatchInlineSnapshot( - `"ml-host-risk-score-default-index-pattern"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[0][0]).toMatchInlineSnapshot( - `"index-pattern"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[1][1]).toMatchInlineSnapshot( - `"d3f72670-d3a0-11eb-bd37-7bb50422e346"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[1][0]).toMatchInlineSnapshot(`"lens"`); - - expect(clients.savedObjectsClient.delete.mock.calls[2][1]).toMatchInlineSnapshot( - `"alerts-default-index-pattern"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[2][0]).toMatchInlineSnapshot( - `"index-pattern"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[3][1]).toMatchInlineSnapshot( - `"42371d00-cf7a-11eb-9a96-05d89f94ad96"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[3][0]).toMatchInlineSnapshot( - `"visualization"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[4][1]).toMatchInlineSnapshot( - `"a62d3ed0-cf92-11eb-a0ff-1763d16cbda7"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[4][0]).toMatchInlineSnapshot( - `"visualization"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[5][1]).toMatchInlineSnapshot( - `"b2dbc9b0-cf94-11eb-bd37-7bb50422e346"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[5][0]).toMatchInlineSnapshot( - `"visualization"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[6][1]).toMatchInlineSnapshot( - `"1d00ebe0-f3b2-11eb-beb2-b91666445a94"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[6][0]).toMatchInlineSnapshot(`"tag"`); - - expect(clients.savedObjectsClient.delete.mock.calls[7][1]).toMatchInlineSnapshot( - `"6f05c8c0-cf77-11eb-9a96-05d89f94ad96"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[7][0]).toMatchInlineSnapshot(`"dashboard"`); - - expect(clients.savedObjectsClient.delete.mock.calls[8][1]).toMatchInlineSnapshot( - `"ml-host-risk-score-latest-default-index-pattern"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[8][0]).toMatchInlineSnapshot( - `"index-pattern"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[9][1]).toMatchInlineSnapshot( - `"dc289c10-d4ff-11eb-a0ff-1763d16cbda7"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[9][0]).toMatchInlineSnapshot(`"lens"`); - - expect(clients.savedObjectsClient.delete.mock.calls[10][1]).toMatchInlineSnapshot( - `"27b483b0-d500-11eb-a0ff-1763d16cbda7"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[10][0]).toMatchInlineSnapshot( - `"dashboard"` - ); - - expect(response.status).toEqual(200); - }); - - it('should delete all hostRiskScoreDashboards saved objects with given tag reference if deleteAll is true', async () => { - const response = await server.inject( - deletePrebuiltSavedObjectsRequest('hostRiskScoreDashboards'), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.delete.mock.calls[11][1]).toMatchInlineSnapshot(`"test-1"`); - expect(clients.savedObjectsClient.delete.mock.calls[11][0]).toMatchInlineSnapshot( - `"test-type"` - ); - - expect(response.status).toEqual(200); - }); - - it('should delete the tag linked to hostRiskScoreDashboards saved objects if deleteAll is true', async () => { - const response = await server.inject( - deletePrebuiltSavedObjectsRequest('hostRiskScoreDashboards'), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.delete.mock.calls[12][1]).toMatchInlineSnapshot(`"tagID"`); - expect(clients.savedObjectsClient.delete.mock.calls[12][0]).toMatchInlineSnapshot(`"tag"`); - - expect(response.status).toEqual(200); - }); - - it('should delete legacy userRiskScoreDashboards', async () => { - const response = await server.inject( - deletePrebuiltSavedObjectsRequest('userRiskScoreDashboards'), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.delete.mock.calls[0][1]).toMatchInlineSnapshot( - `"ml-user-risk-score-latest-default-index-pattern"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[0][0]).toMatchInlineSnapshot( - `"index-pattern"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[1][1]).toMatchInlineSnapshot( - `"54dadd60-1a57-11ed-bb53-ad8c26f4d942"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[1][0]).toMatchInlineSnapshot(`"lens"`); - - expect(clients.savedObjectsClient.delete.mock.calls[2][1]).toMatchInlineSnapshot( - `"ml-user-risk-score-default-index-pattern"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[2][0]).toMatchInlineSnapshot( - `"index-pattern"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[3][1]).toMatchInlineSnapshot( - `"60454070-9a5d-11ec-9633-5f782d122340"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[3][0]).toMatchInlineSnapshot(`"lens"`); - - expect(clients.savedObjectsClient.delete.mock.calls[4][1]).toMatchInlineSnapshot( - `"alerts-default-index-pattern"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[4][0]).toMatchInlineSnapshot( - `"index-pattern"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[5][1]).toMatchInlineSnapshot( - `"a62d3ed0-cf92-11eb-a0ff-1763d16cbda7"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[5][0]).toMatchInlineSnapshot( - `"visualization"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[6][1]).toMatchInlineSnapshot( - `"42371d00-cf7a-11eb-9a96-05d89f94ad96"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[6][0]).toMatchInlineSnapshot( - `"visualization"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[7][1]).toMatchInlineSnapshot( - `"183d32f0-9a5e-11ec-90d3-1109ed409ab5"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[7][0]).toMatchInlineSnapshot( - `"visualization"` - ); - - expect(clients.savedObjectsClient.delete.mock.calls[8][1]).toMatchInlineSnapshot( - `"93fc0f00-1a57-11ed-bb53-ad8c26f4d942"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[8][0]).toMatchInlineSnapshot(`"tag"`); - - expect(clients.savedObjectsClient.delete.mock.calls[9][1]).toMatchInlineSnapshot( - `"1355b030-ca2b-11ec-962f-a3a018b7d10f"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[9][0]).toMatchInlineSnapshot(`"dashboard"`); - - expect(clients.savedObjectsClient.delete.mock.calls[10][1]).toMatchInlineSnapshot( - `"8ac3ad30-1a57-11ed-bb53-ad8c26f4d942"` - ); - expect(clients.savedObjectsClient.delete.mock.calls[10][0]).toMatchInlineSnapshot( - `"dashboard"` - ); - - expect(response.status).toEqual(200); - }); - - it('should delete all userRiskScoreDashboards saved objects with given tag reference if deleteAll is true', async () => { - const response = await server.inject( - deletePrebuiltSavedObjectsRequest('userRiskScoreDashboards'), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.delete.mock.calls[11][1]).toMatchInlineSnapshot(`"test-1"`); - expect(clients.savedObjectsClient.delete.mock.calls[11][0]).toMatchInlineSnapshot( - `"test-type"` - ); - - expect(response.status).toEqual(200); - }); - - it('should delete the tag linked to userRiskScoreDashboards saved objects if deleteAll is true', async () => { - const response = await server.inject( - deletePrebuiltSavedObjectsRequest('userRiskScoreDashboards'), - requestContextMock.convertContext(context) - ); - - expect(clients.savedObjectsClient.delete.mock.calls[12][1]).toMatchInlineSnapshot(`"tagID"`); - expect(clients.savedObjectsClient.delete.mock.calls[12][0]).toMatchInlineSnapshot(`"tag"`); - - expect(response.status).toEqual(200); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts deleted file mode 100644 index 7e772e710cc93..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; - -import { PREBUILT_SAVED_OBJECTS_BULK_DELETE } from '../../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../../types'; - -import { buildSiemResponse } from '../../../detection_engine/routes/utils'; - -import { buildFrameworkRequest } from '../../../timeline/utils/common'; -import { bulkDeleteSavedObjects } from '../helpers/bulk_delete_saved_objects'; -import { deletePrebuiltSavedObjectsRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -export const deletePrebuiltSavedObjectsRoute = (router: SecuritySolutionPluginRouter) => { - router.versioned - .post({ - access: 'internal', - path: PREBUILT_SAVED_OBJECTS_BULK_DELETE, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { validate: { request: deletePrebuiltSavedObjectsRequestBody }, version: '1' }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { template_name: templateName } = request.params; - const deleteAll = request?.body?.deleteAll; - - try { - const securitySolution = await context.securitySolution; - - const spaceId = securitySolution?.getSpaceId(); - - const frameworkRequest = await buildFrameworkRequest(context, request); - const savedObjectsClient = (await frameworkRequest.context.core).savedObjects.client; - - const res = await bulkDeleteSavedObjects({ - deleteAll, - savedObjectsClient, - spaceId, - savedObjectTemplate: templateName, - }); - - return response.ok({ - body: res, - }); - } catch (err) { - const error = transformError(err); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts deleted file mode 100644 index 8b80748694369..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/host_risk_score_dashboards.ts +++ /dev/null @@ -1,417 +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 { SavedObject } from '@kbn/core/types'; -import { RiskScoreFields } from '../../../../../common/search_strategy'; - -export const hostRiskScoreDashboards: SavedObject[] = [ - { - attributes: { - fieldAttrs: '{}', - fields: '[]', - runtimeFieldMap: '{}', - timeFieldName: '@timestamp', - title: 'ml_host_risk_score_', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { 'index-pattern': '7.11.0' }, - references: [], - type: 'index-pattern', - updated_at: '2021-08-18T18:37:41.486Z', - }, - { - attributes: { - description: null, - state: { - datasourceStates: { - indexpattern: { - layers: { - 'b885eaad-3c68-49ad-9891-70158d912dbd': { - columnOrder: [ - '8dcda7ec-1a1a-43b3-b0b8-e702943eed5c', - 'e82aed80-ee04-4ad1-9b9d-fde4a25be58a', - 'aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b', - ], - columns: { - '8dcda7ec-1a1a-43b3-b0b8-e702943eed5c': { - customLabel: true, - dataType: 'string', - isBucketed: true, - label: 'Host Name', - operationType: 'terms', - params: { - missingBucket: false, - orderBy: { columnId: 'aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b', type: 'column' }, - orderDirection: 'desc', - otherBucket: true, - size: 20, - }, - scale: 'ordinal', - sourceField: RiskScoreFields.hostName, - }, - 'aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: 'Cumulative Risk Score', - operationType: 'max', - scale: 'ratio', - sourceField: RiskScoreFields.hostRiskScore, - }, - 'e82aed80-ee04-4ad1-9b9d-fde4a25be58a': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { interval: '1h' }, - scale: 'interval', - sourceField: '@timestamp', - }, - }, - incompleteColumns: {}, - }, - }, - }, - }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - layers: [ - { - accessors: ['aa4ad9b2-8829-4517-aaa8-7ed7e5793e9b'], - layerId: 'b885eaad-3c68-49ad-9891-70158d912dbd', - palette: { name: 'default', type: 'palette' }, - position: 'top', - seriesType: 'bar_stacked', - showGridlines: false, - splitAccessor: '8dcda7ec-1a1a-43b3-b0b8-e702943eed5c', - xAccessor: 'e82aed80-ee04-4ad1-9b9d-fde4a25be58a', - }, - ], - legend: { isVisible: true, position: 'right' }, - preferredSeriesType: 'bar_stacked', - title: 'Empty XY chart', - valueLabels: 'hide', - }, - }, - title: 'Host Risk Score (Max Risk Score Histogram)', - visualizationType: 'lnsXY', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { lens: '7.13.1' }, - references: [ - { - id: '', - name: 'indexpattern-datasource-current-indexpattern', - type: 'index-pattern', - }, - { - id: '', - name: 'indexpattern-datasource-layer-b885eaad-3c68-49ad-9891-70158d912dbd', - type: 'index-pattern', - }, - ], - type: 'lens', - updated_at: '2021-08-18T18:48:30.689Z', - }, - { - attributes: { - fieldAttrs: '{"signal.rule.type":{"count":1}}', - fields: '[]', - runtimeFieldMap: '{}', - timeFieldName: '@timestamp', - title: '.alerts-security.alerts-', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { 'index-pattern': '7.11.0' }, - references: [], - type: 'index-pattern', - updated_at: '2021-08-18T16:27:39.980Z', - }, - { - attributes: { - description: '', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"query":{"query":"","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - title: 'Host Risk Score (Rule Breakdown)', - uiStateJSON: '{}', - version: 1, - visState: - '{"title":"Host Risk Score (Rule Breakdown)","type":"table","aggs":[{"id":"2","enabled":true,"type":"sum","params":{"field":"signal.rule.risk_score","customLabel":"Total Risk Score"},"schema":"metric"},{"id":"1","enabled":true,"type":"count","params":{"customLabel":"Number of Hits"},"schema":"metric"},{"id":"3","enabled":true,"type":"terms","params":{"field":"host.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Host"},"schema":"split"},{"id":"4","enabled":true,"type":"terms","params":{"field":"signal.rule.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Name"},"schema":"bucket"},{"id":"5","enabled":true,"type":"terms","params":{"field":"signal.rule.type","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Type"},"schema":"bucket"}],"params":{"perPage":10,"showPartialRows":false,"showMetricsAtAllLevels":false,"showTotal":false,"showToolbar":false,"totalFunc":"sum","percentageCol":"","row":true}}', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { visualization: '7.13.1' }, - references: [ - { - id: '', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - }, - ], - type: 'visualization', - updated_at: '2021-08-18T16:27:39.980Z', - }, - { - attributes: { - description: '', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"query":{"query":"not user.name: *$","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - title: 'Associated Users (Rule Breakdown)', - uiStateJSON: '{}', - version: 1, - visState: - '{"title":"Associated Users (Rule Breakdown)","type":"table","aggs":[{"id":"2","enabled":true,"type":"sum","params":{"field":"signal.rule.risk_score","customLabel":"Total Risk Score"},"schema":"metric"},{"id":"1","enabled":true,"type":"count","params":{"customLabel":"Number of Hits"},"schema":"metric"},{"id":"3","enabled":true,"type":"terms","params":{"field":"user.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"User"},"schema":"split"},{"id":"4","enabled":true,"type":"terms","params":{"field":"signal.rule.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Name"},"schema":"bucket"},{"id":"5","enabled":true,"type":"terms","params":{"field":"signal.rule.type","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Type"},"schema":"bucket"}],"params":{"perPage":10,"showPartialRows":false,"showMetricsAtAllLevels":false,"showTotal":false,"showToolbar":false,"totalFunc":"sum","percentageCol":"","row":true}}', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { visualization: '7.13.1' }, - references: [ - { - id: '', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - }, - ], - type: 'visualization', - updated_at: '2021-08-18T16:27:39.980Z', - }, - { - attributes: { - description: '', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"query":{"query":"","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - title: 'Host Risk Score (Tactic Breakdown)- Verbose', - uiStateJSON: '{}', - version: 1, - visState: - '{"title":"Host Risk Score (Tactic Breakdown)- Verbose","type":"table","aggs":[{"id":"1","enabled":true,"type":"sum","params":{"field":"signal.rule.risk_score","customLabel":"Total Risk Score"},"schema":"metric"},{"id":"3","enabled":true,"type":"terms","params":{"field":"host.name","orderBy":"1","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Host"},"schema":"split"},{"id":"5","enabled":true,"type":"terms","params":{"field":"signal.rule.threat.tactic.name","orderBy":"1","order":"desc","size":50,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":true,"missingBucketLabel":"Other","customLabel":"Tactic"},"schema":"bucket"},{"id":"6","enabled":true,"type":"terms","params":{"field":"signal.rule.threat.technique.name","orderBy":"1","order":"desc","size":50,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":true,"missingBucketLabel":"Other","customLabel":"Technique"},"schema":"bucket"},{"id":"7","enabled":true,"type":"count","params":{"customLabel":"Number of Hits"},"schema":"metric"}],"params":{"perPage":10,"showPartialRows":false,"showMetricsAtAllLevels":false,"showTotal":false,"showToolbar":false,"totalFunc":"sum","percentageCol":"","row":true}}', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { visualization: '7.13.1' }, - references: [ - { - id: '', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - }, - ], - type: 'visualization', - updated_at: '2021-08-18T16:27:39.980Z', - }, - { - attributes: { color: '#D36086', description: '', name: 'experimental' }, - coreMigrationVersion: '7.13.4', - id: '', - references: [], - type: 'tag', - updated_at: '2021-08-18T16:27:39.980Z', - }, - { - attributes: { - description: - 'This dashboard allows users to drill down further into the details of the risk components associated with a particular host.', - hits: 0, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"language":"kuery","query":""},"filter":[]}', - }, - optionsJSON: '{"hidePanelTitles":false,"useMargins":true}', - panelsJSON: - '[{"version":"7.13.4","type":"visualization","gridData":{"x":0,"y":0,"w":48,"h":3,"i":"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195"},"panelIndex":"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195","embeddableConfig":{"savedVis":{"title":"","description":"","type":"markdown","params":{"fontSize":12,"openLinksInNewTab":false,"markdown":"The Host Risk Score capability is an experimental feature released in 7.14. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md)."},"uiState":{},"data":{"aggs":[],"searchSource":{"query":{"query":"","language":"kuery"},"filter":[]}}},"hidePanelTitles":true,"enhancements":{}}},{"version":"7.13.4","type":"lens","gridData":{"x":0,"y":3,"w":48,"h":15,"i":"e11ed08e-70d0-4c69-991a-12e20dc89440"},"panelIndex":"e11ed08e-70d0-4c69-991a-12e20dc89440","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[{"eventId":"339da811-5c23-4432-9649-53cb066e6aaf","triggers":["VALUE_CLICK_TRIGGER"],"action":{"factoryId":"URL_DRILLDOWN","name":"Go to Host View","config":{"url":{"template":"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}"},"openInNewTab":true,"encodeUrl":true}}}]}},"hidePanelTitles":false},"title":"Cumulative Host Risk Score (multiple hosts)","panelRefName":"panel_e11ed08e-70d0-4c69-991a-12e20dc89440"},{"version":"7.13.4","type":"visualization","gridData":{"x":0,"y":18,"w":24,"h":28,"i":"cae82aa1-20c8-4354-94ab-3934ac53b8fe"},"panelIndex":"cae82aa1-20c8-4354-94ab-3934ac53b8fe","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[{"eventId":"0fd43778-bd5d-4b2b-85c3-47ac3b756434","triggers":["VALUE_CLICK_TRIGGER"],"action":{"factoryId":"URL_DRILLDOWN","name":"Go to Host View","config":{"url":{"template":"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}"},"openInNewTab":true,"encodeUrl":true}}}]}},"hidePanelTitles":false},"title":"Associated Rules of Risky Hosts","panelRefName":"panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe"},{"version":"7.13.4","type":"visualization","gridData":{"x":24,"y":18,"w":24,"h":28,"i":"8d09b97c-a023-4b7e-9e9d-1c46e726a487"},"panelIndex":"8d09b97c-a023-4b7e-9e9d-1c46e726a487","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[{"eventId":"593ff0e6-25da-47ad-b81d-9a0106c0e9aa","triggers":["VALUE_CLICK_TRIGGER"],"action":{"factoryId":"URL_DRILLDOWN","name":"Go to Host View","config":{"url":{"template":"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}"},"openInNewTab":true,"encodeUrl":true}}}]}},"hidePanelTitles":false},"title":"Associated Users of Risky Hosts","panelRefName":"panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487"},{"version":"7.13.4","type":"visualization","gridData":{"x":0,"y":46,"w":48,"h":16,"i":"0c9c8318-ebb0-47fb-919a-1836ebf232ae"},"panelIndex":"0c9c8318-ebb0-47fb-919a-1836ebf232ae","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[{"eventId":"a76ea63c-da92-4bad-b3d6-6df823e1c04b","triggers":["VALUE_CLICK_TRIGGER"],"action":{"factoryId":"URL_DRILLDOWN","name":"Go to Host View","config":{"url":{"template":"{{kibanaUrl}}/app/security/hosts/{{context.panel.filters.[0].meta.params.query}}"},"openInNewTab":true,"encodeUrl":true}}}]}},"hidePanelTitles":false},"title":"Tactic Breakdown of Risky Hosts (Verbose)","panelRefName":"panel_0c9c8318-ebb0-47fb-919a-1836ebf232ae"}]', - timeRestore: false, - title: 'Drilldown of Host Risk Score', - version: 1, - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { dashboard: '7.13.1' }, - references: [ - { - id: '', - name: 'e11ed08e-70d0-4c69-991a-12e20dc89440:panel_e11ed08e-70d0-4c69-991a-12e20dc89440', - type: 'lens', - }, - { - id: '', - name: 'cae82aa1-20c8-4354-94ab-3934ac53b8fe:panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe', - type: 'visualization', - }, - { - id: '', - name: '8d09b97c-a023-4b7e-9e9d-1c46e726a487:panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487', - type: 'visualization', - }, - { - id: '', - name: '0c9c8318-ebb0-47fb-919a-1836ebf232ae:panel_0c9c8318-ebb0-47fb-919a-1836ebf232ae', - type: 'visualization', - }, - { - id: '', - name: 'tag-1d00ebe0-f3b2-11eb-beb2-b91666445a94', - type: 'tag', - }, - ], - type: 'dashboard', - updated_at: '2021-08-18T17:09:15.576Z', - }, - { - attributes: { - fieldAttrs: '{}', - fields: '[]', - runtimeFieldMap: '{}', - timeFieldName: '@timestamp', - title: 'ml_host_risk_score_latest_', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { 'index-pattern': '7.11.0' }, - references: [], - type: 'index-pattern', - updated_at: '2021-08-18T18:47:22.500Z', - }, - { - attributes: { - description: null, - state: { - datasourceStates: { - indexpattern: { - layers: { - '2f34d626-d0ee-4ade-9e75-13c480699485': { - columnOrder: [ - '9c8c581f-6cb8-4ecf-8eb3-4c6df33edc5d', - 'c547501b-fe04-4073-8b4e-dbbdc3a4ff04', - 'e2444d64-721a-4532-9633-5b206eee76d6', - ], - columns: { - '9c8c581f-6cb8-4ecf-8eb3-4c6df33edc5d': { - customLabel: true, - dataType: 'string', - isBucketed: true, - label: 'Host Name', - operationType: 'terms', - params: { - missingBucket: false, - orderBy: { columnId: 'c547501b-fe04-4073-8b4e-dbbdc3a4ff04', type: 'column' }, - orderDirection: 'desc', - otherBucket: true, - size: 20, - }, - scale: 'ordinal', - sourceField: RiskScoreFields.hostName, - }, - 'c547501b-fe04-4073-8b4e-dbbdc3a4ff04': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: 'Risk Score', - operationType: 'sum', - scale: 'ratio', - sourceField: RiskScoreFields.hostRiskScore, - }, - 'e2444d64-721a-4532-9633-5b206eee76d6': { - customLabel: true, - dataType: 'string', - isBucketed: false, - label: 'Current Risk', - operationType: 'last_value', - params: { sortField: '@timestamp' }, - scale: 'ordinal', - sourceField: RiskScoreFields.hostRisk, - }, - }, - incompleteColumns: {}, - }, - }, - }, - }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - columns: [ - { columnId: '9c8c581f-6cb8-4ecf-8eb3-4c6df33edc5d', isTransposed: false }, - { - alignment: 'left', - columnId: 'c547501b-fe04-4073-8b4e-dbbdc3a4ff04', - hidden: true, - isTransposed: false, - }, - { columnId: 'e2444d64-721a-4532-9633-5b206eee76d6', isTransposed: false }, - ], - layerId: '2f34d626-d0ee-4ade-9e75-13c480699485', - }, - }, - title: 'Current Risk Score for Hosts', - visualizationType: 'lnsDatatable', - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { lens: '7.13.1' }, - references: [ - { - id: '', - name: 'indexpattern-datasource-current-indexpattern', - type: 'index-pattern', - }, - { - id: '', - name: 'indexpattern-datasource-layer-2f34d626-d0ee-4ade-9e75-13c480699485', - type: 'index-pattern', - }, - ], - type: 'lens', - updated_at: '2021-08-18T17:07:41.806Z', - }, - { - attributes: { - description: - 'This dashboard shows the most current list of risky hosts (Top 20) in an environment. ', - hits: 0, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"language":"kuery","query":""},"filter":[]}', - }, - optionsJSON: '{"hidePanelTitles":false,"useMargins":true}', - panelsJSON: - '[{"version":"7.13.4","type":"visualization","gridData":{"x":0,"y":0,"w":48,"h":3,"i":"287b65e9-0aaa-42ee-ab7b-d60b3937d37a"},"panelIndex":"287b65e9-0aaa-42ee-ab7b-d60b3937d37a","embeddableConfig":{"savedVis":{"title":"","description":"","type":"markdown","params":{"fontSize":12,"openLinksInNewTab":false,"markdown":"The Host Risk Score capability is an experimental feature released in 7.14. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md)."},"uiState":{},"data":{"aggs":[],"searchSource":{"query":{"query":"","language":"kuery"},"filter":[]}}},"hidePanelTitles":true,"enhancements":{}},"title":"Note:"},{"version":"7.13.4","type":"lens","gridData":{"x":16,"y":3,"w":16,"h":15,"i":"654d55f8-f873-4348-96cd-5dce0b56ac32"},"panelIndex":"654d55f8-f873-4348-96cd-5dce0b56ac32","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[{"eventId":"b04e60d5-4e34-4589-af2e-8e9c3a15936f","triggers":["FILTER_TRIGGER"],"action":{"factoryId":"DASHBOARD_TO_DASHBOARD_DRILLDOWN","name":"Go to Dashboard","config":{"useCurrentFilters":true,"useCurrentDateRange":true}}}]}},"hidePanelTitles":false},"title":"Current Risk Scores for Hosts","panelRefName":"panel_654d55f8-f873-4348-96cd-5dce0b56ac32"}]', - timeRestore: false, - title: 'Current Risk Score for Hosts', - version: 1, - }, - coreMigrationVersion: '7.13.4', - id: '', - migrationVersion: { dashboard: '7.13.1' }, - references: [ - { - id: '', - name: '654d55f8-f873-4348-96cd-5dce0b56ac32:panel_654d55f8-f873-4348-96cd-5dce0b56ac32', - type: 'lens', - }, - { - id: '', - name: '654d55f8-f873-4348-96cd-5dce0b56ac32:drilldown:DASHBOARD_TO_DASHBOARD_DRILLDOWN:b04e60d5-4e34-4589-af2e-8e9c3a15936f:dashboardId', - type: 'dashboard', - }, - { - id: '', - name: 'tag-1d00ebe0-f3b2-11eb-beb2-b91666445a94', - type: 'tag', - }, - ], - type: 'dashboard', - updated_at: '2021-08-18T17:08:00.467Z', - }, -]; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/index.ts deleted file mode 100644 index 54fb29df07ec9..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/index.ts +++ /dev/null @@ -1,8 +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. - */ -export { hostRiskScoreDashboards } from './host_risk_score_dashboards'; -export { userRiskScoreDashboards } from './user_risk_score_dashboards'; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/user_risk_score_dashboards.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/user_risk_score_dashboards.ts deleted file mode 100644 index fea181e6907ca..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/saved_object/user_risk_score_dashboards.ts +++ /dev/null @@ -1,419 +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 { SavedObject } from '@kbn/core/types'; -import { RiskScoreFields } from '../../../../../common/search_strategy'; - -export const userRiskScoreDashboards: SavedObject[] = [ - { - attributes: { - fieldAttrs: '{}', - fields: '[]', - runtimeFieldMap: '{}', - timeFieldName: '@timestamp', - title: 'ml_user_risk_score_latest_', - typeMeta: '{}', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { 'index-pattern': '8.0.0' }, - references: [], - type: 'index-pattern', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: '', - state: { - datasourceStates: { - indexpattern: { - layers: { - 'b4c8cd6f-2499-4791-a0f7-01b0d3f75efc': { - columnOrder: [ - 'ba672ee7-0990-4277-9bc7-6361077efe18', - '6b6df37f-ad45-462c-aa2f-2d19af98ed98', - 'daefb732-9f48-4017-a49a-979cfdeef127', - ], - columns: { - '6b6df37f-ad45-462c-aa2f-2d19af98ed98': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: 'Risk Score', - operationType: 'sum', - params: { emptyAsNull: true }, - scale: 'ratio', - sourceField: RiskScoreFields.userRiskScore, - }, - 'ba672ee7-0990-4277-9bc7-6361077efe18': { - customLabel: true, - dataType: 'string', - isBucketed: true, - label: 'User Name', - operationType: 'terms', - params: { - missingBucket: false, - orderBy: { columnId: '6b6df37f-ad45-462c-aa2f-2d19af98ed98', type: 'column' }, - orderDirection: 'desc', - otherBucket: true, - parentFormat: { id: 'terms' }, - size: 30, - }, - scale: 'ordinal', - sourceField: RiskScoreFields.userName, - }, - 'daefb732-9f48-4017-a49a-979cfdeef127': { - customLabel: true, - dataType: 'string', - filter: { language: 'kuery', query: '' }, - isBucketed: false, - label: 'Current Risk', - operationType: 'last_value', - params: { sortField: '@timestamp' }, - scale: 'ordinal', - sourceField: RiskScoreFields.userRisk, - }, - }, - incompleteColumns: {}, - }, - }, - }, - }, - filters: [], - query: { language: 'kuery', query: '' }, - visualization: { - columns: [ - { columnId: 'ba672ee7-0990-4277-9bc7-6361077efe18', isTransposed: false }, - { columnId: '6b6df37f-ad45-462c-aa2f-2d19af98ed98', hidden: true, isTransposed: false }, - { columnId: 'daefb732-9f48-4017-a49a-979cfdeef127', isTransposed: false }, - ], - layerId: 'b4c8cd6f-2499-4791-a0f7-01b0d3f75efc', - layerType: 'data', - }, - }, - title: 'Current Risk Score for Users', - visualizationType: 'lnsDatatable', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { lens: '8.3.0' }, - references: [ - { - id: '', - name: 'indexpattern-datasource-layer-b4c8cd6f-2499-4791-a0f7-01b0d3f75efc', - type: 'index-pattern', - }, - ], - type: 'lens', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - fieldAttrs: '{}', - fields: '[]', - runtimeFieldMap: '{}', - timeFieldName: '@timestamp', - title: 'ml_user_risk_score_', - typeMeta: '{}', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { 'index-pattern': '8.0.0' }, - references: [], - type: 'index-pattern', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: '', - state: { - datasourceStates: { - indexpattern: { - layers: { - 'b885eaad-3c68-49ad-9891-70158d912dbd': { - columnOrder: [ - '1fced52d-7ba5-4254-8656-fe0d7ced586a', - 'e82aed80-ee04-4ad1-9b9d-fde4a25be58a', - '3fadebce-2f31-4eed-9fc0-237249281a1a', - ], - columns: { - '1fced52d-7ba5-4254-8656-fe0d7ced586a': { - customLabel: true, - dataType: 'string', - isBucketed: true, - label: 'User Name', - operationType: 'terms', - params: { - missingBucket: false, - orderBy: { columnId: '3fadebce-2f31-4eed-9fc0-237249281a1a', type: 'column' }, - orderDirection: 'desc', - otherBucket: false, - parentFormat: { id: 'terms' }, - size: 20, - }, - scale: 'ordinal', - sourceField: RiskScoreFields.userName, - }, - '3fadebce-2f31-4eed-9fc0-237249281a1a': { - customLabel: true, - dataType: 'number', - isBucketed: false, - label: 'Cumulative Risk Score', - operationType: 'max', - params: { emptyAsNull: true }, - scale: 'ratio', - sourceField: RiskScoreFields.userRiskScore, - }, - 'e82aed80-ee04-4ad1-9b9d-fde4a25be58a': { - dataType: 'date', - isBucketed: true, - label: '@timestamp', - operationType: 'date_histogram', - params: { includeEmptyRows: true, interval: '1d' }, - scale: 'interval', - sourceField: '@timestamp', - }, - }, - incompleteColumns: {}, - }, - }, - }, - }, - filters: [], - query: { language: 'kuery', query: 'not user.name: SYSTEM' }, - visualization: { - layers: [ - { - accessors: ['3fadebce-2f31-4eed-9fc0-237249281a1a'], - layerId: 'b885eaad-3c68-49ad-9891-70158d912dbd', - layerType: 'data', - position: 'top', - seriesType: 'bar_stacked', - showGridlines: false, - splitAccessor: '1fced52d-7ba5-4254-8656-fe0d7ced586a', - xAccessor: 'e82aed80-ee04-4ad1-9b9d-fde4a25be58a', - }, - ], - legend: { isVisible: true, legendSize: 'auto', position: 'right' }, - preferredSeriesType: 'bar_stacked', - title: 'Empty XY chart', - valueLabels: 'hide', - yLeftExtent: { mode: 'full' }, - yRightExtent: { mode: 'full' }, - }, - }, - title: 'User Risk Score (Max Risk Score Histogram)', - visualizationType: 'lnsXY', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { lens: '8.3.0' }, - references: [ - { - id: '', - name: 'indexpattern-datasource-layer-b885eaad-3c68-49ad-9891-70158d912dbd', - type: 'index-pattern', - }, - ], - type: 'lens', - updated_at: '2022-08-12T16:31:30.450Z', - }, - { - attributes: { - fieldAttrs: '{}', - fields: '[]', - runtimeFieldMap: '{}', - timeFieldName: '@timestamp', - title: '.alerts-security.alerts-', - typeMeta: '{}', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { 'index-pattern': '8.0.0' }, - references: [], - type: 'index-pattern', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: '', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"query":{"query":"user.name: root","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - title: 'Associated Users (Rule Breakdown)', - uiStateJSON: '{}', - version: 1, - visState: - '{"title":"Associated Users (Rule Breakdown)","type":"table","aggs":[{"id":"2","enabled":true,"type":"sum","params":{"field":"signal.rule.risk_score","customLabel":"Total Risk Score","emptyAsNull":false},"schema":"metric"},{"id":"1","enabled":true,"type":"count","params":{"customLabel":"Number of Hits","emptyAsNull":false},"schema":"metric"},{"id":"3","enabled":true,"type":"terms","params":{"field":"user.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"User"},"schema":"split"},{"id":"4","enabled":true,"type":"terms","params":{"field":"signal.rule.name","orderBy":"2","order":"desc","size":50,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Name"},"schema":"bucket"},{"id":"5","enabled":true,"type":"terms","params":{"field":"signal.rule.type","orderBy":"2","order":"desc","size":50,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Type"},"schema":"bucket"}],"params":{"perPage":25,"showPartialRows":false,"showMetricsAtAllLevels":false,"showTotal":false,"showToolbar":false,"totalFunc":"sum","percentageCol":"","row":true,"autoFitRowToContent":true}}', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { visualization: '8.3.0' }, - references: [ - { - id: '', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - }, - ], - type: 'visualization', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: '', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"query":{"query":"","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - title: 'Alerts by Hostname', - uiStateJSON: '{}', - version: 1, - visState: - '{"title":"Alerts by Hostname","type":"table","aggs":[{"id":"2","enabled":true,"type":"sum","params":{"field":"signal.rule.risk_score","customLabel":"Total Risk Score","emptyAsNull":false},"schema":"metric"},{"id":"1","enabled":true,"type":"count","params":{"customLabel":"Number of Hits","emptyAsNull":false},"schema":"metric"},{"id":"3","enabled":true,"type":"terms","params":{"field":"host.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Host"},"schema":"split"},{"id":"4","enabled":true,"type":"terms","params":{"field":"signal.rule.name","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Name"},"schema":"bucket"},{"id":"5","enabled":true,"type":"terms","params":{"field":"signal.rule.type","orderBy":"2","order":"desc","size":20,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Rule Type"},"schema":"bucket"}],"params":{"perPage":10,"showPartialRows":false,"showMetricsAtAllLevels":false,"showTotal":false,"showToolbar":false,"totalFunc":"sum","percentageCol":"","row":true,"autoFitRowToContent":false}}', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { visualization: '8.3.0' }, - references: [ - { - id: '', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - }, - ], - type: 'visualization', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: '', - kibanaSavedObjectMeta: { - searchSourceJSON: - '{"query":{"query":"not user.name : *$","language":"kuery"},"filter":[],"indexRefName":"kibanaSavedObjectMeta.searchSourceJSON.index"}', - }, - title: 'User Risk Score (Tactic Breakdown)- Verbose', - uiStateJSON: '{}', - version: 1, - visState: - '{"title":"User Risk Score (Tactic Breakdown)- Verbose","type":"table","aggs":[{"id":"1","enabled":true,"type":"sum","params":{"field":"signal.rule.risk_score","customLabel":"Total Risk Score","emptyAsNull":false},"schema":"metric"},{"id":"3","enabled":true,"type":"terms","params":{"field":"user.name","orderBy":"1","order":"desc","size":40,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":false,"missingBucketLabel":"Missing","customLabel":"Username"},"schema":"split"},{"id":"5","enabled":true,"type":"terms","params":{"field":"signal.rule.threat.tactic.name","orderBy":"1","order":"desc","size":100,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":true,"missingBucketLabel":"Other","customLabel":"Tactic"},"schema":"bucket"},{"id":"6","enabled":true,"type":"terms","params":{"field":"signal.rule.threat.technique.name","orderBy":"1","order":"desc","size":100,"otherBucket":false,"otherBucketLabel":"Other","missingBucket":true,"missingBucketLabel":"Other","customLabel":"Technique"},"schema":"bucket"},{"id":"7","enabled":true,"type":"count","params":{"customLabel":"Number of Hits","emptyAsNull":false},"schema":"metric"}],"params":{"perPage":10,"showPartialRows":false,"showMetricsAtAllLevels":false,"showTotal":false,"showToolbar":false,"totalFunc":"sum","percentageCol":"","row":true,"autoFitRowToContent":false}}', - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { visualization: '8.3.0' }, - references: [ - { - id: '', - name: 'kibanaSavedObjectMeta.searchSourceJSON.index', - type: 'index-pattern', - }, - ], - type: 'visualization', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { color: '#6edb7f', description: '', name: 'experimental' }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { tag: '8.0.0' }, - references: [], - type: 'tag', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: - 'This dashboard allows users to drill down further into the details of the risk components associated with a particular user.', - hits: 0, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', - }, - optionsJSON: '{"hidePanelTitles":false,"useMargins":true}', - panelsJSON: - '[{"version":"8.3.0","type":"visualization","gridData":{"x":0,"y":0,"w":48,"h":3,"i":"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195"},"panelIndex":"eaa57cf4-7ca3-4919-ab76-dbac0eb6a195","embeddableConfig":{"savedVis":{"title":"","description":"","type":"markdown","params":{"fontSize":12,"openLinksInNewTab":false,"markdown":"The User Risk Score capability is an experimental feature. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md)."},"uiState":{},"data":{"aggs":[],"searchSource":{"query":{"query":"","language":"kuery"},"filter":[]}}},"hidePanelTitles":true,"enhancements":{}}},{"version":"8.3.0","type":"lens","gridData":{"x":0,"y":3,"w":48,"h":15,"i":"b3fdccab-59c1-47c8-9393-fa043e0dff83"},"panelIndex":"b3fdccab-59c1-47c8-9393-fa043e0dff83","embeddableConfig":{"enhancements":{},"hidePanelTitles":false},"title":"Cumulative User Risk Score (multiple users)","panelRefName":"panel_b3fdccab-59c1-47c8-9393-fa043e0dff83"},{"version":"8.3.0","type":"visualization","gridData":{"x":0,"y":18,"w":24,"h":45,"i":"8d09b97c-a023-4b7e-9e9d-1c46e726a487"},"panelIndex":"8d09b97c-a023-4b7e-9e9d-1c46e726a487","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[]}},"hidePanelTitles":false,"vis":{"params":{"colWidth":[{"colIndex":0,"width":410.5}]}}},"title":"Alert Counts by User","panelRefName":"panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487"},{"version":"8.3.0","type":"visualization","gridData":{"x":24,"y":18,"w":24,"h":45,"i":"cae82aa1-20c8-4354-94ab-3934ac53b8fe"},"panelIndex":"cae82aa1-20c8-4354-94ab-3934ac53b8fe","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[]}},"hidePanelTitles":false,"vis":{"params":{"colWidth":[{"colIndex":0,"width":304}]}}},"title":"Alert Counts by Host","panelRefName":"panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe"},{"version":"8.3.0","type":"visualization","gridData":{"x":0,"y":63,"w":48,"h":15,"i":"ca3c8903-be5d-4265-820c-cc3d67443af2"},"panelIndex":"ca3c8903-be5d-4265-820c-cc3d67443af2","embeddableConfig":{"enhancements":{},"hidePanelTitles":false},"title":"Tactic Breakdown of Risky Users","panelRefName":"panel_ca3c8903-be5d-4265-820c-cc3d67443af2"}]', - refreshInterval: { pause: false, value: 0 }, - timeFrom: 'now-1w', - timeRestore: true, - timeTo: 'now', - title: 'Drilldown of User Risk Score', - version: 1, - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { dashboard: '8.3.0' }, - references: [ - { - id: '', - name: 'b3fdccab-59c1-47c8-9393-fa043e0dff83:panel_b3fdccab-59c1-47c8-9393-fa043e0dff83', - type: 'lens', - }, - { - id: '', - name: '8d09b97c-a023-4b7e-9e9d-1c46e726a487:panel_8d09b97c-a023-4b7e-9e9d-1c46e726a487', - type: 'visualization', - }, - { - id: '', - name: 'cae82aa1-20c8-4354-94ab-3934ac53b8fe:panel_cae82aa1-20c8-4354-94ab-3934ac53b8fe', - type: 'visualization', - }, - { - id: '', - name: 'ca3c8903-be5d-4265-820c-cc3d67443af2:panel_ca3c8903-be5d-4265-820c-cc3d67443af2', - type: 'visualization', - }, - { - id: '', - name: 'tag-93fc0f00-1a57-11ed-bb53-ad8c26f4d942', - type: 'tag', - }, - ], - type: 'dashboard', - updated_at: '2022-08-12T16:20:10.121Z', - }, - { - attributes: { - description: '', - hits: 0, - kibanaSavedObjectMeta: { - searchSourceJSON: '{"query":{"query":"","language":"kuery"},"filter":[]}', - }, - optionsJSON: - '{"useMargins":true,"syncColors":false,"syncTooltips":false,"hidePanelTitles":false}', - panelsJSON: - '[{"version":"8.3.0","type":"visualization","gridData":{"x":0,"y":0,"w":48,"h":3,"i":"02f0548a-aae6-460f-9300-be42b4ae9a1e"},"panelIndex":"02f0548a-aae6-460f-9300-be42b4ae9a1e","embeddableConfig":{"savedVis":{"id":"","title":"","description":"","type":"markdown","params":{"fontSize":12,"openLinksInNewTab":false,"markdown":"User Risk Score is an experimental feature. You can read further about it [here](https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md)."},"uiState":{},"data":{"aggs":[],"searchSource":{"query":{"query":"","language":"kuery"},"filter":[]}}},"hidePanelTitles":true,"enhancements":{}}},{"version":"8.3.0","type":"lens","gridData":{"x":17,"y":3,"w":14,"h":15,"i":"1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5"},"panelIndex":"1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5","embeddableConfig":{"enhancements":{"dynamicActions":{"events":[{"eventId":"d26cff88-a061-494e-abb1-958216009585","triggers":["FILTER_TRIGGER"],"action":{"factoryId":"DASHBOARD_TO_DASHBOARD_DRILLDOWN","name":"Go to Dashboard","config":{"useCurrentFilters":true,"useCurrentDateRange":true,"openInNewTab":false}}}]}},"hidePanelTitles":false},"title":"Current Risk Scores for Users","panelRefName":"panel_1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5"}]', - refreshInterval: { pause: false, value: 0 }, - timeFrom: 'now-1w', - timeRestore: true, - timeTo: 'now', - title: 'Current Risk Score for Users', - version: 1, - }, - coreMigrationVersion: '8.3.0', - id: '', - migrationVersion: { dashboard: '8.3.0' }, - references: [ - { - id: '', - name: '1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5:panel_1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5', - type: 'lens', - }, - { - id: '', - name: '1e9c2cc7-ae0c-4ae7-8d03-8e079b5891b5:drilldown:DASHBOARD_TO_DASHBOARD_DRILLDOWN:d26cff88-a061-494e-abb1-958216009585:dashboardId', - type: 'dashboard', - }, - { - id: '', - name: 'tag-93fc0f00-1a57-11ed-bb53-ad8c26f4d942', - type: 'tag', - }, - ], - type: 'dashboard', - updated_at: '2022-08-12T16:20:10.121Z', - }, -]; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/types.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/types.ts deleted file mode 100644 index dd3735c15bec6..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/types.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 { OutputError } from '@kbn/securitysolution-es-utils'; - -export type SavedObjectTemplate = 'hostRiskScoreDashboards' | 'userRiskScoreDashboards'; - -export interface BulkCreateSavedObjectsResult { - hostRiskScoreDashboards?: { - success: boolean; - error: OutputError; - body?: { id: string; name: string; type: string }; - }; - userRiskScoreDashboards?: { - success: boolean; - error: OutputError; - body?: { id: string; name: string; type: string }; - }; -} diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/readme.md b/x-pack/plugins/security_solution/server/lib/risk_score/readme.md deleted file mode 100644 index 17087d447e630..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/readme.md +++ /dev/null @@ -1,488 +0,0 @@ - -# Version -|Version|Risk Score Entity|Scripts created|Ingest pipelines created|Transforms created|Behind feature flag|Notes| -|-------|------|-------|----------------|----------|----|----| -|8.3`deprecated`|host|1.ml_hostriskscore_levels_script_{spacename} 2.ml_hostriskscore_map_script_{spacename} 3.ml_hostriskscore_reduce_script_{spacename} 4.ml_hostriskscore_init_script_{spacename}|ml_hostriskscore_ingest_pipeline_{spacename}|1.ml_hostriskscore_pivot_transform_{spacename} Destination Index: `ml_host_risk_score_{spacename}` 2.ml_hostriskscore_latest_transform_{spacename} Destination Index: `ml_host_risk_score_latest_{spacename}`| Yes|https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/host-risk-score.md| -|8.3`deprecated`|user|1.ml_userriskscore_levels_script_{spacename} 2.ml_userriskscore_map_script_{spacename} 3.ml_userriskscore_reduce_script_{spacename}|ml_userriskscore_ingest_pipeline_{spacename}|1.ml_userriskscore_pivot_transform_{spacename} Destination index: `ml_user_risk_score_{spacename}` 2.ml_userriskscore_latest_transform_{spacename} Destination index: `ml_user_risk_score_latest_{spacename}`|Yes|https://github.com/elastic/detection-rules/blob/main/docs/experimental-machine-learning/user-risk-score.md| -|8.4`deprecated`|host|1.ml_hostriskscore_levels_script 2.ml_hostriskscore_map_script 3.ml_hostriskscore_reduce_script 4.ml_hostriskscore_init_script|ml_hostriskscore_ingest_pipeline|1.ml_hostriskscore_pivot_transform_{spacename} Destination Index: `ml_host_risk_score_{spacename}` 2.ml_hostriskscore_latest_transform_{spacename} Destination Index: `ml_host_risk_score_latest_{spacename}`|Yes|Installation via dev tools releasesd. https://github.com/elastic/kibana/blob/8.4/x-pack/plugins/security_solution/server/lib/prebuilt_dev_tool_content/console_templates/enable_host_risk_score.console| -|8.4`deprecated`|user|1.ml_userriskscore_levels_script_{spacename} 2.ml_userriskscore_map_script_{spacename} 3.ml_userriskscore_reduce_script_{spacename}|ml_userriskscore_ingest_pipeline_{spacename}|1.ml_userriskscore_pivot_transform_{spacename} Destination index: `ml_user_risk_score_{spacename}` 2.ml_userriskscore_latest_transform_{spacename} Destination index: `ml_user_risk_score_latest_{spacename}`|Yes|Installation via dev tools not available yet (Installation via dev tools is availble in 8.5). -|8.5+|host|1.ml_hostriskscore_levels_script_{spacename} 2.ml_hostriskscore_map_script_{spacename} 3.ml_hostriskscore_reduce_script_{spacename} 4.ml_hostriskscore_init_script_{spacename}|ml_hostriskscore_ingest_pipeline_{spacename}|1.ml_hostriskscore_pivot_transform_{spacename} Destination Index: `ml_host_risk_score_{spacename}` 2.ml_hostriskscore_latest_transform_{spacename} Destination Index: `ml_host_risk_score_latest_{spacename}`| No|`Breaking Chang`: New schema for Destination indices| -|8.5+|user|1.ml_userriskscore_levels_script_{spacename} 2.ml_userriskscore_map_script_{spacename} 3.ml_userriskscore_reduce_script_{spacename}|ml_userriskscore_ingest_pipeline_{spacename}|1.ml_userriskscore_pivot_transform_{spacename} Destination index: `ml_user_risk_score_{spacename}` 2.ml_userriskscore_latest_transform_{spacename} Destination index: `ml_user_risk_score_latest_{spacename}`|No|`Breaking Chang`: New schema for Destination indices| -# Risk Score API - -### API usage - -#### 1. GET /internal/risk_score/index_status - `getRiskScoreIndexStatusRoute` -##### REQUEST: -```typescript - GET /internal/risk_score/index_status - { - indexName: 'ml_host_risk_score_latest' - } -``` -##### RESPONSE: -```typescript - { - isDeprecated: boolean; - isEnabled: boolean; - } -``` -##### This route is called from `useRiskScore` hook. - -#### 2. PUT - /internal/risk_score/indices/create - -example: -##### REQUEST: - -``` -PUT /internal/risk_score/indices/create -{ - "index": "ml_host_risk_score_latest_default-test", - "mappings": { - "properties": { - "host.name": { - "type": "keyword" - }, - "@timestamp": { - "type": "date" - }, - "ingest_timestamp": { - "type": "date" - }, - "risk": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "risk_stats": { - "properties": { - "risk_score": { - "type": "float" - } - } - } - } - } -} -``` - - -##### RESPONSE: -``` -{ - "index": "ml_host_risk_score_latest_default-test", - "mappings": { - "properties": { - "host.name": { - "type": "keyword" - }, - "@timestamp": { - "type": "date" - }, - "ingest_timestamp": { - "type": "date" - }, - "risk": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "risk_stats": { - "properties": { - "risk_score": { - "type": "float" - } - } - } - } - } -} -``` - -#### 3. POST - /internal/risk_score/indices/delete - -example: - -##### REQUEST: -``` - POST /internal/risk_score/indices/delete - { - "indices": ["ml_host_risk_score_latest_default-test"] - } -``` - -##### RESPONSE: -``` - { - "deleted": [ - "ml_host_risk_score_latest_default-test" - ] - } -``` - -#### 4. POST - /internal/risk_score - -Onboard host or user risk score. -##### Option: - -|Body|description| -|--|--| -|riskScoreEntity|value: `host` or `user`| - -example: - -##### REQUEST: -``` - POST /internal/risk_score - { - "riskScoreEntity": host - } -``` -##### RESPONSE: - -``` -[ - { - "ml_hostriskscore_levels_script_default": { - "success": true, - "error": null - } - }, - { - "ml_hostriskscore_ingest_pipeline_default": { - "success": true, - "error": null - } - }, - { - "ml_hostriskscore_init_script_default": { - "success": true, - "error": null - } - }, - { - "ml_hostriskscore_map_script_default": { - "success": true, - "error": null - } - }, - { - "ml_hostriskscore_reduce_script_default": { - "success": true, - "error": null - } - }, - { - "ml_host_risk_score_default": { - "success": true, - "error": null - } - }, - { - "ml_host_risk_score_latest_default": { - "success": true, - "error": null - } - }, - { - "ml_hostriskscore_pivot_transform_default": { - "success": true, - "error": null - } - }, - { - "ml_hostriskscore_latest_transform_default": { - "success": true, - "error": null - } - } -] -``` - -#### 5. GET - /internal/risk_score/prebuilt_content/dev_tool/{console_id} - -Get scripts for onboarding host or user risk score - -##### Option: - -|Param|description| -|--|--| -|console_id|value: `enable_host_risk_score` or `enable_user_risk_score`| - -example: - -##### REQUEST: - -``` -GET /internal/risk_score/prebuilt_content/dev_tool/enable_host_risk_score -``` - -##### RESPONSE: - -``` -# Click the run button of each step to enable the module -# Upload scripts -# 1. Script to assign risk level based on risk score -PUT _scripts/ml_hostriskscore_levels_script_default -{ -"script": { -"lang": "painless", -"source": "double risk_score = (def)ctx.getByPath(params.risk_score);\nif (risk_score < 20) {\n - ctx['host']['risk']['calculated_level']='Unknown' \n}\nelse if (risk_score>= 20 && risk_score < 40) {\n - ctx['host']['risk']['calculated_level']='Low' \n}\nelse if (risk_score>= 40 && risk_score < 70) {\n - ctx['host']['risk']['calculated_level']='Moderate' \n}\nelse if (risk_score>= 70 && risk_score < 90) {\n - ctx['host']['risk']['calculated_level']='High' \n}\nelse if (risk_score>= 90) {\n - ctx['host']['risk']['calculated_level'] = 'Critical'\n}" - } - } - - # 2. Script to setup initial state for the Host Risk Score scripted metric aggregation - PUT _scripts/ml_hostriskscore_init_script_default - { - "script": { - "lang": "painless", - "source": "state.rule_risk_stats = new HashMap();\nstate.host_variant_set = false;\nstate.host_variant = - new String();\nstate.tactic_ids = new HashSet();" - } - } - - # 3. Map script for the Host Risk Score transform - PUT _scripts/ml_hostriskscore_map_script_default - { - "script": { - "lang": "painless", - "source": "// Get the host variant\nif (state.host_variant_set == false) {\n if - (doc.containsKey(\"host.os.full\") && doc[\"host.os.full\"].size() != 0) {\n state.host_variant = - doc[\"host.os.full\"].value;\n state.host_variant_set = true;\n }\n}\n// Aggregate all the tactics seen - on the host\nif (doc.containsKey(\"signal.rule.threat.tactic.id\") && - doc[\"signal.rule.threat.tactic.id\"].size() != 0) {\n - state.tactic_ids.add(doc[\"signal.rule.threat.tactic.id\"].value);\n}\n// Get running sum of - time-decayed risk score per rule name per shard\nString rule_name = - doc[\"signal.rule.name\"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, - [0.0,\"\",false]);\nint time_diff = (int)((System.currentTimeMillis() - - doc[\"@timestamp\"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0));\ndouble risk_derate = - Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant));\nstats[0] = - Math.max(stats[0], doc[\"signal.rule.risk_score\"].value * risk_derate);\nif (stats[2] == false) {\n - stats[1] = doc[\"kibana.alert.rule.uuid\"].value;\n stats[2] = - true;\n}\nstate.rule_risk_stats.put(rule_name, stats);" - } - } - - # 4. Reduce script for the Host Risk Score transform - PUT _scripts/ml_hostriskscore_reduce_script_default - { - "script": { - "lang": "painless", - "source": "// Consolidating time decayed risks and tactics from across all shards\nMap total_risk_stats - = new HashMap();\nString host_variant = new String();\ndef tactic_ids = new HashSet();\nfor (state in - states) {\n for (key in state.rule_risk_stats.keySet()) {\n def rule_stats = - state.rule_risk_stats.get(key);\n def stats = total_risk_stats.getOrDefault(key, [0.0,\"\",false]);\n - stats[0] = Math.max(stats[0], rule_stats[0]);\n if (stats[2] == false) {\n stats[1] = rule_stats[1];\n - stats[2] = true;\n } \n total_risk_stats.put(key, stats);\n }\n if (host_variant.length() == 0) {\n - host_variant = state.host_variant;\n }\n tactic_ids.addAll(state.tactic_ids);\n}\n// Consolidating - individual rule risks and arranging them in decreasing order\nList risks = new ArrayList();\nfor (key in - total_risk_stats.keySet()) {\n risks.add(total_risk_stats[key][0])\n}\nCollections.sort(risks, - Collections.reverseOrder());\n// Calculating total host risk score\ndouble total_risk = 0.0;\ndouble - risk_cap = params.max_risk * params.zeta_constant;\nfor (int i=0;i= 40 && total_norm_risk < 50) {\n total_norm_risk=85 + - (total_norm_risk - 40);\n}\nelse {\n total_norm_risk=95 + (total_norm_risk - 50) / 10;\n}\n// - Calculating multipliers to the host risk score\ndouble risk_multiplier=1.0;\nList - multipliers=new ArrayList();\n// Add a multiplier if host is a server\nif - (host_variant.toLowerCase().contains(\"server\")) {\n risk_multiplier - *=params.server_multiplier;\n multipliers.add(\"Host is a server\");\n}\n// Add multipliers - based on number and diversity of tactics seen on the host\nfor (String tactic : tactic_ids) {\n - multipliers.add(\"Tactic \"+tactic);\n risk_multiplier *=1 + params.tactic_base_multiplier * - params.tactic_weights.getOrDefault(tactic, 0);\n}\n// Calculating final risk\ndouble - final_risk=total_norm_risk;\nif (risk_multiplier> 1.0) {\n double prior_odds = (total_norm_risk) - / (100 - total_norm_risk);\n double updated_odds = prior_odds * risk_multiplier; \n final_risk = - 100 * updated_odds / (1 + updated_odds);\n}\n// Adding additional metadata\nList rule_stats = - new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n Map temp = new HashMap();\n - temp[\"rule_name\"] = key;\n temp[\"rule_risk\"] = total_risk_stats[key][0];\n temp[\"rule_id\"] - = total_risk_stats[key][1];\n rule_stats.add(temp);\n}\n\nreturn [\"calculated_score_norm\": - final_risk, \"rule_risks\": rule_stats, \"multipliers\": multipliers];" - } - } - - # 5. Upload the ingest pipeline - # Ingest pipeline to add ingest timestamp and risk level to documents - PUT _ingest/pipeline/ml_hostriskscore_ingest_pipeline_default - { - "processors": - [{"set":{"field":"ingest_timestamp","value":"{{_ingest.timestamp}}"}},{"fingerprint":{"fields":["@timestamp","_id"],"method":"SHA-256","target_field":"_id"}},{"script":{"id":"ml_hostriskscore_levels_script_default","params":{"risk_score":"host.risk.calculated_score_norm"}}}] - } - - # 6. Create mappings for the destination index of the Host Risk Score pivot transform - PUT ml_host_risk_score_default - { - "mappings": - {"properties":{"host":{"properties":{"name":{"type":"keyword"},"risk":{"properties":{"calculated_score_norm":{"type":"float"},"calculated_level":{"type":"keyword"},"multipliers":{"type":"keyword"},"rule_risks":{"properties":{"rule_name":{"type":"text","fields":{"keyword":{"type":"keyword"}}},"rule_risk":{"type":"float"},"rule_id":{"type":"keyword"}}}}}}},"ingest_timestamp":{"type":"date"},"@timestamp":{"type":"date"}}} - } - - # 7. Upload the Host Risk Score pivot transform - # This transform runs hourly and calculates a risk score and risk level for hosts in a Kibana - space - PUT _transform/ml_hostriskscore_pivot_transform_default - {"dest":{"index":"ml_host_risk_score_default","pipeline":"ml_hostriskscore_ingest_pipeline_default"},"frequency":"1h","pivot":{"aggregations":{"@timestamp":{"max":{"field":"@timestamp"}},"host.risk":{"scripted_metric":{"combine_script":"return - state","init_script":{"id":"ml_hostriskscore_init_script_default"},"map_script":{"id":"ml_hostriskscore_map_script_default"},"params":{"lookback_time":72,"max_risk":100,"p":1.5,"server_multiplier":1.5,"tactic_base_multiplier":0.25,"tactic_weights":{"TA0001":1,"TA0002":2,"TA0003":3,"TA0004":4,"TA0005":4,"TA0006":4,"TA0007":4,"TA0008":5,"TA0009":6,"TA0010":7,"TA0011":6,"TA0040":8,"TA0042":1,"TA0043":1},"time_decay_constant":6,"zeta_constant":2.612},"reduce_script":{"id":"ml_hostriskscore_reduce_script_default"}}}},"group_by":{"host.name":{"terms":{"field":"host.name"}}}},"source":{"index":[".alerts-security.alerts-default"],"query":{"bool":{"filter":[{"range":{"@timestamp":{"gte":"now-5d"}}}]}}},"sync":{"time":{"delay":"120s","field":"@timestamp"}}} - - - # 8. Start the pivot transform - POST _transform/ml_hostriskscore_pivot_transform_default/_start - - # 9. Create mappings for the destination index of the Host Risk Score latest transform - PUT ml_host_risk_score_latest_default - { - "mappings": - {"properties":{"host":{"properties":{"name":{"type":"keyword"},"risk":{"properties":{"calculated_score_norm":{"type":"float"},"calculated_level":{"type":"keyword"},"multipliers":{"type":"keyword"},"rule_risks":{"properties":{"rule_name":{"type":"text","fields":{"keyword":{"type":"keyword"}}},"rule_risk":{"type":"float"},"rule_id":{"type":"keyword"}}}}}}},"ingest_timestamp":{"type":"date"},"@timestamp":{"type":"date"}}} - } - - # 10. Upload the latest transform - # This transform gets the latest risk information about hosts in a Kibana space - PUT _transform/ml_hostriskscore_latest_transform_default - {"dest":{"index":"ml_host_risk_score_latest_default"},"frequency":"1h","latest":{"sort":"@timestamp","unique_key":["host.name"]},"source":{"index":["ml_host_risk_score_default"]},"sync":{"time":{"delay":"2s","field":"ingest_timestamp"}}} - - # 11. Start the latest transform - POST _transform/ml_hostriskscore_latest_transform_default/_start - - # Hint: If you don't see data after running any of the transforms, stop and restart the - transforms - # Stop the pivot transform - POST _transform/ml_hostriskscore_pivot_transform_default/_stop - - # Start the pivot transform - POST _transform/ml_hostriskscore_pivot_transform_default/_start - - # Stop the latest transform - POST _transform/ml_hostriskscore_latest_transform_default/_stop - - # Start the latest transform - POST _transform/ml_hostriskscore_latest_transform_default/_start -``` - -#### 6. POST - /internal/risk_score/prebuilt_content/saved_objects/_bulk_create/{template_name} - -Import saved objects for host or user risk score -##### Option: - -|Param|description| -|--|--| -|template_name|value: `hostRiskScoreDashboards` or `userRiskScoreDashboards`| - -example: - -##### REQUEST: - -``` -POST /internal/risk_score/prebuilt_content/saved_objects/_bulk_create/hostRiskScoreDashboards -``` - -##### RESPONSE: - -``` -{ - "hostRiskScoreDashboards": { - "success": true, - "error": null, - "body": [ - { - "id": "259ef77a-0ea2-4ba2-bb77-f33fae4ec8aa", - "type": "index-pattern", - "title": "ml_host_risk_score_default" - }, - { - "id": "0adfc3b7-efa0-470e-ac31-27b1d8e01c48", - "type": "lens", - "title": "Host Risk Score (Max Risk Score Histogram)" - }, - { - "id": "e1a4d5f1-e59f-4ee6-918b-a1a1b48bf8de", - "type": "index-pattern", - "title": ".alerts-security.alerts-default" - }, - { - "id": "7799bfdf-9318-4f85-b840-678ccfbd9f79", - "type": "visualization", - "title": "Host Risk Score (Rule Breakdown)" - }, - { - "id": "acbc71e9-de52-47cd-ade6-33be0efdb1dc", - "type": "visualization", - "title": "Associated Users (Rule Breakdown)" - }, - { - "id": "0fb7224d-5e32-4f3d-b408-ee6acfd3f0c6", - "type": "visualization", - "title": "Host Risk Score (Tactic Breakdown)- Verbose" - }, - { - "id": "53e4c2cd-9f34-48dd-ab87-f48b8c5dec22", - "type": "tag", - "name": "experimental" - }, - { - "id": "2175ffc6-c53c-46ac-b15d-be9b849881ac", - "type": "dashboard", - "title": "Drilldown of Host Risk Score" - }, - { - "id": "d9d560b4-beed-4c27-9989-95187e64d79b", - "type": "index-pattern", - "title": "ml_host_risk_score_latest_default" - }, - { - "id": "927a8467-ccc6-4374-85a4-0aab6c1c0613", - "type": "lens", - "title": "Current Risk Score for Hosts" - }, - { - "id": "aa7acd4e-b4e1-4730-acac-f73992034b0d", - "type": "dashboard", - "title": "Current Risk Score for Hosts" - } - ] - } -} -``` - -#### 7. POST - /internal/risk_score/prebuilt_content/saved_objects/_bulk_delete/{template_name} - -Import saved objects for host or user risk score -##### Option: - -|Param|description| -|--|--| -|template_name|value: `hostRiskScoreDashboards` or `userRiskScoreDashboards`| - -example: - -##### REQUEST: - -``` -POST /internal/risk_score/prebuilt_content/saved_objects/_bulk_delete/hostRiskScoreDashboards -``` - -##### RESPONSE: - -``` -[ - "Saved object [index-pattern/ml-host-risk-score-default-index-pattern] not found", - "Saved object [lens/d3f72670-d3a0-11eb-bd37-7bb50422e346] not found", - "Saved object [index-pattern/alerts-default-index-pattern] not found", - "Saved object [visualization/42371d00-cf7a-11eb-9a96-05d89f94ad96] not found", - "Saved object [visualization/a62d3ed0-cf92-11eb-a0ff-1763d16cbda7] not found", - "Saved object [visualization/b2dbc9b0-cf94-11eb-bd37-7bb50422e346] not found", - "Saved object [tag/1d00ebe0-f3b2-11eb-beb2-b91666445a94] not found", - "Saved object [dashboard/6f05c8c0-cf77-11eb-9a96-05d89f94ad96] not found", - "Saved object [index-pattern/ml-host-risk-score-latest-default-index-pattern] not found", - "Saved object [lens/dc289c10-d4ff-11eb-a0ff-1763d16cbda7] not found", - "Saved object [dashboard/27b483b0-d500-11eb-a0ff-1763d16cbda7] not found" -] -``` \ No newline at end of file diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts deleted file mode 100644 index 886e1fddeed2e..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/routes/index.ts +++ /dev/null @@ -1,20 +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. - */ -export { createEsIndexRoute } from '../indices/create_index_route'; -export { deleteEsIndicesRoute } from '../indices/delete_indices_route'; - -export { readPrebuiltDevToolContentRoute } from '../prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route'; - -export { createPrebuiltSavedObjectsRoute } from '../prebuilt_saved_objects/routes/create_prebuilt_saved_objects'; -export { deletePrebuiltSavedObjectsRoute } from '../prebuilt_saved_objects/routes/delete_prebuilt_saved_objects'; - -export { createStoredScriptRoute } from '../stored_scripts/create_script_route'; -export { deleteStoredScriptRoute } from '../stored_scripts/delete_script_route'; - -export { getRiskScoreIndexStatusRoute } from '../index_status'; - -export { installRiskScoresRoute } from '../onboarding/routes/install_risk_scores'; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.test.ts deleted file mode 100644 index 89d2618b74a72..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.test.ts +++ /dev/null @@ -1,101 +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. - */ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { Logger } from '@kbn/core/server'; -import { - serverMock, - requestContextMock, - requestMock, -} from '../../detection_engine/routes/__mocks__'; -import { createStoredScriptRoute } from './create_script_route'; -import { RISK_SCORE_CREATE_STORED_SCRIPT } from '../../../../common/constants'; -import { createStoredScript } from './lib/create_script'; -import { transformError } from '@kbn/securitysolution-es-utils'; - -const testScriptId = 'test-script'; -const testScriptSource = - 'if (state.host_variant_set == false) {\n if (doc.containsKey("host.os.full") && doc["host.os.full"].size() != 0) {\n state.host_variant = doc["host.os.full"].value;\n state.host_variant_set = true;\n }\n}\n// Aggregate all the tactics seen on the host\nif (doc.containsKey("signal.rule.threat.tactic.id") && doc["signal.rule.threat.tactic.id"].size() != 0) {\n state.tactic_ids.add(doc["signal.rule.threat.tactic.id"].value);\n}\n// Get running sum of time-decayed risk score per rule name per shard\nString rule_name = doc["signal.rule.name"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, [0.0,"",false]);\nint time_diff = (int)((System.currentTimeMillis() - doc["@timestamp"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0));\ndouble risk_derate = Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant));\nstats[0] = Math.max(stats[0], doc["signal.rule.risk_score"].value * risk_derate);\nif (stats[2] == false) {\n stats[1] = doc["kibana.alert.rule.uuid"].value;\n stats[2] = true;\n}\nstate.rule_risk_stats.put(rule_name, stats);'; - -jest.mock('./lib/create_script', () => { - const actualModule = jest.requireActual('./lib/create_script'); - return { - ...actualModule, - createStoredScript: jest - .fn() - .mockResolvedValue({ [testScriptId]: { success: true, error: null } }), - }; -}); - -describe('createStoredScriptRoute', () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - const logger = { error: jest.fn() } as unknown as Logger; - - beforeEach(() => { - jest.clearAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - - createStoredScriptRoute(server.router, logger); - }); - - it('Create stored script', async () => { - const request = requestMock.create({ - method: 'put', - path: RISK_SCORE_CREATE_STORED_SCRIPT, - body: { - id: testScriptId, - script: { - lang: 'painless', - source: testScriptSource, - }, - }, - }); - const response = await server.inject(request, requestContextMock.convertContext(context)); - expect(createStoredScript).toHaveBeenCalled(); - expect(response.status).toEqual(200); - }); - - it('Create stored script - should validate input', async () => { - const invalidRequest = requestMock.create({ - method: 'put', - path: RISK_SCORE_CREATE_STORED_SCRIPT, - }); - await server.inject(invalidRequest, requestContextMock.convertContext(context)); - const result = server.validate(invalidRequest); - - expect(result.ok).not.toHaveBeenCalled(); - }); - - it('return error if failed to create stored script', async () => { - (createStoredScript as jest.Mock).mockResolvedValue({ - [testScriptId]: { success: false, error: transformError(new Error('unknown error')) }, - }); - const request = requestMock.create({ - method: 'put', - path: RISK_SCORE_CREATE_STORED_SCRIPT, - body: { - id: testScriptId, - script: { - lang: 'painless', - source: testScriptSource, - }, - }, - }); - - const response = await server.inject(request, requestContextMock.convertContext(context)); - expect(createStoredScript).toHaveBeenCalled(); - expect(response.status).toEqual(500); - expect(response.body).toEqual({ message: 'unknown error', status_code: 500 }); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts deleted file mode 100644 index 85cd1fb9d1928..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Logger } from '@kbn/core/server'; -import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import { createStoredScriptRequestBody } from '../../../../common/api/entity_analytics/risk_score'; -import { RISK_SCORE_CREATE_STORED_SCRIPT } from '../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../types'; -import { createStoredScript } from './lib/create_script'; - -export const createStoredScriptRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { - router.versioned - .put({ - access: 'internal', - path: RISK_SCORE_CREATE_STORED_SCRIPT, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { validate: { request: { body: createStoredScriptRequestBody } }, version: '1' }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { client } = (await context.core).elasticsearch; - const esClient = client.asCurrentUser; - const options = request.body; - - try { - const result = await createStoredScript({ - esClient, - logger, - options, - }); - - const error = result[options.id].error; - if (error != null) { - return siemResponse.error({ statusCode: error.statusCode, body: error.message }); - } else { - return response.ok({ body: options }); - } - } catch (e) { - const error = transformError(e); - return siemResponse.error({ statusCode: error.statusCode, body: error.message }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.test.ts deleted file mode 100644 index 8d95c0854bcc4..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.test.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 { - serverMock, - requestContextMock, - requestMock, -} from '../../detection_engine/routes/__mocks__'; -import { deleteStoredScriptRoute } from './delete_script_route'; -import { RISK_SCORE_DELETE_STORED_SCRIPT } from '../../../../common/constants'; -import { deleteStoredScript } from './lib/delete_script'; - -jest.mock('./lib/delete_script', () => { - const actualModule = jest.requireActual('./lib/delete_script'); - return { - ...actualModule, - deleteStoredScript: jest.fn(), - }; -}); - -describe('deleteStoredScriptRoute', () => { - let server: ReturnType; - let { context } = requestContextMock.createTools(); - - beforeEach(() => { - jest.resetModules(); - jest.resetAllMocks(); - - server = serverMock.create(); - ({ context } = requestContextMock.createTools()); - - deleteStoredScriptRoute(server.router); - }); - - it('delete indices', async () => { - const request = requestMock.create({ - method: 'delete', - path: RISK_SCORE_DELETE_STORED_SCRIPT, - body: { id: 'test-script' }, - }); - const response = await server.inject(request, requestContextMock.convertContext(context)); - expect(deleteStoredScript).toHaveBeenCalled(); - expect(response.status).toEqual(200); - }); - - it('delete indices - should validate input', async () => { - const invalidRequest = requestMock.create({ - method: 'delete', - path: RISK_SCORE_DELETE_STORED_SCRIPT, - }); - await server.inject(invalidRequest, requestContextMock.convertContext(context)); - const result = server.validate(invalidRequest); - - expect(result.ok).not.toHaveBeenCalled(); - }); -}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts deleted file mode 100644 index 91bf387d55bd0..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; -import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; -import { RISK_SCORE_DELETE_STORED_SCRIPT } from '../../../../common/constants'; -import type { SecuritySolutionPluginRouter } from '../../../types'; -import { deleteStoredScript } from './lib/delete_script'; -import { deleteStoredScriptRequestBody } from '../../../../common/api/entity_analytics/risk_score'; - -export const deleteStoredScriptRoute = (router: SecuritySolutionPluginRouter) => { - router.versioned - .delete({ - access: 'internal', - path: RISK_SCORE_DELETE_STORED_SCRIPT, - security: { - authz: { - requiredPrivileges: ['securitySolution'], - }, - }, - }) - .addVersion( - { validate: { request: { body: deleteStoredScriptRequestBody } }, version: '1' }, - async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - const { client } = (await context.core).elasticsearch; - const options = request.body; - try { - await deleteStoredScript({ - client, - options, - }); - return response.ok({ body: options }); - } catch (err) { - const error = transformError(err); - return siemResponse.error({ - body: error.message, - statusCode: error.statusCode, - }); - } - } - ); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts deleted file mode 100644 index d6c2e5211625b..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { CreateStoredScriptRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -export const createStoredScript = async ({ - esClient, - logger, - options, -}: { - esClient: ElasticsearchClient; - logger: Logger; - options: CreateStoredScriptRequestBody; -}) => { - try { - await esClient.putScript(options); - return { [options.id]: { success: true, error: null } }; - } catch (error) { - const createScriptError = transformError(error); - logger.error(`Failed to create stored script: ${options.id}: ${createScriptError.message}`); - return { [options.id]: { success: false, error: createScriptError } }; - } -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts deleted file mode 100644 index bbbf8e9582ff5..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts +++ /dev/null @@ -1,18 +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 { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; -import type { DeleteStoredScriptRequestBody } from '../../../../../common/api/entity_analytics/risk_score'; - -export const deleteStoredScript = async ({ - client, - options, -}: { - client: IScopedClusterClient; - options: DeleteStoredScriptRequestBody; -}) => { - await client.asCurrentUser.deleteScript(options); -}; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts b/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts deleted file mode 100644 index da62185ddd125..0000000000000 --- a/x-pack/plugins/security_solution/server/lib/risk_score/transform/helpers/transforms.ts +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { transformError } from '@kbn/securitysolution-es-utils'; -import type { TransformPutTransformRequest } from '@elastic/elasticsearch/lib/api/types'; -import type { ElasticsearchClient, Logger } from '@kbn/core/server'; -import { i18n } from '@kbn/i18n'; - -export const TRANSFORM_STATE = { - ABORTING: 'aborting', - FAILED: 'failed', - INDEXING: 'indexing', - STARTED: 'started', - STOPPED: 'stopped', - STOPPING: 'stopping', - WAITING: 'waiting', -} as const; - -export const createAndStartTransform = ({ - esClient, - transformId, - options, - logger, -}: { - esClient: ElasticsearchClient; - transformId: string; - options: string | Omit; - logger: Logger; -}) => { - const transformOptions = typeof options === 'string' ? JSON.parse(options) : options; - const transform = { - transform_id: transformId, - ...transformOptions, - }; - return createTransformIfNotExists(esClient, transform, logger).then((result) => { - if (result[transform.transform_id].success) { - return startTransformIfNotStarted(esClient, transform.transform_id, logger); - } else { - return result; - } - }); -}; -/** - * Checks if a transform exists, And if not creates it - * @param transform - the transform to create. If a transform with the same transform_id already exists, nothing is created. - */ -export const createTransformIfNotExists = async ( - esClient: ElasticsearchClient, - transform: TransformPutTransformRequest, - logger: Logger -) => { - try { - await esClient.transform.getTransform({ - transform_id: transform.transform_id, - }); - - logger.error(`Transform ${transform.transform_id} already exists`); - return { - [transform.transform_id]: { - success: false, - isExist: true, - error: transformError( - new Error( - i18n.translate('xpack.securitySolution.riskScore.transform.transformExistsTitle', { - values: { transformId: transform.transform_id }, - defaultMessage: `Failed to create Transform as {transformId} already exists`, - }) - ) - ), - }, - }; - } catch (existErr) { - const existError = transformError(existErr); - if (existError.statusCode === 404) { - try { - await esClient.transform.putTransform(transform); - - return { [transform.transform_id]: { success: true, isExist: true, error: null } }; - } catch (createErr) { - const createError = transformError(createErr); - logger.error( - `Failed to create transform ${transform.transform_id}: ${createError.message}` - ); - return { [transform.transform_id]: { success: false, isExist: false, error: createError } }; - } - } else { - logger.error( - `Failed to check if transform ${transform.transform_id} exists before creation: ${existError.message}` - ); - return { [transform.transform_id]: { success: false, isExist: false, error: existError } }; - } - } -}; - -const checkTransformState = async ( - esClient: ElasticsearchClient, - transformId: string, - logger: Logger -) => { - try { - const transformStats = await esClient.transform.getTransformStats({ - transform_id: transformId, - }); - if (transformStats.count <= 0) { - logger.error(`Failed to check ${transformId} state: couldn't find transform`); - - return { - [transformId]: { - success: false, - error: transformError( - new Error( - i18n.translate('xpack.securitySolution.riskScore.transform.notFoundTitle', { - values: { transformId }, - defaultMessage: `Failed to check Transform state as {transformId} not found`, - }) - ) - ), - }, - }; - } - - return transformStats.transforms[0]; - } catch (statsErr) { - const statsError = transformError(statsErr); - - logger.error(`Failed to check if transform ${transformId} is started: ${statsError.message}`); - return { - [transformId]: { - success: false, - error: statsErr, - }, - }; - } -}; - -export const startTransformIfNotStarted = async ( - esClient: ElasticsearchClient, - transformId: string, - logger: Logger -) => { - const fetchedTransformStats = await checkTransformState(esClient, transformId, logger); - if (fetchedTransformStats.state === 'stopped') { - try { - await esClient.transform.startTransform({ transform_id: transformId }); - return { [transformId]: { success: true, error: null } }; - } catch (startErr) { - const startError = transformError(startErr); - - logger.error(`Failed starting transform ${transformId}: ${startError.message}`); - return { - [transformId]: { - success: false, - error: startError, - }, - }; - } - } else if ( - fetchedTransformStats.state === TRANSFORM_STATE.STOPPING || - fetchedTransformStats.state === TRANSFORM_STATE.ABORTING || - fetchedTransformStats.state === TRANSFORM_STATE.FAILED - ) { - logger.error( - `Not starting transform ${transformId} since it's state is: ${fetchedTransformStats.state}` - ); - return { - [transformId]: { - success: false, - error: transformError( - new Error( - i18n.translate('xpack.securitySolution.riskScore.transform.start.stateConflictTitle', { - values: { transformId, state: fetchedTransformStats.state }, - defaultMessage: `Not starting transform {transformId} since it's state is: {state}`, - }) - ) - ), - }, - }; - } - return { [transformId]: { success: true, error: null } }; -}; diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index f7d5ce7afb3d3..c4814107b48c1 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -41,17 +41,6 @@ import type { ITelemetryReceiver } from '../lib/telemetry/receiver'; import { telemetryDetectionRulesPreviewRoute } from '../lib/detection_engine/routes/telemetry/telemetry_detection_rules_preview_route'; import { readAlertsIndexExistsRoute } from '../lib/detection_engine/routes/index/read_alerts_index_exists_route'; import { registerResolverRoutes } from '../endpoint/routes/resolver'; -import { - createEsIndexRoute, - createPrebuiltSavedObjectsRoute, - createStoredScriptRoute, - deleteEsIndicesRoute, - deletePrebuiltSavedObjectsRoute, - deleteStoredScriptRoute, - getRiskScoreIndexStatusRoute, - installRiskScoresRoute, - readPrebuiltDevToolContentRoute, -} from '../lib/risk_score/routes'; import { registerManageExceptionsRoutes } from '../lib/exceptions/api/register_routes'; import { registerDashboardsRoutes } from '../lib/dashboards/routes'; import { registerTagsRoutes } from '../lib/tags/routes'; @@ -125,17 +114,6 @@ export const initRoutes = ( // Privileges API to get the generic user privileges readPrivilegesRoute(router, hasEncryptionKey); - // risky score module - createEsIndexRoute(router, logger); - deleteEsIndicesRoute(router); - createStoredScriptRoute(router, logger); - deleteStoredScriptRoute(router); - readPrebuiltDevToolContentRoute(router); - createPrebuiltSavedObjectsRoute(router, logger); - deletePrebuiltSavedObjectsRoute(router); - getRiskScoreIndexStatusRoute(router); - installRiskScoresRoute(router, logger); - // Dashboards registerDashboardsRoutes(router, logger); registerTagsRoutes(router, logger); diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/__mocks__/index.ts index e6069d12886fe..9c5cbdf35b89e 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/__mocks__/index.ts @@ -31,7 +31,6 @@ export const mockOptions: HostsRequestOptions = { pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 50, querySize: 10 }, timerange: { interval: '12h', from: '2020-09-03T09:15:21.415Z', to: '2020-09-04T09:15:21.415Z' }, sort: { direction: Direction.desc, field: HostsFields.lastSeen }, - isNewRiskScoreModuleInstalled: false, }; export const mockSearchStrategyResponse: IEsSearchResponse = { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts index ad60ec516cb53..a07b8e7b5b440 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.ts @@ -72,13 +72,7 @@ export const allHosts: SecuritySolutionFactory = { const hostNames = edges.map((edge) => getOr('', 'node.host.name[0]', edge)); const enhancedEdges = deps?.spaceId - ? await enhanceEdges( - edges, - hostNames, - deps.spaceId, - deps.esClient, - options.isNewRiskScoreModuleInstalled - ) + ? await enhanceEdges(edges, hostNames, deps.spaceId, deps.esClient) : edges; return { @@ -99,11 +93,10 @@ async function enhanceEdges( edges: HostsEdges[], hostNames: string[], spaceId: string, - esClient: IScopedClusterClient, - isNewRiskScoreModuleInstalled: boolean + esClient: IScopedClusterClient ): Promise { const [riskByHostName, criticalityByHostName] = await Promise.all([ - getHostRiskData(esClient, spaceId, hostNames, isNewRiskScoreModuleInstalled).then( + getHostRiskData(esClient, spaceId, hostNames).then( buildRecordFromAggs('host.name', 'host.risk.calculated_level') ), getHostCriticalityData(esClient, hostNames).then( @@ -124,13 +117,12 @@ async function enhanceEdges( export async function getHostRiskData( esClient: IScopedClusterClient, spaceId: string, - hostNames: string[], - isNewRiskScoreModuleInstalled: boolean + hostNames: string[] ) { try { const hostRiskResponse = await esClient.asCurrentUser.search( buildRiskScoreQuery({ - defaultIndex: [getHostRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled)], + defaultIndex: [getHostRiskIndex(spaceId, true)], filterQuery: buildHostNamesFilter(hostNames), riskScoreEntity: RiskScoreEntity.host, factoryQueryType: RiskQueries.hostsRiskScore, diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/__mocks__/index.ts index 1978493803392..ba257d7d1b51a 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/__mocks__/index.ts @@ -21,7 +21,6 @@ export const mockOptions: RelatedHostsRequestOptions = { factoryQueryType: RelatedEntitiesQueries.relatedHosts, userName: 'user1', from: '2020-09-02T15:17:13.678Z', - isNewRiskScoreModuleInstalled: false, }; export const mockSearchStrategyResponse: IEsSearchResponse = { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/index.ts index a736c486e9ef7..769e28b5fb4fd 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_hosts/index.ts @@ -57,12 +57,7 @@ export const usersRelatedHosts: SecuritySolutionFactory { const hostNames = relatedHosts.map((item) => item.host); - const hostRiskData = await getHostRiskData( - esClient, - spaceId, - hostNames, - isNewRiskScoreModuleInstalled - ); + const hostRiskData = await getHostRiskData(esClient, spaceId, hostNames); const hostsRiskByHostName: Record | undefined = hostRiskData?.hits.hits.reduce( (acc, hit) => ({ diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/__mocks__/index.ts index eb7841382a684..3dc412b7faef1 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/__mocks__/index.ts @@ -21,7 +21,6 @@ export const mockOptions: RelatedUsersRequestOptions = { factoryQueryType: RelatedEntitiesQueries.relatedUsers, hostName: 'host1', from: '2020-09-02T15:17:13.678Z', - isNewRiskScoreModuleInstalled: false, }; export const mockSearchStrategyResponse: IEsSearchResponse = { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/index.ts index 9ad579f5d9b54..d12d205e2d525 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/related_entities/related_users/index.ts @@ -56,12 +56,7 @@ export const hostsRelatedUsers: SecuritySolutionFactory { const userNames = relatedUsers.map((item) => item.user); - const userRiskData = await getUserRiskData( - esClient, - spaceId, - userNames, - isNewRiskScoreModuleInstalled - ); + const userRiskData = await getUserRiskData(esClient, spaceId, userNames); const usersRiskByUserName: Record | undefined = userRiskData?.hits.hits.reduce( (acc, hit) => ({ diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts index df8cf7449bb38..4fea1ba3e1887 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/__mocks__/index.ts @@ -33,7 +33,6 @@ export const mockOptions: UsersRequestOptions = { querySize: 10, }, sort: { field: UsersFields.name, direction: Direction.asc }, - isNewRiskScoreModuleInstalled: false, }; export const mockSearchStrategyResponse: IEsSearchResponse = { diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts index 7ae8371152dde..874950d3c7418 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.ts @@ -78,13 +78,7 @@ export const allUsers: SecuritySolutionFactory = { const edges = users.splice(cursorStart, querySize - cursorStart); const userNames = edges.map(({ name }) => name); const enhancedEdges = deps?.spaceId - ? await enhanceEdges( - edges, - userNames, - deps.spaceId, - deps.esClient, - options.isNewRiskScoreModuleInstalled - ) + ? await enhanceEdges(edges, userNames, deps.spaceId, deps.esClient) : edges; return { @@ -105,11 +99,10 @@ async function enhanceEdges( edges: User[], userNames: string[], spaceId: string, - esClient: IScopedClusterClient, - isNewRiskScoreModuleInstalled: boolean + esClient: IScopedClusterClient ): Promise { const [riskByUserName, criticalityByUserName] = await Promise.all([ - getUserRiskData(esClient, spaceId, userNames, isNewRiskScoreModuleInstalled).then( + getUserRiskData(esClient, spaceId, userNames).then( buildRecordFromAggs('user.name', 'user.risk.calculated_level') ), getUserCriticalityData(esClient, userNames).then( @@ -129,13 +122,12 @@ async function enhanceEdges( export async function getUserRiskData( esClient: IScopedClusterClient, spaceId: string, - userNames: string[], - isNewRiskScoreModuleInstalled: boolean + userNames: string[] ) { try { const userRiskResponse = await esClient.asCurrentUser.search( buildRiskScoreQuery({ - defaultIndex: [getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled)], + defaultIndex: [getUserRiskIndex(spaceId, true)], filterQuery: buildUserNamesFilter(userNames), riskScoreEntity: RiskScoreEntity.user, factoryQueryType: RiskQueries.usersRiskScore, diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/init_and_status_apis.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/init_and_status_apis.ts index bbcfd976abeb7..161c2c114769c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/init_and_status_apis.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/init_and_status_apis.ts @@ -8,15 +8,7 @@ import expect from '@kbn/expect'; import { riskEngineConfigurationTypeName } from '@kbn/security-solution-plugin/server/lib/entity_analytics/risk_engine/saved_object'; -import { - legacyTransformIds, - createLegacyTransforms, - clearLegacyTransforms, - riskEngineRouteHelpersFactory, - installLegacyRiskScore, - getLegacyRiskScoreDashboards, - clearLegacyDashboards, -} from '../../utils'; +import { riskEngineRouteHelpersFactory } from '../../utils'; import { FtrProviderContext } from '../../../../ftr_provider_context'; const expectTaskIsNotRunning = (taskStatus?: string) => { @@ -31,7 +23,6 @@ export default ({ getService }: FtrProviderContext) => { const customSpaceName = 'ea-customspace-it'; const riskEngineRoutes = riskEngineRouteHelpersFactory(supertest); const riskEngineRoutesWithNamespace = riskEngineRouteHelpersFactory(supertest, customSpaceName); - const log = getService('log'); describe('@ess @serverless @serverlessQA init_and_status_apis', () => { before(async () => { @@ -48,8 +39,6 @@ export default ({ getService }: FtrProviderContext) => { afterEach(async () => { await riskEngineRoutes.cleanUp(); await riskEngineRoutesWithNamespace.cleanUp(); - await clearLegacyTransforms({ es, log }); - await clearLegacyDashboards({ supertest, log }); await spaces.delete(customSpaceName); }); @@ -59,7 +48,6 @@ export default ({ getService }: FtrProviderContext) => { expect(response.body).to.eql({ result: { errors: [], - legacy_risk_engine_disabled: true, risk_engine_configuration_created: true, risk_engine_enabled: true, risk_engine_resources_installed: true, @@ -70,7 +58,6 @@ export default ({ getService }: FtrProviderContext) => { expect(customNamespaceResponse.body).to.eql({ result: { errors: [], - legacy_risk_engine_disabled: true, risk_engine_configuration_created: true, risk_engine_enabled: true, risk_engine_resources_installed: true, @@ -618,46 +605,6 @@ export default ({ getService }: FtrProviderContext) => { expect(response2.component_templates.length).to.eql(1); expect(response2.component_templates[0].name).to.eql(newComponentTemplateName); }); - - // Failing: See https://github.com/elastic/kibana/issues/191637 - describe.skip('remove legacy risk score transform', function () { - this.tags('skipFIPS'); - it('should remove legacy risk score transform if it exists', async () => { - await installLegacyRiskScore({ supertest }); - - for (const transformId of legacyTransformIds) { - const tr = await es.transform.getTransform({ - transform_id: transformId, - }); - - expect(tr?.transforms?.[0]?.id).to.eql(transformId); - } - - const legacyDashboards = await getLegacyRiskScoreDashboards({ - kibanaServer, - }); - - expect(legacyDashboards.length).to.eql(4); - - await riskEngineRoutes.init(); - - for (const transformId of legacyTransformIds) { - try { - await es.transform.getTransform({ - transform_id: transformId, - }); - } catch (err) { - expect(err).to.not.be(undefined); - } - } - - const legacyDashboardsAfterInit = await getLegacyRiskScoreDashboards({ - kibanaServer, - }); - - expect(legacyDashboardsAfterInit.length).to.eql(0); - }); - }); }); // FLAKY: https://github.com/elastic/kibana/issues/196319 @@ -668,7 +615,6 @@ export default ({ getService }: FtrProviderContext) => { expect(status1.body).to.eql({ risk_engine_status: 'NOT_INSTALLED', - legacy_risk_engine_status: 'NOT_INSTALLED', }); await riskEngineRoutes.init(); @@ -676,7 +622,6 @@ export default ({ getService }: FtrProviderContext) => { const status2 = await riskEngineRoutes.getStatus(); expect(status2.body.risk_engine_status).to.be('ENABLED'); - expect(status2.body.legacy_risk_engine_status).to.be('NOT_INSTALLED'); expect(status2.body.risk_engine_task_status?.runAt).to.be.a('string'); expectTaskIsNotRunning(status2.body.risk_engine_task_status?.status); @@ -687,40 +632,17 @@ export default ({ getService }: FtrProviderContext) => { expect(status3.body).to.eql({ risk_engine_status: 'DISABLED', - legacy_risk_engine_status: 'NOT_INSTALLED', }); await riskEngineRoutes.enable(); const status4 = await riskEngineRoutes.getStatus(); expect(status4.body.risk_engine_status).to.be('ENABLED'); - expect(status4.body.legacy_risk_engine_status).to.be('NOT_INSTALLED'); expect(status4.body.risk_engine_task_status?.runAt).to.be.a('string'); expectTaskIsNotRunning(status4.body.risk_engine_task_status?.status); expect(status4.body.risk_engine_task_status?.startedAt).to.be(undefined); }); - - it('should return status of legacy risk engine', async () => { - await createLegacyTransforms({ es }); - const status1 = await riskEngineRoutes.getStatus(); - - expect(status1.body).to.eql({ - risk_engine_status: 'NOT_INSTALLED', - legacy_risk_engine_status: 'ENABLED', - }); - - await riskEngineRoutes.init(); - - const status2 = await riskEngineRoutes.getStatus(); - - expect(status2.body.risk_engine_status).to.be('ENABLED'); - expect(status2.body.legacy_risk_engine_status).to.be('NOT_INSTALLED'); - - expect(status2.body.risk_engine_task_status?.runAt).to.be.a('string'); - expectTaskIsNotRunning(status2.body.risk_engine_task_status?.status); - expect(status2.body.risk_engine_task_status?.startedAt).to.be(undefined); - }); }); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_cleanup_api.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_cleanup_api.ts index 968b234509d34..baafb7ac8cf26 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_cleanup_api.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_cleanup_api.ts @@ -45,7 +45,6 @@ export default ({ getService }: FtrProviderContext) => { it('should return response with success status', async () => { const status1 = await riskEngineRoutes.getStatus(); expect(status1.body.risk_engine_status).to.be('NOT_INSTALLED'); - expect(status1.body.legacy_risk_engine_status).to.be('NOT_INSTALLED'); const firstDocumentId = uuidv4(); await indexListOfDocuments([buildDocument({ host: { name: 'host-1' } }, firstDocumentId)]); @@ -56,7 +55,6 @@ export default ({ getService }: FtrProviderContext) => { const status2 = await riskEngineRoutes.getStatus(); expect(status2.body.risk_engine_status).to.be('ENABLED'); - expect(status2.body.legacy_risk_engine_status).to.be('NOT_INSTALLED'); const response = await riskEngineRoutes.cleanUp(); expect(response.body).to.eql({ @@ -69,7 +67,6 @@ export default ({ getService }: FtrProviderContext) => { const status3 = await riskEngineRoutes.getStatus(); expect(status3.body.risk_engine_status).to.be('NOT_INSTALLED'); - expect(status3.body.legacy_risk_engine_status).to.be('NOT_INSTALLED'); }); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_schedule_now.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_schedule_now.ts index b4dbd27a323f5..18b827cb5a78c 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_schedule_now.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/risk_engine_schedule_now.ts @@ -9,8 +9,6 @@ import { v4 as uuidv4 } from 'uuid'; import { deleteAllAlerts, deleteAllRules } from '../../../../../common/utils/security_solution'; import { buildDocument, - clearLegacyDashboards, - clearLegacyTransforms, createAndSyncRuleAndAlertsFactory, riskEngineRouteHelpersFactory, waitForRiskEngineRun, @@ -27,8 +25,6 @@ export default ({ getService }: FtrProviderContext) => { const log = getService('log'); const cleanAllResources = async () => { - await clearLegacyTransforms({ es, log }); - await clearLegacyDashboards({ supertest, log }); await deleteAllAlerts(supertest, log, es); await deleteAllRules(supertest, log); await riskEngineRoutes.cleanUp(); diff --git a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/risk_engine.ts b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/risk_engine.ts index 0a88e9fbe2518..a2eae32a79179 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/risk_engine.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/entity_analytics/utils/risk_engine.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { - ELASTIC_HTTP_VERSION_HEADER, - X_ELASTIC_INTERNAL_ORIGIN_REQUEST, -} from '@kbn/core-http-common'; +import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common'; import { v4 as uuidv4 } from 'uuid'; import SuperTest from 'supertest'; import type { Client } from '@elastic/elasticsearch'; @@ -26,7 +23,6 @@ import { RISK_ENGINE_SCHEDULE_NOW_URL, } from '@kbn/security-solution-plugin/common/constants'; import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types'; -import { removeLegacyTransforms } from '@kbn/security-solution-plugin/server/lib/entity_analytics/utils/transforms'; import { EntityRiskScoreRecord } from '@kbn/security-solution-plugin/common/api/entity_analytics/common'; import { SupertestWithoutAuthProviderType } from '@kbn/ftr-common-functional-services'; @@ -395,103 +391,6 @@ export const updateRiskEngineConfigSO = async ({ } }; -export const legacyTransformIds = [ - 'ml_hostriskscore_pivot_transform_default', - 'ml_hostriskscore_latest_transform_default', - 'ml_userriskscore_pivot_transform_default', - 'ml_userriskscore_latest_transform_default', -]; - -export const clearLegacyTransforms = async ({ - es, - log, -}: { - es: Client; - log: ToolingLog; -}): Promise => { - try { - await removeLegacyTransforms({ - namespace: 'default', - esClient: es, - }); - } catch (e) { - log.warning(`Error deleting legacy transforms: ${e.message}`); - } -}; - -export const clearLegacyDashboards = async ({ - supertest, - log, -}: { - supertest: SuperTest.Agent; - log: ToolingLog; -}): Promise => { - try { - await supertest - .post( - '/internal/risk_score/prebuilt_content/saved_objects/_bulk_delete/hostRiskScoreDashboards' - ) - .set('kbn-xsrf', 'true') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send(); - - await supertest - .post( - '/internal/risk_score/prebuilt_content/saved_objects/_bulk_delete/userRiskScoreDashboards' - ) - .set('kbn-xsrf', 'true') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send(); - } catch (e) { - log.warning(`Error deleting legacy dashboards: ${e.message}`); - } -}; - -export const createLegacyTransforms = async ({ es }: { es: Client }): Promise => { - const transforms = legacyTransformIds.map((transform) => - es.transform.putTransform({ - transform_id: transform, - source: { - index: ['.alerts-security.alerts-default'], - }, - dest: { - index: 'ml_host_risk_score_default', - }, - pivot: { - group_by: { - 'host.name': { - terms: { - field: 'host.name', - }, - }, - }, - aggregations: { - '@timestamp': { - max: { - field: '@timestamp', - }, - }, - }, - }, - settings: {}, - }) - ); - - await Promise.all(transforms); -}; - -export const getLegacyRiskScoreDashboards = async ({ - kibanaServer, -}: { - kibanaServer: KbnClient; -}) => { - const savedObejectLens = await kibanaServer.savedObjects.find({ - type: 'lens', - }); - - return savedObejectLens?.saved_objects.filter((s) => s?.attributes?.title?.includes('Risk')); -}; - const assertStatusCode = (statusCode: number, response: SuperTest.Response) => { if (response.status !== statusCode) { throw new Error( @@ -647,41 +546,3 @@ export const riskEngineRouteHelpersFactoryNoAuth = ( return response; }, }); - -export const installLegacyRiskScore = async ({ supertest }: { supertest: SuperTest.Agent }) => { - await supertest - .post('/internal/risk_score') - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '1') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send({ riskScoreEntity: 'host' }) - .expect(200); - - await supertest - .post('/internal/risk_score') - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '1') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send({ riskScoreEntity: 'user' }) - .expect(200); - - await supertest - .post( - '/internal/risk_score/prebuilt_content/saved_objects/_bulk_create/hostRiskScoreDashboards' - ) - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '1') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send() - .expect(200); - - await supertest - .post( - '/internal/risk_score/prebuilt_content/saved_objects/_bulk_create/userRiskScoreDashboards' - ) - .set('kbn-xsrf', 'true') - .set(ELASTIC_HTTP_VERSION_HEADER, '1') - .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') - .send() - .expect(200); -}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts b/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts index 2265f228c2ce7..c654781c23be3 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts @@ -5,10 +5,7 @@ * 2.0. */ -import { - RISK_ENGINE_STATUS_URL, - RISK_SCORE_INDEX_STATUS_API_URL, -} from '@kbn/security-solution-plugin/common/constants'; +import { RISK_ENGINE_STATUS_URL } from '@kbn/security-solution-plugin/common/constants'; import { BASIC_TABLE_LOADING } from '../screens/common'; import { ANOMALIES_TABLE_ROWS, @@ -67,15 +64,6 @@ export const mockRiskEngineEnabled = () => { legacy_risk_engine_status: 'INSTALLED', }, }).as('riskEngineStatus'); - - // mock the risk index status - cy.intercept('GET', `${RISK_SCORE_INDEX_STATUS_API_URL}?indexName=*&entity=*`, { - statusCode: 200, - body: { - isDeprecated: false, - isEnabled: true, - }, - }).as('riskIndexStatus'); }; /** From 6534ff3c897e412ce1e1e6494875673edcaa2222 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 13:58:33 +0000 Subject: [PATCH 02/38] fix index not found error handling --- .../public/common/utils/exceptions/index.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/utils/exceptions/index.ts b/x-pack/plugins/security_solution/public/common/utils/exceptions/index.ts index bc4b93112963f..01e09eb683467 100644 --- a/x-pack/plugins/security_solution/public/common/utils/exceptions/index.ts +++ b/x-pack/plugins/security_solution/public/common/utils/exceptions/index.ts @@ -5,9 +5,15 @@ * 2.0. */ -export const isIndexNotFoundError = (error: unknown): boolean => - ( - error as { - attributes?: { caused_by?: { type?: string } }; - } - ).attributes?.caused_by?.type === 'index_not_found_exception'; +export const isIndexNotFoundError = (error: unknown): boolean => { + const castError = error as { + attributes?: { + caused_by?: { type?: string }; + error?: { caused_by?: { type?: string } }; + }; + }; + return ( + castError.attributes?.caused_by?.type === 'index_not_found_exception' || + castError.attributes?.error?.caused_by?.type === 'index_not_found_exception' + ); +}; From e32da1554dc557dc765d940eec434361ea8f373b Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 13:59:35 +0000 Subject: [PATCH 03/38] rename isEnabled to hasEngineBeenInstalled and only search risk score when engine has been installed --- .../api/hooks/use_risk_score.tsx | 18 +++++++++++++----- .../entity_analytics_risk_score/index.tsx | 6 +++--- .../components/risk_details_tab_body/index.tsx | 6 +++--- .../components/user_risk_score_tab_body.tsx | 11 ++++++++--- .../navigation/host_risk_score_tab_body.tsx | 6 +++--- .../entity_details/host_right/content.tsx | 2 +- .../flyout/entity_details/mocks/index.ts | 4 ++-- .../entity_details/user_right/content.tsx | 2 +- .../public/flyout/shared/mocks/index.ts | 2 +- 9 files changed, 35 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx index 50756f092e27b..f34aad9064567 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx @@ -34,7 +34,7 @@ export interface RiskScoreState({ factoryQueryType, initialResult, - abort: skip, + abort: skip || !hasEngineBeenInstalled || isStatusLoading || !isAuthorized, showErrorToast: false, }); const refetchAll = useCallback(() => { @@ -113,10 +113,18 @@ export const useRiskScore = ; } diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx index 4c26749c86319..c8256395c337d 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx @@ -69,7 +69,7 @@ const RiskDetailsTabBodyComponent: React.FC< [entityName, riskEntity] ); - const { data, loading, refetch, inspect, isEngineEnabled } = useRiskScore({ + const { data, loading, refetch, inspect, hasEngineBeenInstalled } = useRiskScore({ filterQuery, onlyLatest: false, riskEntity, @@ -109,7 +109,7 @@ const RiskDetailsTabBodyComponent: React.FC< } const status = { - isDisabled: !isEngineEnabled && !loading, + isDisabled: !hasEngineBeenInstalled && !loading, }; if (status.isDisabled) { @@ -123,7 +123,7 @@ const RiskDetailsTabBodyComponent: React.FC< ); } - if (isEngineEnabled && severitySelectionRedux.length === 0 && data && data.length === 0) { + if (hasEngineBeenInstalled && severitySelectionRedux.length === 0 && data && data.length === 0) { return ; } diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx index ad312e3a8b499..d74966fceacf7 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx @@ -66,7 +66,7 @@ export const UserRiskScoreQueryTabBody = ({ const privileges = useMissingRiskEnginePrivileges(); - const { data, inspect, isInspected, isEngineEnabled, loading, refetch, totalCount } = + const { data, inspect, isInspected, hasEngineBeenInstalled, loading, refetch, totalCount } = useRiskScore({ filterQuery, pagination, @@ -82,7 +82,7 @@ export const UserRiskScoreQueryTabBody = ({ skip: querySkip, }); - const isDisabled = !isEngineEnabled && !loading; + const isDisabled = !hasEngineBeenInstalled && !loading; const RiskScoreUpsell = useUpsellingComponent('entity_analytics_panel'); if (RiskScoreUpsell) { @@ -110,7 +110,12 @@ export const UserRiskScoreQueryTabBody = ({ ); } - if (isEngineEnabled && userSeveritySelectionRedux.length === 0 && data && data.length === 0) { + if ( + hasEngineBeenInstalled && + userSeveritySelectionRedux.length === 0 && + data && + data.length === 0 + ) { return ; } diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx index ccd44230a9d16..9a4e88c89a6ed 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx @@ -64,7 +64,7 @@ export const HostRiskScoreQueryTabBody = ({ const timerange = useMemo(() => ({ from, to }), [from, to]); const privileges = useMissingRiskEnginePrivileges(); - const { data, inspect, isInspected, isEngineEnabled, loading, refetch, totalCount } = + const { data, inspect, isInspected, hasEngineBeenInstalled, loading, refetch, totalCount } = useRiskScore({ filterQuery, pagination, @@ -80,7 +80,7 @@ export const HostRiskScoreQueryTabBody = ({ riskEntity: RiskScoreEntity.host, }); - const isDisabled = !isEngineEnabled && !loading; + const isDisabled = !hasEngineBeenInstalled && !loading; const RiskScoreUpsell = useUpsellingComponent('entity_analytics_panel'); if (RiskScoreUpsell) { @@ -110,7 +110,7 @@ export const HostRiskScoreQueryTabBody = ({ if ( !loading && - isEngineEnabled && + hasEngineBeenInstalled && severitySelectionRedux.length === 0 && data && data.length === 0 diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx index cf6ca20ef9daa..e087e5e65c356 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx @@ -48,7 +48,7 @@ export const HostPanelContent = ({ return ( - {riskScoreState.isEngineEnabled && riskScoreState.data?.length !== 0 && ( + {riskScoreState.hasEngineBeenInstalled && riskScoreState.data?.length !== 0 && ( <> = { refetch: () => {}, totalCount: 0, isAuthorized: true, - isEngineEnabled: true, + hasEngineBeenInstalled: true, loading: false, error: undefined, }; @@ -111,7 +111,7 @@ export const mockHostRiskScoreState: RiskScoreState = { refetch: () => {}, totalCount: 0, isAuthorized: true, - isEngineEnabled: true, + hasEngineBeenInstalled: true, loading: false, error: undefined, }; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx index 3a23fd6cb8b0e..d1149a55bd398 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx @@ -57,7 +57,7 @@ export const UserPanelContent = ({ return ( - {riskScoreState.isEngineEnabled && riskScoreState.data?.length !== 0 && ( + {riskScoreState.hasEngineBeenInstalled && riskScoreState.data?.length !== 0 && ( <> {}, totalCount: 0, - isEngineEnabled: true, + hasEngineBeenInstalled: true, isAuthorized: true, isDeprecated: false, loading: false, From 98a53391de5d792cfc6da099f66eb6e52eaca494 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 14:09:48 +0000 Subject: [PATCH 04/38] remove unused tests --- .../entity_analytics/legacy_risk_score.cy.ts | 298 ------------------ ...{new_risk_score.cy.ts => risk_score.cy.ts} | 0 .../e2e/entity_analytics/enrichments.cy.ts | 41 +-- 3 files changed, 1 insertion(+), 338 deletions(-) delete mode 100644 x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/legacy_risk_score.cy.ts rename x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/{new_risk_score.cy.ts => risk_score.cy.ts} (100%) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/legacy_risk_score.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/legacy_risk_score.cy.ts deleted file mode 100644 index 71f2e619cc536..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/legacy_risk_score.cy.ts +++ /dev/null @@ -1,298 +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 moment from 'moment'; -import { updateDashboardTimeRange } from '../../../../tasks/entity_analytics'; -import { login } from '../../../../tasks/login'; -import { visitWithTimeRange } from '../../../../tasks/navigation'; - -import { ALERTS_URL, ENTITY_ANALYTICS_URL } from '../../../../urls/navigation'; - -import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; - -import { - ENABLE_HOST_RISK_SCORE_BUTTON, - ENABLE_USER_RISK_SCORE_BUTTON, - HOSTS_DONUT_CHART, - HOSTS_TABLE_ROWS, - HOST_RISK_SCORE_NO_DATA_DETECTED, - USERS_DONUT_CHART, - USERS_TABLE, - USERS_TABLE_ROWS, - USER_RISK_SCORE_NO_DATA_DETECTED, - USERS_TABLE_ALERT_CELL, - HOSTS_TABLE_ALERT_CELL, - HOSTS_TABLE, -} from '../../../../screens/entity_analytics'; -import { - openRiskTableFilterAndSelectTheLowOption, - removeLowFilterAndCloseRiskTableFilter, -} from '../../../../tasks/host_risk'; -import { createRule } from '../../../../tasks/api_calls/rules'; -import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule'; -import { getNewRule } from '../../../../objects/rule'; -import { clickOnFirstHostsAlerts, clickOnFirstUsersAlerts } from '../../../../tasks/risk_scores'; -import { OPTION_LIST_LABELS, OPTION_LIST_VALUES } from '../../../../screens/common/filter_group'; -import { kqlSearch } from '../../../../tasks/security_header'; -import { setEndDate } from '../../../../tasks/date_picker'; - -const TEST_USER_ALERTS = 1; -const TEST_USER_NAME = 'test'; -const SIEM_KIBANA_HOST_ALERTS = 1; -const SIEM_KIBANA_HOST_NAME = 'siem-kibana'; -const DATE_FORMAT = 'MMM D, YYYY @ HH:mm:ss.SSS'; -const DATE_BEFORE_ALERT_CREATION = moment().format(DATE_FORMAT); - -// Failing: See https://github.com/elastic/kibana/issues/192513 -// Failing: See https://github.com/elastic/kibana/issues/192512 -describe.skip('Entity Analytics Dashboard', { tags: ['@ess'] }, () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'auditbeat_multiple' }); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'auditbeat_multiple' }); - }); - - describe('legacy risk score', () => { - describe('Without data', () => { - beforeEach(() => { - login(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - it('shows enable host risk button', () => { - cy.get(ENABLE_HOST_RISK_SCORE_BUTTON).should('be.visible'); - }); - - it('shows enable user risk button', () => { - cy.get(ENABLE_USER_RISK_SCORE_BUTTON).should('be.visible'); - }); - }); - - describe('Risk Score enabled but still no data', () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts_no_data' }); - cy.task('esArchiverLoad', { archiveName: 'risk_users_no_data' }); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts_no_data' }); - cy.task('esArchiverUnload', { archiveName: 'risk_users_no_data' }); - }); - - it('shows no data detected prompt for host risk score module', () => { - cy.get(HOST_RISK_SCORE_NO_DATA_DETECTED).should('be.visible'); - }); - - it('shows no data detected prompt for user risk score module', () => { - cy.get(USER_RISK_SCORE_NO_DATA_DETECTED).should('be.visible'); - }); - }); - - describe('With Legacy data', () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts_legacy_data' }); - cy.task('esArchiverLoad', { archiveName: 'risk_users_legacy_data' }); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts_legacy_data' }); - cy.task('esArchiverUnload', { archiveName: 'risk_users_legacy_data' }); - }); - - it('shows enable host risk button', () => { - cy.get(ENABLE_HOST_RISK_SCORE_BUTTON).should('be.visible'); - }); - - it('shows enable user risk button', () => { - cy.get(ENABLE_USER_RISK_SCORE_BUTTON).should('be.visible'); - }); - }); - - describe('With host risk data', () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - }); - - it('renders donut chart', () => { - cy.get(HOSTS_DONUT_CHART).should('include.text', '6Total'); - }); - - it('renders table', () => { - cy.get(HOSTS_TABLE).should('be.visible'); - cy.get(HOSTS_TABLE_ROWS).should('have.length', 5); - }); - - it('renders alerts column', () => { - cy.get(HOSTS_TABLE_ALERT_CELL).should('have.length', 5); - }); - it('filters by risk level', () => { - cy.get(HOSTS_TABLE).should('be.visible'); - cy.get(HOSTS_TABLE_ROWS).should('have.length', 5); - - openRiskTableFilterAndSelectTheLowOption(); - - cy.get(HOSTS_DONUT_CHART).should('include.text', '1Total'); - cy.get(HOSTS_TABLE_ROWS).should('have.length', 1); - - removeLowFilterAndCloseRiskTableFilter(); - }); - - it('filters the host risk table with KQL search bar query', () => { - kqlSearch(`host.name : ${SIEM_KIBANA_HOST_NAME}{enter}`); - - cy.get(HOSTS_DONUT_CHART).should('include.text', '1Total'); - cy.get(HOSTS_TABLE_ROWS).should('have.length', 1); - }); - - describe('With alerts data', () => { - before(() => { - createRule(getNewRule()); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(ALERTS_URL); - waitForAlertsToPopulate(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - after(() => { - deleteAlertsAndRules(); - }); - - it('populates alerts column', () => { - cy.get(HOSTS_TABLE_ALERT_CELL).first().should('include.text', SIEM_KIBANA_HOST_ALERTS); - }); - - it('filters the alerts count with time range', () => { - setEndDate(DATE_BEFORE_ALERT_CREATION); - - updateDashboardTimeRange(); - - cy.get(HOSTS_TABLE_ALERT_CELL).first().should('include.text', 0); - }); - - it('opens alerts page when alerts count is clicked', () => { - clickOnFirstHostsAlerts(); - cy.url().should('include', ALERTS_URL); - - cy.get(OPTION_LIST_LABELS).eq(0).should('include.text', 'Status'); - cy.get(OPTION_LIST_VALUES(0)).should('include.text', 'open'); - cy.get(OPTION_LIST_LABELS).eq(1).should('include.text', 'Host'); - cy.get(OPTION_LIST_VALUES(1)).should('include.text', SIEM_KIBANA_HOST_NAME); - }); - }); - }); - - describe('With user risk data', () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_users' }); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_users' }); - }); - - it('renders donut chart', () => { - cy.get(USERS_DONUT_CHART).should('include.text', '7Total'); - }); - - it('renders table', () => { - cy.get(USERS_TABLE).should('be.visible'); - cy.get(USERS_TABLE_ROWS).should('have.length', 5); - }); - - it('renders alerts column', () => { - cy.get(USERS_TABLE_ALERT_CELL).should('have.length', 5); - }); - - it('filters by risk level', () => { - cy.get(USERS_TABLE).should('be.visible'); - cy.get(USERS_TABLE_ROWS).should('have.length', 5); - - openRiskTableFilterAndSelectTheLowOption(); - - cy.get(USERS_DONUT_CHART).should('include.text', '2Total'); - cy.get(USERS_TABLE_ROWS).should('have.length', 2); - - removeLowFilterAndCloseRiskTableFilter(); - }); - - it('filters the host risk table with KQL search bar query', () => { - kqlSearch(`user.name : ${TEST_USER_NAME}{enter}`); - - cy.get(USERS_DONUT_CHART).should('include.text', '1Total'); - cy.get(USERS_TABLE_ROWS).should('have.length', 1); - }); - - describe('With alerts data', () => { - before(() => { - createRule(getNewRule()); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(ALERTS_URL); - waitForAlertsToPopulate(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - after(() => { - deleteAlertsAndRules(); - }); - - it('populates alerts column', () => { - cy.get(USERS_TABLE_ALERT_CELL).first().should('include.text', TEST_USER_ALERTS); - }); - - it('filters the alerts count with time range', () => { - setEndDate(DATE_BEFORE_ALERT_CREATION); - updateDashboardTimeRange(); - - cy.get(USERS_TABLE_ALERT_CELL).first().should('include.text', 0); - }); - - it('opens alerts page when alerts count is clicked', () => { - clickOnFirstUsersAlerts(); - - cy.url().should('include', ALERTS_URL); - - cy.get(OPTION_LIST_LABELS).eq(0).should('include.text', 'Status'); - cy.get(OPTION_LIST_VALUES(0)).should('include.text', 'open'); - cy.get(OPTION_LIST_LABELS).eq(1).should('include.text', 'User'); - cy.get(OPTION_LIST_VALUES(1)).should('include.text', TEST_USER_NAME); - }); - }); - }); - }); -}); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/new_risk_score.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/risk_score.cy.ts similarity index 100% rename from x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/new_risk_score.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/risk_score.cy.ts diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts index 8a1be034a444f..fe10f84608167 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts @@ -46,45 +46,6 @@ describe.skip('Enrichment', { tags: ['@ess'] }, () => { }); describe('Custom query rule', () => { - // FLAKY: https://github.com/elastic/kibana/issues/176965 - describe.skip('from legacy risk scores', () => { - beforeEach(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - deleteAlertsAndRules(); - createRule(getNewRule({ rule_id: 'rule1' })); - login(); - visitWithTimeRange(ALERTS_URL); - waitForAlertsToPopulate(); - }); - - afterEach(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - cy.task('esArchiverUnload', { archiveName: 'risk_hosts_updated' }); - }); - - it('Should has enrichment fields from legacy risk', function () { - cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); - cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); - scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); - cy.get(HOST_RISK_COLUMN).contains('Low'); - scrollAlertTableColumnIntoView(USER_RISK_COLUMN); - cy.get(USER_RISK_COLUMN).contains('Low'); - scrollAlertTableColumnIntoView(ACTION_COLUMN); - expandFirstAlert(); - cy.get(ENRICHED_DATA_ROW).contains('Low'); - cy.get(ENRICHED_DATA_ROW).contains(CURRENT_HOST_RISK_LEVEL); - cy.get(ENRICHED_DATA_ROW).contains('Critical').should('not.exist'); - cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL).should('not.exist'); - - closeAlertFlyout(); - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - cy.task('esArchiverLoad', { archiveName: 'risk_hosts_updated' }); - expandFirstAlert(); - cy.get(ENRICHED_DATA_ROW).contains('Critical'); - cy.get(ENRICHED_DATA_ROW).contains(ORIGINAL_HOST_RISK_LEVEL); - }); - }); - describe('from new risk scores', () => { beforeEach(() => { cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); @@ -101,7 +62,7 @@ describe.skip('Enrichment', { tags: ['@ess'] }, () => { cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_updated' }); }); - it('Should has enrichment fields from legacy risk', function () { + it('Should has enrichment fields risk', function () { cy.get(HOST_RISK_HEADER_COLUMN).contains('Host Risk Level'); cy.get(USER_RISK_HEADER_COLUMN).contains('User Risk Level'); scrollAlertTableColumnIntoView(HOST_RISK_COLUMN); From bea1be4c531938ec10f4c0ec7c5ec5d279476e97 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 14:09:56 +0000 Subject: [PATCH 05/38] remove unused translations --- .../components/risk_score_enable_section.tsx | 12 +- .../public/entity_analytics/translations.ts | 133 +----------------- .../entity_analytics_management_page.cy.ts | 11 -- 3 files changed, 11 insertions(+), 145 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx index 6798dbe5b0501..d54cbc8721e1d 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx @@ -71,9 +71,9 @@ const RiskEngineHealth: React.FC<{ currentRiskEngineStatus?: RiskEngineStatus | return {'-'}; } if (currentRiskEngineStatus === RiskEngineStatusEnum.ENABLED) { - return {i18n.RISK_SCORE_MODULE_STATUS_ON}; + return {i18n.RISK_ENGINE_STATUS_ON}; } - return {i18n.RISK_SCORE_MODULE_STATUS_OFF}; + return {i18n.RISK_ENGINE_STATUS_OFF}; }; const RiskEngineStatusRow: React.FC<{ @@ -121,18 +121,18 @@ export const RiskScoreEnableSection: React.FC<{ const { data: riskEngineStatus, isFetching: isStatusLoading } = useRiskEngineStatus(); const initRiskEngineMutation = useInitRiskEngineMutation({ onSuccess: () => { - addSuccess(i18n.RISK_SCORE_MODULE_TURNED_ON, toastOptions); + addSuccess(i18n.RISK_ENGINE_TURNED_ON, toastOptions); }, }); const enableRiskEngineMutation = useEnableRiskEngineMutation({ onSuccess: () => { - addSuccess(i18n.RISK_SCORE_MODULE_TURNED_ON, toastOptions); + addSuccess(i18n.RISK_ENGINE_TURNED_ON, toastOptions); }, }); const disableRiskEngineMutation = useDisableRiskEngineMutation({ onSuccess: () => { - addSuccess(i18n.RISK_SCORE_MODULE_TURNED_OFF, toastOptions); + addSuccess(i18n.RISK_ENGINE_TURNED_OFF, toastOptions); }, }); @@ -170,7 +170,7 @@ export const RiskScoreEnableSection: React.FC<{ <> <> -

{i18n.RISK_SCORE_MODULE_STATUS}

+

{i18n.RISK_ENGINE_STATUS}

{initRiskEngineMutation.isError && } {disableRiskEngineMutation.isError && ( diff --git a/x-pack/plugins/security_solution/public/entity_analytics/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/translations.ts index 2e06ec9ad1eb9..17a89319c0717 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/translations.ts @@ -35,21 +35,21 @@ export const HIDE_USERS_RISK_SCORE = i18n.translate( } ); -export const RISK_SCORE_MODULE_STATUS = i18n.translate( +export const RISK_ENGINE_STATUS = i18n.translate( 'xpack.securitySolution.riskScore.riskScorePreview.status', { defaultMessage: 'Status', } ); -export const RISK_SCORE_MODULE_STATUS_ON = i18n.translate( +export const RISK_ENGINE_STATUS_ON = i18n.translate( 'xpack.securitySolution.riskScore.riskScorePreview.statusOn', { defaultMessage: 'On', } ); -export const RISK_SCORE_MODULE_STATUS_OFF = i18n.translate( +export const RISK_ENGINE_STATUS_OFF = i18n.translate( 'xpack.securitySolution.riskScore.riskScorePreview.statusOff', { defaultMessage: 'Off', @@ -77,20 +77,6 @@ export const EA_DASHBOARD_LINK = i18n.translate( } ); -export const EA_DOCS_RISK_HOSTS = i18n.translate( - 'xpack.securitySolution.riskScore.riskScorePreview.eaDocsHosts', - { - defaultMessage: 'Host risk score', - } -); - -export const EA_DOCS_RISK_USERS = i18n.translate( - 'xpack.securitySolution.riskScore.riskScorePreview.eaDocsUsers', - { - defaultMessage: 'User risk score', - } -); - export const EA_DOCS_ENTITY_RISK_SCORE = i18n.translate( 'xpack.securitySolution.riskScore.riskScorePreview.eaDocsEntities', { @@ -145,71 +131,6 @@ export const PREVIEW_QUERY_ERROR_TITLE = i18n.translate( } ); -export const UPDATE_AVAILABLE = i18n.translate('xpack.securitySolution.riskScore.updateAvailable', { - defaultMessage: 'Update available', -}); - -export const START_UPDATE = i18n.translate('xpack.securitySolution.riskScore.startUpdate', { - defaultMessage: 'Start update', -}); - -export const UPDATING_RISK_ENGINE = i18n.translate( - 'xpack.securitySolution.riskScore.updatingRiskEngine', - { - defaultMessage: 'Updating risk engine...', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_TITLE = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModa.title', - { - defaultMessage: 'Do you want to update the entity risk engine?', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_EXISTING_USER_HOST_1 = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_1', - { - defaultMessage: 'Existing user and host risk score transforms will be deleted', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_EXISTING_USER_HOST_2 = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_2', - { - defaultMessage: ', as they are no longer required.', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_EXISTING_DATA_1 = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_1', - { - defaultMessage: 'Legacy risk score data will not be deleted', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_EXISTING_DATA_2 = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_2', - { - defaultMessage: - ', it will still exist in the index but will no longer be available in the user interface. You will need to remove legacy risk score data manually.', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_BUTTON_NO = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModal.buttonNo', - { - defaultMessage: 'No, not yet', - } -); - -export const UPDATE_RISK_ENGINE_MODAL_BUTTON_YES = i18n.translate( - 'xpack.securitySolution.riskScore.updateRiskEngineModal.buttonYes', - { - defaultMessage: 'Yes, update now!', - } -); - export const ERROR_PANEL_TITLE = i18n.translate( 'xpack.securitySolution.riskScore.errorPanel.title', { @@ -231,50 +152,6 @@ export const ERROR_PANEL_ERRORS = i18n.translate( } ); -export const UPDATE_PANEL_TITLE = i18n.translate( - 'xpack.securitySolution.riskScore.updatePanel.title', - { - defaultMessage: 'New entity risk scoring engine available', - } -); - -export const UPDATE_PANEL_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.updatePanel.message', - { - defaultMessage: - 'A new entity risk scoring engine is available. Update now to get the latest features.', - } -); - -export const UPDATE_PANEL_GO_TO_MANAGE = i18n.translate( - 'xpack.securitySolution.riskScore.updatePanel.goToManage', - { - defaultMessage: 'Manage', - } -); - -export const UPDATE_PANEL_GO_TO_DISMISS = i18n.translate( - 'xpack.securitySolution.riskScore.updatePanel.Dismiss', - { - defaultMessage: 'Dismiss', - } -); - -export const getMaxSpaceTitle = (maxSpaces: number) => - i18n.translate('xpack.securitySolution.riskScore.maxSpacePanel.title', { - defaultMessage: - 'You cannot enable entity risk scoring in more than {maxSpaces, plural, =1 {# Kibana space} other {# Kibana spaces}}.', - values: { maxSpaces }, - }); - -export const MAX_SPACE_PANEL_MESSAGE = i18n.translate( - 'xpack.securitySolution.riskScore.maxSpacePanel.message', - { - defaultMessage: - 'You can disable entity risk scoring in the space it is currently enabled before enabling it in this space', - } -); - export const CHECK_PRIVILEGES = i18n.translate( 'xpack.securitySolution.riskScore.errors.privileges.check', { @@ -289,14 +166,14 @@ export const NEED_TO_HAVE = i18n.translate( } ); -export const RISK_SCORE_MODULE_TURNED_ON = i18n.translate( +export const RISK_ENGINE_TURNED_ON = i18n.translate( 'xpack.securitySolution.riskScore.moduleTurnedOn', { defaultMessage: 'Entity risk score has been turned on', } ); -export const RISK_SCORE_MODULE_TURNED_OFF = i18n.translate( +export const RISK_ENGINE_TURNED_OFF = i18n.translate( 'xpack.securitySolution.riskScore.moduleTurnedOff', { defaultMessage: 'Entity risk score has been turned off', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts index b8d222471c87e..76f5dadd43de0 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts @@ -133,17 +133,6 @@ describe( cy.get(RISK_SCORE_ERROR_PANEL).contains('There was an error'); }); - - it('should update if there legacy risk score installed', () => { - installRiskScoreModule(); - visit(ENTITY_ANALYTICS_MANAGEMENT_URL); - - cy.get(RISK_SCORE_STATUS).should('not.exist'); - - upgradeRiskEngine(); - - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId: 'default' }); - }); }); } ); From 78f956a8349020ec902a929104d1b3a1e5e22535 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 14:18:10 +0000 Subject: [PATCH 06/38] tidy up unused test data --- .../entity_analytics_management_page.cy.ts | 3 - .../host_details/risk_tab.cy.ts | 36 +--- .../hosts/host_risk_tab.cy.ts | 49 +----- .../hosts/hosts_risk_column.cy.ts | 25 +-- .../screens/entity_analytics_management.ts | 6 - .../cypress/tasks/entity_analytics.ts | 35 +--- .../risk_hosts_legacy_data/data.json | 53 ------ .../risk_hosts_legacy_data/mappings.json | 155 ------------------ .../risk_users_legacy_data/data.json | 49 ------ .../risk_users_legacy_data/mappings.json | 136 --------------- 10 files changed, 4 insertions(+), 543 deletions(-) delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/mappings.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/mappings.json diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts index 76f5dadd43de0..08778dc1342fb 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts @@ -17,9 +17,6 @@ import { RISK_SCORE_STATUS, LOCAL_QUERY_BAR_SEARCH_INPUT_SELECTOR, } from '../../screens/entity_analytics_management'; - -import { deleteRiskScore, installRiskScoreModule } from '../../tasks/api_calls/risk_scores'; -import { RiskScoreEntity } from '../../tasks/risk_scores/common'; import { login } from '../../tasks/login'; import { visit } from '../../tasks/navigation'; import { ENTITY_ANALYTICS_MANAGEMENT_URL } from '../../urls/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts index 746f28cba4462..6a4ce7f7253dd 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts @@ -7,8 +7,6 @@ import { login } from '../../../tasks/login'; import { visitHostDetailsPage } from '../../../tasks/navigation'; - -import { TABLE_CELL, TABLE_ROWS } from '../../../screens/alerts_details'; import { deleteRiskEngineConfiguration } from '../../../tasks/api_calls/risk_engine'; import { openRiskInformationFlyout, mockRiskEngineEnabled } from '../../../tasks/entity_analytics'; import { ALERTS_COUNT, ALERT_GRID_CELL } from '../../../screens/alerts'; @@ -17,39 +15,7 @@ import { navigateToHostRiskDetailTab } from '../../../tasks/host_risk'; import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; describe('risk tab', { tags: ['@ess'] }, () => { - describe('with legacy risk score', () => { - beforeEach(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - login(); - deleteRiskEngineConfiguration(); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - }); - - it('renders risk tab', () => { - visitHostDetailsPage('siem-kibana'); - navigateToHostRiskDetailTab(); - - cy.get('[data-test-subj="topRiskScoreContributors"]') - .find(TABLE_ROWS) - .within(() => { - cy.get(TABLE_CELL).contains('Unusual Linux Username'); - }); - }); - - it('shows risk information overlay when button is clicked', () => { - visitHostDetailsPage('siem-kibana'); - navigateToHostRiskDetailTab(); - - openRiskInformationFlyout(); - - cy.get(RISK_INFORMATION_FLYOUT_HEADER).contains('Entity Risk Analytics'); - }); - }); - - describe('with new risk score', { tags: ['@serverless'] }, () => { + describe('with risk score', { tags: ['@serverless'] }, () => { before(() => { cy.task('esArchiverLoad', { archiveName: 'risk_scores_new_complete_data' }); cy.task('esArchiverLoad', { archiveName: 'query_alert', useCreate: true, docsOnly: true }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts index 3123bd30cb450..18358f6145e41 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts @@ -23,54 +23,7 @@ import { kqlSearch } from '../../../tasks/security_header'; import { mockRiskEngineEnabled } from '../../../tasks/entity_analytics'; describe('risk tab', { tags: ['@ess'] }, () => { - describe('with legacy risk score', () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - }); - - beforeEach(() => { - login(); - visitWithTimeRange(hostsUrl('allHosts')); - // by some reason after navigate to host risk, page is sometimes is reload or go to all host tab - // this fix wait until we fave host in all host table, and then we go to risk tab - cy.contains('siem-kibana'); - - navigateToHostRiskDetailTab(); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - }); - - it('renders the table', () => { - kqlSearch('host.name: "siem-kibana" {enter}'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(4).should('have.text', 'siem-kibana'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(5).should('have.text', 'Mar 10, 2021 @ 14:51:05.766'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(6).should('have.text', '21.00'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(7).should('have.text', 'Low'); - }); - - it('filters the table', () => { - openRiskTableFilterAndSelectTheCriticalOption(); - - cy.get(HOST_BY_RISK_TABLE_CELL).eq(3).should('not.have.text', 'siem-kibana'); - - removeCriticalFilterAndCloseRiskTableFilter(); - }); - - it('should be able to change items count per page', () => { - selectFiveItemsPerPageOption(); - - cy.get(HOST_BY_RISK_TABLE_HOSTNAME_CELL).should('have.length', 5); - }); - - it('should not allow page change when page is empty', () => { - kqlSearch('host.name: "nonexistent_host" {enter}'); - cy.get(HOST_BY_RISK_TABLE_NEXT_PAGE_BUTTON).should(`not.exist`); - }); - }); - - describe('with new risk score', { tags: ['@serverless'] }, () => { + describe('with risk score', { tags: ['@serverless'] }, () => { before(() => { cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts index 179dbb0277a11..d8a9bdc18b7bf 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts @@ -7,36 +7,13 @@ import { login } from '../../../tasks/login'; import { visitWithTimeRange } from '../../../tasks/navigation'; - import { hostsUrl } from '../../../urls/navigation'; import { TABLE_CELL } from '../../../screens/alerts_details'; import { kqlSearch } from '../../../tasks/security_header'; import { mockRiskEngineEnabled } from '../../../tasks/entity_analytics'; describe('All hosts table', { tags: ['@ess'] }, () => { - describe('with legacy risk score', () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - }); - - beforeEach(() => { - login(); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - }); - - it('it renders risk column', () => { - visitWithTimeRange(hostsUrl('allHosts')); - kqlSearch('host.name: "siem-kibana" {enter}'); - - cy.get('[data-test-subj="tableHeaderCell_node.risk_4"]').should('exist'); - cy.get(TABLE_CELL).eq(4).should('have.text', 'Low'); - }); - }); - - describe('with new risk score', { tags: ['@serverless'] }, () => { + describe('with risk score', { tags: ['@serverless'] }, () => { before(() => { cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics_management.ts b/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics_management.ts index e1d62ffb420c8..918a4ec656cda 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics_management.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics_management.ts @@ -28,12 +28,6 @@ export const LOCAL_QUERY_BAR_SEARCH_INPUT_SELECTOR = export const RISK_SCORE_ERROR_PANEL = '[data-test-subj="risk-score-error-panel"]'; -export const RISK_SCORE_UPDATE_CANCEL = '[data-test-subj="risk-score-update-cancel"]'; - -export const RISK_SCORE_UPDATE_CONFIRM = '[data-test-subj="risk-score-update-confirm"]'; - -export const RISK_SCORE_UPDATE_BUTTON = '[data-test-subj="risk-score-update-button"]'; - export const RISK_SCORE_STATUS = '[data-test-subj="risk-score-status"]'; export const RISK_SCORE_STATUS_LOADING = '[data-test-subj="risk-score-status-loading"]'; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts b/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts index c654781c23be3..8f9b9ed6ca5c8 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts @@ -13,11 +13,8 @@ import { ANOMALIES_TABLE_NEXT_PAGE_BUTTON, OPEN_RISK_INFORMATION_FLYOUT_BUTTON, } from '../screens/entity_analytics'; -import { RISK_SCORE_STATUS } from '../screens/entity_analytics_management'; -import { ENTITY_ANALYTICS_URL, ENTITY_ANALYTICS_MANAGEMENT_URL } from '../urls/navigation'; +import { ENTITY_ANALYTICS_URL } from '../urls/navigation'; import { - RISK_SCORE_UPDATE_CONFIRM, - RISK_SCORE_UPDATE_BUTTON, RISK_SCORE_SWITCH, RISK_PREVIEW_ERROR_BUTTON, } from '../screens/entity_analytics_management'; @@ -66,38 +63,8 @@ export const mockRiskEngineEnabled = () => { }).as('riskEngineStatus'); }; -/** - * @deprecated - * At the moment there isn't a way to clean all assets created by the risk engine enablement. - * We can't clean assets after each tests and we can't call this function from the `after` hook (cypress good practice). - * Reintroduce this task when we can safely delete the risk engine data. - * - * Please use `mockRiskEngineEnabled` instead. - */ -// const enableRiskEngine = () => { -// cy.visit(ENTITY_ANALYTICS_MANAGEMENT_URL); -// cy.get(RISK_SCORE_STATUS).should('have.text', 'Off'); -// riskEngineStatusChange(); -// cy.get(RISK_SCORE_STATUS).should('have.text', 'On'); -// }; - -export const updateRiskEngine = () => { - cy.get(RISK_SCORE_UPDATE_BUTTON).click(); -}; - -export const updateRiskEngineConfirm = () => { - cy.get(RISK_SCORE_UPDATE_CONFIRM).click(); -}; - export const previewErrorButtonClick = () => { cy.get(RISK_PREVIEW_ERROR_BUTTON).click(); }; export const openRiskInformationFlyout = () => cy.get(OPEN_RISK_INFORMATION_FLYOUT_BUTTON).click(); - -export const upgradeRiskEngine = () => { - visitWithTimeRange(ENTITY_ANALYTICS_MANAGEMENT_URL); - updateRiskEngine(); - updateRiskEngineConfirm(); - cy.get(RISK_SCORE_STATUS).should('have.text', 'On'); -}; diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/data.json deleted file mode 100644 index 6bed81a735a02..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/data.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "Qcf-2Pmk_H0kal4VVU_6tooAAAAAAAAA", - "index": "ml_host_risk_score_latest_default", - "source": { - "risk_stats": { - "rule_risks": [ - { - "rule_id": "3301ee30-36d2-11ed-bc8e-edf6538225c3", - "rule_name": "test", - "rule_risk": 21 - } - ], - "risk_score": 17.084609494640123, - "risk_multipliers": [] - }, - "@timestamp": "2022-09-18T17:50:42.961Z", - "host": { - "name": "MacBook-Pro.local" - }, - "ingest_timestamp": "2022-09-18T17:54:22.363192Z", - "risk": "Unknown" - } - } -} - -{ - "type": "doc", - "value": { - "id": "LtYjLhe5xxdQ+/tZ0LQ2YqhYE7BMKO9jJAT9dOALoKY=", - "index": "ml_host_risk_score_default", - "source": { - "host": { - "name": "MacBook-Pro.local" - }, - "risk_stats": { - "rule_risks": [ - { - "rule_id": "3301ee30-36d2-11ed-bc8e-edf6538225c3", - "rule_name": "test", - "rule_risk": 21 - } - ], - "risk_score": 17.084609494640123, - "risk_multipliers": [] - }, - "ingest_timestamp": "2022-09-18T17:54:22.363192Z", - "risk": "Unknown", - "@timestamp": "2022-09-18T17:50:42.961Z" - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/mappings.json deleted file mode 100644 index 94e1a3b52ffd6..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_legacy_data/mappings.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - } - } - }, - "ingest_timestamp": { - "type": "date" - }, - "risk": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "risk_stats": { - "properties": { - "risk_score": { - "type": "float" - }, - "rule_risks": { - "properties": { - "rule_id": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "rule_name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "rule_risk": { - "type": "float" - } - } - } - } - } - } - }, - "settings": { - "index": { - "routing": { - "allocation": { - "include": { - "_tier_preference": "data_content" - } - } - }, - "number_of_shards": "1", - "number_of_replicas": "1" - } - } - } -} - -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - } - } - }, - "ingest_timestamp": { - "type": "date" - }, - "risk": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "risk_stats": { - "properties": { - "risk_score": { - "type": "float" - }, - "rule_risks": { - "properties": { - "rule_id": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "rule_name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "rule_risk": { - "type": "float" - } - } - } - } - } - } - }, - "settings": { - "index": { - "routing": { - "allocation": { - "include": { - "_tier_preference": "data_content" - } - } - }, - "number_of_shards": "1", - "number_of_replicas": "1" - } - } - } -} - - diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/data.json deleted file mode 100644 index e8f43bb3bf277..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/data.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "Yb5XrKVhLNCdGL2ef-A3jloAAAAAAAAA", - "index": "ml_user_risk_score_latest_default", - "source": { - "risk_stats": { - "rule_risks": [ - { - "rule_name": "test", - "rule_risk": 21 - } - ], - "risk_score": 17.084609494640123 - }, - "@timestamp": "2022-09-18T18:28:30.943Z", - "ingest_timestamp": "2022-09-18T18:31:32.969840Z", - "risk": "Unknown", - "user": { - "name": "johnsmith" - } - } - } -} - -{ - "type": "doc", - "value": { - "id": "LrLLssaZUZHhh2cKbkwqIEpguUegcpuG9V+qzVlm8N0=", - "index": "ml_user_risk_score_default", - "source": { - "risk_stats": { - "rule_risks": [ - { - "rule_name": "test", - "rule_risk": 21 - } - ], - "risk_score": 17.084609494640123 - }, - "ingest_timestamp": "2022-09-18T18:31:32.969840Z", - "risk": "Unknown", - "@timestamp": "2022-09-18T18:28:30.943Z", - "user": { - "name": "johnsmith" - } - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/mappings.json deleted file mode 100644 index eb8b3e844a557..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_users_legacy_data/mappings.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_user_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "ingest_timestamp": { - "type": "date" - }, - "risk": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "risk_stats": { - "properties": { - "risk_score": { - "type": "float" - }, - "rule_risks": { - "properties": { - "rule_name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "rule_risk": { - "type": "float" - } - } - } - } - }, - "user": { - "properties": { - "name": { - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "routing": { - "allocation": { - "include": { - "_tier_preference": "data_content" - } - } - }, - "number_of_shards": "1", - "number_of_replicas": "1" - } - } - } -} - -{ - "type": "index", - "value": { - "index": "ml_user_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "ingest_timestamp": { - "type": "date" - }, - "risk": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword" - } - } - }, - "risk_stats": { - "properties": { - "risk_score": { - "type": "float" - }, - "rule_risks": { - "properties": { - "rule_name": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - }, - "rule_risk": { - "type": "float" - } - } - } - } - }, - "user": { - "properties": { - "name": { - "type": "keyword" - } - } - } - } - }, - "settings": { - "index": { - "routing": { - "allocation": { - "include": { - "_tier_preference": "data_content" - } - } - }, - "number_of_shards": "1", - "number_of_replicas": "1" - } - } - } -} - From 8b9ab1dcc9c39bd13b71a0beee5877059b2c158a Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 14:20:19 +0000 Subject: [PATCH 07/38] found some more tests --- .../dashboards/upgrade_risk_score.cy.ts | 114 ------------------ .../entity_analytics_management_page.cy.ts | 6 +- 2 files changed, 1 insertion(+), 119 deletions(-) delete mode 100644 x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/upgrade_risk_score.cy.ts diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/upgrade_risk_score.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/upgrade_risk_score.cy.ts deleted file mode 100644 index ef114aec912a6..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/upgrade_risk_score.cy.ts +++ /dev/null @@ -1,114 +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 { - UPGRADE_RISK_SCORE_BUTTON, - USERS_TABLE, - HOSTS_TABLE_ROWS, - HOSTS_TABLE, - USERS_TABLE_ROWS, - HOST_RISK_SCORE_NO_DATA_DETECTED, - USER_RISK_SCORE_NO_DATA_DETECTED, -} from '../../../screens/entity_analytics'; -import { PAGE_TITLE } from '../../../screens/entity_analytics_management'; -import { - deleteRiskScore, - installLegacyRiskScoreModule, - installRiskScoreModule, -} from '../../../tasks/api_calls/risk_scores'; -import { clickUpgradeRiskScore } from '../../../tasks/risk_scores'; - -import { login } from '../../../tasks/login'; -import { visitWithTimeRange } from '../../../tasks/navigation'; - -import { RiskScoreEntity } from '../../../tasks/risk_scores/common'; - -import { ENTITY_ANALYTICS_URL } from '../../../urls/navigation'; -import { upgradeRiskEngine } from '../../../tasks/entity_analytics'; -import { deleteRiskEngineConfiguration } from '../../../tasks/api_calls/risk_engine'; -import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; - -const spaceId = 'default'; - -describe( - 'Upgrade risk scores', - { - tags: ['@ess'], - env: { - ftrConfig: { - kbnServerArgs: [ - `--xpack.securitySolution.enableExperimental=${JSON.stringify(['entityStoreDisabled'])}`, - ], - }, - }, - }, - () => { - beforeEach(() => { - login(); - deleteRiskEngineConfiguration(); - deleteAlertsAndRules(); - }); - - describe('show upgrade risk button', () => { - beforeEach(() => { - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId }); - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId }); - installLegacyRiskScoreModule(RiskScoreEntity.host, spaceId); - installLegacyRiskScoreModule(RiskScoreEntity.user, spaceId); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - afterEach(() => { - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId }); - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId }); - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - cy.task('esArchiverUnload', { archiveName: 'risk_users' }); - }); - - it('shows upgrade panel', () => { - cy.get(UPGRADE_RISK_SCORE_BUTTON).should('be.visible'); - - clickUpgradeRiskScore(); - - cy.get(PAGE_TITLE).should('have.text', 'Entity Risk Score'); - }); - }); - - describe('upgrade risk engine', () => { - beforeEach(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_hosts' }); - cy.task('esArchiverLoad', { archiveName: 'risk_users' }); - login(); - installRiskScoreModule(); - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); - - afterEach(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_hosts' }); - cy.task('esArchiverUnload', { archiveName: 'risk_users' }); - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.host, spaceId }); - deleteRiskScore({ riskScoreEntity: RiskScoreEntity.user, spaceId }); - deleteRiskEngineConfiguration(); - }); - - it('show old risk score data before upgrade, and hide after', () => { - cy.get(HOSTS_TABLE).should('be.visible'); - cy.get(HOSTS_TABLE_ROWS).should('have.length', 5); - - cy.get(USERS_TABLE).should('be.visible'); - cy.get(USERS_TABLE_ROWS).should('have.length', 5); - - upgradeRiskEngine(); - - visitWithTimeRange(ENTITY_ANALYTICS_URL); - - cy.get(HOST_RISK_SCORE_NO_DATA_DETECTED).should('be.visible'); - cy.get(USER_RISK_SCORE_NO_DATA_DETECTED).should('be.visible'); - }); - }); - } -); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts index 08778dc1342fb..2a6bad3c86c0b 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/entity_analytics_management_page.cy.ts @@ -30,11 +30,7 @@ import { } from '../../tasks/api_calls/risk_engine'; import { updateDateRangeInLocalDatePickers } from '../../tasks/date_picker'; import { submitLocalSearch } from '../../tasks/search_bar'; -import { - riskEngineStatusChange, - upgradeRiskEngine, - previewErrorButtonClick, -} from '../../tasks/entity_analytics'; +import { riskEngineStatusChange, previewErrorButtonClick } from '../../tasks/entity_analytics'; describe( 'Entity analytics management page', From 46122530e78a25018534188776af667ca2d99f3d Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 14:23:32 +0000 Subject: [PATCH 08/38] translations --- .../translations/translations/fr-FR.json | 63 ++----------------- .../translations/translations/ja-JP.json | 63 ++----------------- .../translations/translations/zh-CN.json | 63 ++----------------- 3 files changed, 15 insertions(+), 174 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 06506ff9d1c93..94e3e466cac43 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -11696,8 +11696,8 @@ "xpack.apm.serviceIcons.service": "Service", "xpack.apm.serviceIcons.serviceDetails.cloud.architecture": "Architecture", "xpack.apm.serviceIcons.serviceDetails.cloud.availabilityZoneLabel": "{zones, plural, =0 {Zone de disponibilité} one {Zone de disponibilité} other {Zones de disponibilité}}", - "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, =0 {Nom de fonction} one {Nom de fonction} other {Noms de fonction}}", "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, =0 {Type de déclencheur} one {Type de déclencheur} other {Types de déclencheurs}}", + "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, =0 {Nom de fonction} one {Nom de fonction} other {Noms de fonction}}", "xpack.apm.serviceIcons.serviceDetails.cloud.machineTypesLabel": "{machineTypes, plural, =0{Type de machine} one {Type de machine} other {Types de machines}}", "xpack.apm.serviceIcons.serviceDetails.cloud.projectIdLabel": "ID de projet", "xpack.apm.serviceIcons.serviceDetails.cloud.providerLabel": "Fournisseur cloud", @@ -28260,8 +28260,8 @@ "xpack.maps.source.esSearch.descendingLabel": "décroissant", "xpack.maps.source.esSearch.extentFilterLabel": "Filtre dynamique pour les données de la zone de carte visible", "xpack.maps.source.esSearch.fieldNotFoundMsg": "Impossible de trouver \"{fieldName}\" dans le modèle d'indexation \"{indexPatternName}\".", - "xpack.maps.source.esSearch.geoFieldLabel": "Champ géospatial", "xpack.maps.source.esSearch.geofieldLabel": "Champ géospatial", + "xpack.maps.source.esSearch.geoFieldLabel": "Champ géospatial", "xpack.maps.source.esSearch.geoFieldTypeLabel": "Type de champ géospatial", "xpack.maps.source.esSearch.indexOverOneLengthEditError": "Votre vue de données pointe vers plusieurs index. Un seul index est autorisé par vue de données.", "xpack.maps.source.esSearch.indexZeroLengthEditError": "Votre vue de données ne pointe vers aucun index.", @@ -37006,7 +37006,6 @@ "xpack.securitySolution.alertCountByRuleByStatus.ruleName": "kibana.alert.rule.name", "xpack.securitySolution.alertCountByRuleByStatus.status": "Statut", "xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle": "Nom de règle", - "xpack.securitySolution.alertDetails.overview.hostRiskDataTitle": "Données de risque de {riskEntity}", "xpack.securitySolution.alertDetails.summary.readLess": "Lire moins", "xpack.securitySolution.alertDetails.summary.readMore": "En savoir plus", "xpack.securitySolution.alerts.badge.readOnly.tooltip": "Impossible de mettre à jour les alertes", @@ -38013,8 +38012,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "Kibana ne permet qu'un maximum de {maxNumber} {maxNumber, plural, =1 {alerte} other {alertes}} par exécution de règle.", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "Nom obligatoire.", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "Ajouter un guide d'investigation sur les règles...", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "Fournissez des instructions sur les conditions préalables à la règle, telles que les intégrations requises, les étapes de configuration et tout ce qui est nécessaire au bon fonctionnement de la règle.", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "Ajouter le guide de configuration de règle...", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "Fournissez des instructions sur les conditions préalables à la règle, telles que les intégrations requises, les étapes de configuration et tout ce qui est nécessaire au bon fonctionnement de la règle.", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "Guide de configuration", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "Une balise ne doit pas être vide", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.threatIndicatorPathFieldEmptyError": "Le remplacement du préfixe d'indicateur ne peut pas être vide.", @@ -39521,7 +39520,6 @@ "xpack.securitySolution.enableRiskScore.enableRiskScore": "Activer le score de risque de {riskEntity}", "xpack.securitySolution.enableRiskScore.enableRiskScoreDescription": "Une fois que vous avez activé cette fonctionnalité, vous pouvez obtenir un accès rapide aux scores de risque de {riskEntity} dans cette section. Les données pourront prendre jusqu'à une heure pour être générées après l'activation du module.", "xpack.securitySolution.enableRiskScore.enableRiskScorePopoverTitle": "Les alertes doivent être disponibles avant d'activer le module", - "xpack.securitySolution.enableRiskScore.upgradeRiskScore": "Mettre à niveau le score de risque de {riskEntity}", "xpack.securitySolution.endpoint.action.chooseFromTheList": "Choisissez une action dans la liste", "xpack.securitySolution.endpoint.action.permissionDenied": "Autorisation refusée", "xpack.securitySolution.endpoint.actions.agentDetails": "Afficher les détails de l'agent", @@ -41244,9 +41242,6 @@ "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "Impossible d'interroger les données d'authentifications", "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "Impossible d'interroger les données d'événements", "xpack.securitySolution.hosts.pageTitle": "Hôtes", - "xpack.securitySolution.hosts.topRiskScoreContributors.rankColumnTitle": "Rang", - "xpack.securitySolution.hosts.topRiskScoreContributors.ruleNameColumnTitle": "Nom de règle", - "xpack.securitySolution.hosts.topRiskScoreContributors.title": "Principaux contributeurs de score de risque", "xpack.securitySolution.hosts.topRiskScoreContributorsTable.title": "Principaux contributeurs de score de risque", "xpack.securitySolution.hostsRiskTable.filteredHostsTitle": "Afficher les hôtes à risque {severity}", "xpack.securitySolution.hostsRiskTable.hostNameTitle": "Nom d'hôte", @@ -42133,8 +42128,6 @@ "xpack.securitySolution.responseActionsList.list.status": "Statut", "xpack.securitySolution.responseActionsList.list.time": "Heure", "xpack.securitySolution.responseActionsList.list.user": "Utilisateur", - "xpack.securitySolution.risk_score.toast.viewDashboard": "Afficher le tableau de bord", - "xpack.securitySolution.riskDeprecated.entity.upgradeRiskScoreDescription": "Les données actuelles ne sont plus prises en charge. Veuillez migrer vos données et mettre à niveau le module. Les données pourront prendre jusqu'à une heure pour être générées après l'activation du module.", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.clusterPrivilegesTitle": "Privilèges de cluster Elasticsearch manquants :", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.essenceDescription": "Vous avez besoin des privilèges suivants pour accéder totalement à cette fonctionnalité. Contactez votre administrateur si vous avez besoin d'aide. En savoir plus sur {docs}.", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.indexPrivilegesTitle": "Privilèges d'index Elasticsearch manquants :", @@ -42165,16 +42158,6 @@ "xpack.securitySolution.riskInformation.title": "Analyse de risque des entités", "xpack.securitySolution.riskInformation.unknownRiskDescription": "Inférieur à 20", "xpack.securitySolution.riskInformation.weightColumnHeader": "Pondération des risques par défaut", - "xpack.securitySolution.riskScore.api.ingestPipeline.create.errorMessageTitle": "Impossible de créer un pipeline d'ingestion", - "xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle": "Impossible de supprimer {totalCount, plural, =1 {le pipeline} other {les pipelines}} d'ingestion", - "xpack.securitySolution.riskScore.api.storedScript.create.errorMessageTitle": "Impossible de créer un script stocké", - "xpack.securitySolution.riskScore.api.storedScript.delete.errorMessageTitle": "Impossible de supprimer un script stocké", - "xpack.securitySolution.riskScore.api.transforms.create.errorMessageTitle": "Impossible de créer la transformation", - "xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle": "Impossible de supprimer {totalCount, plural, =1 {la transformation} other {les transformations}}", - "xpack.securitySolution.riskScore.api.transforms.getState.errorMessageTitle": "Impossible d'obtenir l'état de transformation", - "xpack.securitySolution.riskScore.api.transforms.getState.notFoundMessageTitle": "Transformation introuvable", - "xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle": "Impossible de démarrer {totalCount, plural, =1 {la transformation} other {les transformations}}", - "xpack.securitySolution.riskScore.api.transforms.stop.errorMessageTitle": "Impossible d'arrêter {totalCount, plural, =1 {la transformation} other {les transformations}}", "xpack.securitySolution.riskScore.enableButtonTitle": "Activer", "xpack.securitySolution.riskScore.errorPanel.errors": "Erreurs", "xpack.securitySolution.riskScore.errorPanel.message": "Le statut du moteur à risque n'a pas pu être changé. Résoudre les problèmes suivants et réessayer :", @@ -42182,13 +42165,9 @@ "xpack.securitySolution.riskScore.errors.privileges.check": "Vérifier les privilèges", "xpack.securitySolution.riskScore.errors.privileges.needToHave": "Vous devez avoir :", "xpack.securitySolution.riskScore.failSearchDescription": "Impossible de lancer une recherche sur le score de risque", - "xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle": "Scores de risque de l'hôte activés", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody": "Nous n’avons pas trouvé de données de score de risque de l’hôte. Vérifiez si vous avez des filtres globaux dans la barre de recherche KQL globale. Si vous venez d’activer le module de risque de l’hôte, le moteur de risque peut mettre une heure à générer les données de score de risque de l’hôte et les afficher dans ce panneau.", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelTitle": "Aucune donnée de score de risque de l'hôte disponible pour l'affichage", - "xpack.securitySolution.riskScore.install.errorMessageTitle": "Erreur d'installation", "xpack.securitySolution.riskScore.kpi.failSearchDescription": "Impossible de lancer une recherche sur le score de risque", - "xpack.securitySolution.riskScore.maxSpacePanel.message": "Vous pouvez désactiver l'évaluation de l'entité dans l'espace où elle est actuellement activée avant de l'activer dans cet espace", - "xpack.securitySolution.riskScore.maxSpacePanel.title": "Vous ne pouvez pas autoriser le score de risque dans plus de {maxSpaces, plural, =1 {# espace Kibana} other {# espaces Kibana}}.", "xpack.securitySolution.riskScore.moduleTurnedOff": "Le score de risque des entités a été désactivé", "xpack.securitySolution.riskScore.moduleTurnedOn": "Le score de risque des entités a été activé", "xpack.securitySolution.riskScore.overview.alerts": "Alertes", @@ -42203,11 +42182,8 @@ "xpack.securitySolution.riskScore.previewTable.levelColumnTitle": "Niveau", "xpack.securitySolution.riskScore.previewTable.nameColumnTitle": "Nom", "xpack.securitySolution.riskScore.previewTable.scoreNormColumnTitle": "Norme de score", - "xpack.securitySolution.riskScore.restartButtonTitle": "Redémarrer", "xpack.securitySolution.riskScore.riskScorePreview.eaDocsDashboard": "Tableau de bord d'analyse des entités", "xpack.securitySolution.riskScore.riskScorePreview.eaDocsEntities": "Comment le score de risque est-il calculé ?", - "xpack.securitySolution.riskScore.riskScorePreview.eaDocsHosts": "Score de risque de l'hôte", - "xpack.securitySolution.riskScore.riskScorePreview.eaDocsUsers": "Score de risque de l'utilisateur", "xpack.securitySolution.riskScore.riskScorePreview.entityRiskScoring": "Score de risque des entités", "xpack.securitySolution.riskScore.riskScorePreview.errorMessage": "Un problème est survenu lors de la création de l'aperçu. Veuillez réessayer.", "xpack.securitySolution.riskScore.riskScorePreview.errorTitle": "Erreur de l'aperçu", @@ -42225,35 +42201,6 @@ "xpack.securitySolution.riskScore.riskScorePreview.usefulLinks": "Liens utiles", "xpack.securitySolution.riskScore.riskScorePreview.users.hide": "Masquer les utilisateurs", "xpack.securitySolution.riskScore.riskScorePreview.users.show": "Afficher les utilisateurs", - "xpack.securitySolution.riskScore.savedObjects.bulkCreateFailureTitle": "Impossible d’importer les objets enregistrés", - "xpack.securitySolution.riskScore.savedObjects.bulkCreateSuccessTitle": "{totalCount} {totalCount, plural, =1 {objet enregistré importé} other {objets enregistrés importés}}", - "xpack.securitySolution.riskScore.savedObjects.bulkDeleteFailureTitle": "Impossible de supprimer les objets enregistrés", - "xpack.securitySolution.riskScore.savedObjects.enableRiskScoreSuccessTitle": "{items} ont bien été importés", - "xpack.securitySolution.riskScore.savedObjects.failedToCreateTagTitle": "Impossible d'importer les objets enregistrés : {savedObjectTemplate} n'a pas été créé, car la balise n'a pas pu être créée : {tagName}", - "xpack.securitySolution.riskScore.savedObjects.failedToFindTagTitle": "Impossible d'importer les objets enregistrés : {savedObjectTemplate} n'a pas été créé, car la balise n'a pas pu être trouvée : {tagName}", - "xpack.securitySolution.riskScore.savedObjects.templateAlreadyExistsTitle": "Impossible d'importer les objets enregistrés : {savedObjectTemplate} n'a pas été créé, car il existe déjà", - "xpack.securitySolution.riskScore.savedObjects.templateNotFoundTitle": "Impossible d'importer les objets enregistrés : {savedObjectTemplate} n'a pas été créé, car le modèle n'a pas été trouvé", - "xpack.securitySolution.riskScore.startUpdate": "Lancer la mise à jour", - "xpack.securitySolution.riskScore.technicalPreviewLabel": "Bêta", - "xpack.securitySolution.riskScore.transform.notFoundTitle": "Impossible de vérifier l'état de transformation, car {transformId} n'a pas été trouvé", - "xpack.securitySolution.riskScore.transform.start.stateConflictTitle": "Impossible de démarrer la transformation {transformId}, car son état est : {state}", - "xpack.securitySolution.riskScore.transform.transformExistsTitle": "Impossible de créer la transformation, car {transformId} existe déjà", - "xpack.securitySolution.riskScore.uninstall.errorMessageTitle": "Erreur de désinstallation", - "xpack.securitySolution.riskScore.updateAvailable": "Mise à jour disponible", - "xpack.securitySolution.riskScore.updatePanel.Dismiss": "Rejeter", - "xpack.securitySolution.riskScore.updatePanel.goToManage": "Gérer", - "xpack.securitySolution.riskScore.updatePanel.message": "Un nouveau moteur d'évaluation du risque des entités est disponible. Mettre à jour maintenant pour obtenir les dernières fonctionnalités.", - "xpack.securitySolution.riskScore.updatePanel.title": "Nouveau moteur d'évaluation du risque des entités disponible", - "xpack.securitySolution.riskScore.updateRiskEngineModa.title": "Voulez-vous mettre à jour le moteur de risque des entités ?", - "xpack.securitySolution.riskScore.updateRiskEngineModal.buttonNo": "Non, pas maintenant", - "xpack.securitySolution.riskScore.updateRiskEngineModal.buttonYes": "Oui, faire la mise à jour maintenant", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_1": "Les données héritées de score de risque ne seront pas supprimées,", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_2": "elles seront toujours présentes dans l'index, mais sans être disponibles dans l'interface utilisateur. Il vous faudra retirer manuellement les données héritées de score de risque.", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_1": "Les transformations existantes de score de risque de l'utilisateur et de l'hôte seront supprimées,", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_2": "puisqu'elles ne seront plus nécessaires.", - "xpack.securitySolution.riskScore.updatingRiskEngine": "Mise à jour du moteur de risque...", - "xpack.securitySolution.riskScore.userRiskScoresEnabledTitle": "Scores de risque de l'utilisateur activés", - "xpack.securitySolution.riskScore.usersDashboardRestartTooltip": "Le calcul du score de risque pourra prendre un certain temps à se lancer. Cependant, en appuyant sur Redémarrer, vous pouvez le forcer à s'exécuter immédiatement.", "xpack.securitySolution.riskScore.usersDashboardWarningPanelBody": "Nous n’avons pas trouvé de données de score de risque de l’utilisateur. Vérifiez si vous avez des filtres globaux dans la barre de recherche KQL globale. Si vous venez d’activer le module de risque de l’utilisateur, le moteur de risque peut mettre une heure à générer les données de score de risque de l’utilisateur et à les afficher dans ce panneau.", "xpack.securitySolution.riskScore.usersDashboardWarningPanelTitle": "Aucune donnée de score de risque de l'utilisateur disponible pour l'affichage", "xpack.securitySolution.riskTabBody.scoreOverTimeTitle": "Score de risque de {riskEntity} sur la durée", @@ -43802,8 +43749,8 @@ "xpack.slo.sloEmbeddable.config.sloSelector.placeholder": "Sélectionner un SLO", "xpack.slo.sloEmbeddable.displayName": "Aperçu du SLO", "xpack.slo.sloEmbeddable.overview.sloNotFoundText": "Le SLO a été supprimé. Vous pouvez supprimer sans risque le widget du tableau de bord.", - "xpack.slo.sLOGridItem.targetFlexItemLabel": "Cible {target}", "xpack.slo.sloGridItem.targetFlexItemLabel": "Cible {target}", + "xpack.slo.sLOGridItem.targetFlexItemLabel": "Cible {target}", "xpack.slo.sloGroupConfiguration.customFiltersLabel": "Personnaliser le filtre", "xpack.slo.sloGroupConfiguration.customFiltersOptional": "Facultatif", "xpack.slo.sloGroupConfiguration.customFilterText": "Personnaliser le filtre", @@ -45328,8 +45275,8 @@ "xpack.stackConnectors.components.casesWebhookxpack.stackConnectors.components.casesWebhook.connectorTypeTitle": "Webhook - Données de gestion des cas", "xpack.stackConnectors.components.d3security.bodyCodeEditorAriaLabel": "Éditeur de code", "xpack.stackConnectors.components.d3security.bodyFieldLabel": "Corps", - "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3 Security", "xpack.stackConnectors.components.d3security.connectorTypeTitle": "Données D3", + "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3 Security", "xpack.stackConnectors.components.d3security.eventTypeFieldLabel": "Type d'événement", "xpack.stackConnectors.components.d3security.invalidActionText": "Nom d'action non valide.", "xpack.stackConnectors.components.d3security.requiredActionText": "L'action est requise.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index d4c397428a8e0..f2d87674ce498 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -11679,8 +11679,8 @@ "xpack.apm.serviceIcons.service": "サービス", "xpack.apm.serviceIcons.serviceDetails.cloud.architecture": "アーキテクチャー", "xpack.apm.serviceIcons.serviceDetails.cloud.availabilityZoneLabel": "{zones, plural, other {可用性ゾーン}}", - "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, other {関数名}}", "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, other {トリガータイプ}}", + "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, other {関数名}}", "xpack.apm.serviceIcons.serviceDetails.cloud.machineTypesLabel": "{machineTypes, plural, other {コンピュータータイプ} }\n", "xpack.apm.serviceIcons.serviceDetails.cloud.projectIdLabel": "プロジェクト ID", "xpack.apm.serviceIcons.serviceDetails.cloud.providerLabel": "クラウドプロバイダー", @@ -28232,8 +28232,8 @@ "xpack.maps.source.esSearch.descendingLabel": "降順", "xpack.maps.source.esSearch.extentFilterLabel": "マップの表示範囲でデータを動的にフィルタリング", "xpack.maps.source.esSearch.fieldNotFoundMsg": "インデックスパターン''{indexPatternName}''に''{fieldName}''が見つかりません。", - "xpack.maps.source.esSearch.geoFieldLabel": "地理空間フィールド", "xpack.maps.source.esSearch.geofieldLabel": "地理空間フィールド", + "xpack.maps.source.esSearch.geoFieldLabel": "地理空間フィールド", "xpack.maps.source.esSearch.geoFieldTypeLabel": "地理空間フィールドタイプ", "xpack.maps.source.esSearch.indexOverOneLengthEditError": "データビューは複数のインデックスを参照しています。データビューごとに1つのインデックスのみが許可されています。", "xpack.maps.source.esSearch.indexZeroLengthEditError": "データビューはどのインデックスも参照していません。", @@ -36974,7 +36974,6 @@ "xpack.securitySolution.alertCountByRuleByStatus.ruleName": "kibana.alert.rule.name", "xpack.securitySolution.alertCountByRuleByStatus.status": "ステータス", "xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle": "ルール名", - "xpack.securitySolution.alertDetails.overview.hostRiskDataTitle": "{riskEntity}リスクデータ", "xpack.securitySolution.alertDetails.summary.readLess": "表示を減らす", "xpack.securitySolution.alertDetails.summary.readMore": "続きを読む", "xpack.securitySolution.alerts.badge.readOnly.tooltip": "アラートを更新できません", @@ -37980,8 +37979,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "Kibanaで許可される最大数は、1回の実行につき、{maxNumber} {maxNumber, plural, other {アラート}}です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名前が必要です。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "ルール調査ガイドを追加...", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "必要な統合、構成ステップ、ルールが正常に動作するために必要な他のすべての項目といった、ルール前提条件に関する指示を入力します。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "ルールセットアップガイドを追加...", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "必要な統合、構成ステップ、ルールが正常に動作するために必要な他のすべての項目といった、ルール前提条件に関する指示を入力します。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "セットアップガイド", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "タグを空にすることはできません", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.threatIndicatorPathFieldEmptyError": "インジケータープレフィックスの無効化を空にすることはできません", @@ -39487,7 +39486,6 @@ "xpack.securitySolution.enableRiskScore.enableRiskScore": "{riskEntity}リスクスコアを有効化", "xpack.securitySolution.enableRiskScore.enableRiskScoreDescription": "この機能を有効化すると、このセクションで{riskEntity}リスクスコアにすばやくアクセスできます。モジュールを有効化した後、データの生成までに1時間かかる場合があります。", "xpack.securitySolution.enableRiskScore.enableRiskScorePopoverTitle": "モジュールを有効にする前に、アラートが使用可能でなければなりません", - "xpack.securitySolution.enableRiskScore.upgradeRiskScore": "{riskEntity}リスクスコアをアップグレード", "xpack.securitySolution.endpoint.action.chooseFromTheList": "リストからアクションを選択", "xpack.securitySolution.endpoint.action.permissionDenied": "パーミッションが拒否されました", "xpack.securitySolution.endpoint.actions.agentDetails": "エージェント詳細を表示", @@ -41210,9 +41208,6 @@ "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "認証データをクエリできませんでした", "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "イベントデータをクエリできませんでした", "xpack.securitySolution.hosts.pageTitle": "ホスト", - "xpack.securitySolution.hosts.topRiskScoreContributors.rankColumnTitle": "ランク", - "xpack.securitySolution.hosts.topRiskScoreContributors.ruleNameColumnTitle": "ルール名", - "xpack.securitySolution.hosts.topRiskScoreContributors.title": "上位のリスクスコアの要因", "xpack.securitySolution.hosts.topRiskScoreContributorsTable.title": "上位のリスクスコアの要因", "xpack.securitySolution.hostsRiskTable.filteredHostsTitle": "{severity}のリスクがあるホストを表示", "xpack.securitySolution.hostsRiskTable.hostNameTitle": "ホスト名", @@ -42100,8 +42095,6 @@ "xpack.securitySolution.responseActionsList.list.status": "ステータス", "xpack.securitySolution.responseActionsList.list.time": "時間", "xpack.securitySolution.responseActionsList.list.user": "ユーザー", - "xpack.securitySolution.risk_score.toast.viewDashboard": "ダッシュボードを表示", - "xpack.securitySolution.riskDeprecated.entity.upgradeRiskScoreDescription": "現在のデータはサポートされていません。データを移行し、モジュールをアップグレードしてください。モジュールを有効化した後、データの生成までに1時間かかる場合があります。", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.clusterPrivilegesTitle": "不足しているElasticsearchクラスター権限:", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.essenceDescription": "この機能のすべてにアクセスするには、次の権限が必要です。サポートについては、管理者にお問い合わせください。{docs}の詳細をお読みください。", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.indexPrivilegesTitle": "Elasticsearchインデックス権限がありません。", @@ -42132,16 +42125,6 @@ "xpack.securitySolution.riskInformation.title": "Entity Risk Analytics", "xpack.securitySolution.riskInformation.unknownRiskDescription": "20未満", "xpack.securitySolution.riskInformation.weightColumnHeader": "デフォルトリスクウィジェット", - "xpack.securitySolution.riskScore.api.ingestPipeline.create.errorMessageTitle": "インジェストパイプラインを作成できませんでした", - "xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle": "インジェスト{totalCount, plural, other {パイプライン}}を削除できませんでした", - "xpack.securitySolution.riskScore.api.storedScript.create.errorMessageTitle": "保存されたスクリプトを作成できませんでした", - "xpack.securitySolution.riskScore.api.storedScript.delete.errorMessageTitle": "保存されたスクリプトを削除できませんでした", - "xpack.securitySolution.riskScore.api.transforms.create.errorMessageTitle": "トランスフォームを作成できませんでした", - "xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle": "{totalCount, plural, other {トランスフォーム}}を削除できませんでした", - "xpack.securitySolution.riskScore.api.transforms.getState.errorMessageTitle": "トランスフォーム状態を取得できませんでした", - "xpack.securitySolution.riskScore.api.transforms.getState.notFoundMessageTitle": "トランスフォームが見つかりません", - "xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle": "{totalCount, plural, other {トランスフォーム}}を開始できませんでした", - "xpack.securitySolution.riskScore.api.transforms.stop.errorMessageTitle": "{totalCount, plural, other {トランスフォーム}}を停止できませんでした", "xpack.securitySolution.riskScore.enableButtonTitle": "有効にする", "xpack.securitySolution.riskScore.errorPanel.errors": "エラー", "xpack.securitySolution.riskScore.errorPanel.message": "リスクエンジンステータスを変更できませんでした。次の項目を修正して、再試行してください。", @@ -42149,13 +42132,9 @@ "xpack.securitySolution.riskScore.errors.privileges.check": "権限を確認", "xpack.securitySolution.riskScore.errors.privileges.needToHave": "次の項目が必要です。", "xpack.securitySolution.riskScore.failSearchDescription": "リスクスコアで検索を実行できませんでした", - "xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle": "ホストリスクスコア有効", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody": "ホストリスクスコアデータが見つかりません。グローバルKQL検索バーにグローバルフィルターがあるかどうかを確認してください。ホストリスクモジュールを有効にしたばかりの場合は、リスクエンジンがホストリスクスコアデータを生成し、このパネルに表示するまでに1時間かかることがあります。", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelTitle": "表示するホストリスクスコアデータがありません", - "xpack.securitySolution.riskScore.install.errorMessageTitle": "インストールエラー", "xpack.securitySolution.riskScore.kpi.failSearchDescription": "リスクスコアで検索を実行できませんでした", - "xpack.securitySolution.riskScore.maxSpacePanel.message": "このスペースで有効化する前に、現在有効なスペースでエンティティリスクスコアリングを無効化できます。", - "xpack.securitySolution.riskScore.maxSpacePanel.title": "エンティティリスクスコアリングを有効にできるのは、{maxSpaces, plural, other {# 個のKibanaスペース}}までです。", "xpack.securitySolution.riskScore.moduleTurnedOff": "エンティティリスクスコアがオフになりました", "xpack.securitySolution.riskScore.moduleTurnedOn": "エンティティリスクスコアがオンになりました", "xpack.securitySolution.riskScore.overview.alerts": "アラート", @@ -42170,11 +42149,8 @@ "xpack.securitySolution.riskScore.previewTable.levelColumnTitle": "レベル", "xpack.securitySolution.riskScore.previewTable.nameColumnTitle": "名前", "xpack.securitySolution.riskScore.previewTable.scoreNormColumnTitle": "スコア基準", - "xpack.securitySolution.riskScore.restartButtonTitle": "再起動", "xpack.securitySolution.riskScore.riskScorePreview.eaDocsDashboard": "エンティティ分析ダッシュボード", "xpack.securitySolution.riskScore.riskScorePreview.eaDocsEntities": "リスクスコアを計算する方法", - "xpack.securitySolution.riskScore.riskScorePreview.eaDocsHosts": "ホストリスクスコア", - "xpack.securitySolution.riskScore.riskScorePreview.eaDocsUsers": "ユーザーリスクスコア", "xpack.securitySolution.riskScore.riskScorePreview.entityRiskScoring": "エンティティリスクスコア", "xpack.securitySolution.riskScore.riskScorePreview.errorMessage": "プレビューを作成しているときに問題が発生しました。再試行してください。", "xpack.securitySolution.riskScore.riskScorePreview.errorTitle": "プレビューが失敗しました", @@ -42192,35 +42168,6 @@ "xpack.securitySolution.riskScore.riskScorePreview.usefulLinks": "便利なリンク", "xpack.securitySolution.riskScore.riskScorePreview.users.hide": "ユーザーを非表示", "xpack.securitySolution.riskScore.riskScorePreview.users.show": "ユーザーを表示", - "xpack.securitySolution.riskScore.savedObjects.bulkCreateFailureTitle": "保存されたオブジェクトをインポートできませんでした", - "xpack.securitySolution.riskScore.savedObjects.bulkCreateSuccessTitle": "{totalCount} {totalCount, plural, other {個の保存されたオブジェクト}}が正常にインポートされました", - "xpack.securitySolution.riskScore.savedObjects.bulkDeleteFailureTitle": "保存されたオブジェクトを削除できませんでした", - "xpack.securitySolution.riskScore.savedObjects.enableRiskScoreSuccessTitle": "{items}が正常にインポートされました", - "xpack.securitySolution.riskScore.savedObjects.failedToCreateTagTitle": "保存されたオブジェクトをインポートできませんでした:タグ{tagName}を作成できなかったため、{savedObjectTemplate}が作成されませんでした", - "xpack.securitySolution.riskScore.savedObjects.failedToFindTagTitle": "保存されたオブジェクトをインポートできませんでした:タグ{tagName}を検出できなかったため、{savedObjectTemplate}が作成されませんでした", - "xpack.securitySolution.riskScore.savedObjects.templateAlreadyExistsTitle": "保存されたオブジェクトをインポートできませんでした:{savedObjectTemplate}はすでに存在するため、作成されませんでした", - "xpack.securitySolution.riskScore.savedObjects.templateNotFoundTitle": "保存されたオブジェクトをインポートできませんでした:{savedObjectTemplate}が見つからないため、作成されませんでした", - "xpack.securitySolution.riskScore.startUpdate": "更新を開始", - "xpack.securitySolution.riskScore.technicalPreviewLabel": "ベータ", - "xpack.securitySolution.riskScore.transform.notFoundTitle": "{transformId}が見つからないため、トランスフォームを確認できませんでした", - "xpack.securitySolution.riskScore.transform.start.stateConflictTitle": "状態が\"{state}\"のため、トランスフォーム{transformId}が開始しません", - "xpack.securitySolution.riskScore.transform.transformExistsTitle": "{transformId}がすでに存在するため、トランスフォームを作成できませんでした", - "xpack.securitySolution.riskScore.uninstall.errorMessageTitle": "アンインストールエラー", - "xpack.securitySolution.riskScore.updateAvailable": "更新が利用可能です", - "xpack.securitySolution.riskScore.updatePanel.Dismiss": "閉じる", - "xpack.securitySolution.riskScore.updatePanel.goToManage": "管理", - "xpack.securitySolution.riskScore.updatePanel.message": "新しいエンティティリスクスコアリングエンジンが利用可能です。今すぐ更新して最新機能をご利用ください。", - "xpack.securitySolution.riskScore.updatePanel.title": "新しいエンティティリスクスコアリングエンジンが利用可能です", - "xpack.securitySolution.riskScore.updateRiskEngineModa.title": "エンティティリスクエンジンを更新しますか?", - "xpack.securitySolution.riskScore.updateRiskEngineModal.buttonNo": "いいえ。今はしません", - "xpack.securitySolution.riskScore.updateRiskEngineModal.buttonYes": "はい。今すぐ更新します!", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_1": "レガシーリスクスコアデータは削除されません。", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_2": "インデックスには存在しますが、ユーザーインターフェースでは利用できなくなります。レガシーリスクスコアデータは手動で削除する必要があります。", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_1": "既存のユーザーとホストのリスクスコア変換は", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_2": "必要がないため、削除されます。", - "xpack.securitySolution.riskScore.updatingRiskEngine": "リスクエンジンを更新中...", - "xpack.securitySolution.riskScore.userRiskScoresEnabledTitle": "ユーザーリスクスコア有効", - "xpack.securitySolution.riskScore.usersDashboardRestartTooltip": "リスクスコア計算の実行には少し時間がかかる場合があります。ただし、再起動を押すと、すぐに強制的に実行できます。", "xpack.securitySolution.riskScore.usersDashboardWarningPanelBody": "ユーザーリスクスコアデータが見つかりません。グローバルKQL検索バーにグローバルフィルターがあるかどうかを確認してください。ユーザーリスクモジュールを有効にしたばかりの場合は、リスクエンジンがユーザーリスクスコアデータを生成し、このパネルに表示するまでに1時間かかることがあります。", "xpack.securitySolution.riskScore.usersDashboardWarningPanelTitle": "表示するユーザーリスクスコアデータがありません", "xpack.securitySolution.riskTabBody.scoreOverTimeTitle": "経時的な{riskEntity}リスクスコア", @@ -43766,8 +43713,8 @@ "xpack.slo.sloEmbeddable.config.sloSelector.placeholder": "SLOを選択", "xpack.slo.sloEmbeddable.displayName": "SLO概要", "xpack.slo.sloEmbeddable.overview.sloNotFoundText": "SLOが削除されました。ウィジェットをダッシュボードから安全に削除できます。", - "xpack.slo.sLOGridItem.targetFlexItemLabel": "目標{target}", "xpack.slo.sloGridItem.targetFlexItemLabel": "目標{target}", + "xpack.slo.sLOGridItem.targetFlexItemLabel": "目標{target}", "xpack.slo.sloGroupConfiguration.customFiltersLabel": "カスタムフィルター", "xpack.slo.sloGroupConfiguration.customFiltersOptional": "オプション", "xpack.slo.sloGroupConfiguration.customFilterText": "カスタムフィルター", @@ -45287,8 +45234,8 @@ "xpack.stackConnectors.components.casesWebhookxpack.stackConnectors.components.casesWebhook.connectorTypeTitle": "Webフック - ケース管理データ", "xpack.stackConnectors.components.d3security.bodyCodeEditorAriaLabel": "コードエディター", "xpack.stackConnectors.components.d3security.bodyFieldLabel": "本文", - "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3セキュリティ", "xpack.stackConnectors.components.d3security.connectorTypeTitle": "D3データ", + "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3セキュリティ", "xpack.stackConnectors.components.d3security.eventTypeFieldLabel": "イベントタイプ", "xpack.stackConnectors.components.d3security.invalidActionText": "無効なアクション名です。", "xpack.stackConnectors.components.d3security.requiredActionText": "アクションが必要です。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e5ee0c1ede629..706f96a0e1e52 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -11449,8 +11449,8 @@ "xpack.apm.serviceIcons.service": "服务", "xpack.apm.serviceIcons.serviceDetails.cloud.architecture": "架构", "xpack.apm.serviceIcons.serviceDetails.cloud.availabilityZoneLabel": "{zones, plural, other {可用性区域}}", - "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, other {功能名称}}", "xpack.apm.serviceIcons.serviceDetails.cloud.faasTriggerTypeLabel": "{triggerTypes, plural, other {触发类型}}", + "xpack.apm.serviceIcons.serviceDetails.cloud.functionNameLabel": "{functionNames, plural, other {功能名称}}", "xpack.apm.serviceIcons.serviceDetails.cloud.machineTypesLabel": "{machineTypes, plural, other {机器类型}}", "xpack.apm.serviceIcons.serviceDetails.cloud.projectIdLabel": "项目 ID", "xpack.apm.serviceIcons.serviceDetails.cloud.providerLabel": "云服务提供商", @@ -27741,8 +27741,8 @@ "xpack.maps.source.esSearch.convertToGeoJsonErrorMsg": "无法将搜索响应转换成 geoJson 功能集合,错误:{errorMsg}", "xpack.maps.source.esSearch.descendingLabel": "降序", "xpack.maps.source.esSearch.extentFilterLabel": "在可见地图区域中动态筛留数据", - "xpack.maps.source.esSearch.geoFieldLabel": "地理空间字段", "xpack.maps.source.esSearch.geofieldLabel": "地理空间字段", + "xpack.maps.source.esSearch.geoFieldLabel": "地理空间字段", "xpack.maps.source.esSearch.geoFieldTypeLabel": "地理空间字段类型", "xpack.maps.source.esSearch.indexOverOneLengthEditError": "您的数据视图指向多个索引。每个数据视图只允许一个索引。", "xpack.maps.source.esSearch.indexZeroLengthEditError": "您的数据视图未指向任何索引。", @@ -36378,7 +36378,6 @@ "xpack.securitySolution.alertCountByRuleByStatus.ruleName": "kibana.alert.rule.name", "xpack.securitySolution.alertCountByRuleByStatus.status": "状态", "xpack.securitySolution.alertCountByRuleByStatus.tooltipTitle": "规则名称", - "xpack.securitySolution.alertDetails.overview.hostRiskDataTitle": "{riskEntity}风险数据", "xpack.securitySolution.alertDetails.summary.readLess": "阅读更少内容", "xpack.securitySolution.alertDetails.summary.readMore": "阅读更多内容", "xpack.securitySolution.alerts.badge.readOnly.tooltip": "无法更新告警", @@ -37377,8 +37376,8 @@ "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.maxAlertsFieldLessThanWarning": "每次规则运行时,Kibana 最多只允许 {maxNumber} 个{maxNumber, plural, other {告警}}。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.nameFieldRequiredError": "名称必填。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.noteHelpText": "添加规则调查指南......", - "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "提供有关规则先决条件的说明,如所需集成、配置步骤,以及规则正常运行所需的任何其他内容。", "xpack.securitySolution.detectionEngine.createRule.stepAboutrule.setupHelpText": "添加规则设置指南......", + "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupHelpText": "提供有关规则先决条件的说明,如所需集成、配置步骤,以及规则正常运行所需的任何其他内容。", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.setupLabel": "设置指南", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.tagFieldEmptyError": "标签不得为空", "xpack.securitySolution.detectionEngine.createRule.stepAboutRule.threatIndicatorPathFieldEmptyError": "指标前缀覆盖不得为空", @@ -38877,7 +38876,6 @@ "xpack.securitySolution.enableRiskScore.enableRiskScore": "启用{riskEntity}风险分数", "xpack.securitySolution.enableRiskScore.enableRiskScoreDescription": "一旦启用此功能,您将可以在此部分快速访问{riskEntity}风险分数。启用此模板后,可能需要一小时才能生成数据。", "xpack.securitySolution.enableRiskScore.enableRiskScorePopoverTitle": "启用模块之前,告警需要处于可用状态", - "xpack.securitySolution.enableRiskScore.upgradeRiskScore": "升级{riskEntity}风险分数", "xpack.securitySolution.endpoint.action.chooseFromTheList": "从列表中选择操作", "xpack.securitySolution.endpoint.action.permissionDenied": "权限被拒绝", "xpack.securitySolution.endpoint.actions.agentDetails": "查看代理详情", @@ -40572,9 +40570,6 @@ "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingAuthenticationsData": "无法查询身份验证数据", "xpack.securitySolution.hosts.navigaton.matrixHistogram.errorFetchingEventsData": "无法查询事件数据", "xpack.securitySolution.hosts.pageTitle": "主机", - "xpack.securitySolution.hosts.topRiskScoreContributors.rankColumnTitle": "排名", - "xpack.securitySolution.hosts.topRiskScoreContributors.ruleNameColumnTitle": "规则名称", - "xpack.securitySolution.hosts.topRiskScoreContributors.title": "风险分数主要因素", "xpack.securitySolution.hosts.topRiskScoreContributorsTable.title": "风险分数主要因素", "xpack.securitySolution.hostsRiskTable.filteredHostsTitle": "查看{severity}风险主机", "xpack.securitySolution.hostsRiskTable.hostNameTitle": "主机名", @@ -41458,8 +41453,6 @@ "xpack.securitySolution.responseActionsList.list.status": "状态", "xpack.securitySolution.responseActionsList.list.time": "时间", "xpack.securitySolution.responseActionsList.list.user": "用户", - "xpack.securitySolution.risk_score.toast.viewDashboard": "查看仪表板", - "xpack.securitySolution.riskDeprecated.entity.upgradeRiskScoreDescription": "当前数据不再受支持。请迁移您的数据并升级该模块。启用此模板后,可能需要一小时才能生成数据。", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.clusterPrivilegesTitle": "缺少 Elasticsearch 集群权限:", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.essenceDescription": "您需要以下权限,才能完全使用此功能。有关进一步帮助,请联系您的管理员。阅读有关 {docs} 的更多内容。", "xpack.securitySolution.riskEngine.missingPrivilegesCallOut.messageBody.indexPrivilegesTitle": "缺少 Elasticsearch 索引权限:", @@ -41490,16 +41483,6 @@ "xpack.securitySolution.riskInformation.title": "实体风险分析", "xpack.securitySolution.riskInformation.unknownRiskDescription": "小于 20", "xpack.securitySolution.riskInformation.weightColumnHeader": "默认风险权重", - "xpack.securitySolution.riskScore.api.ingestPipeline.create.errorMessageTitle": "无法创建采集管道", - "xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle": "无法删除采集{totalCount, plural, other {管道}}", - "xpack.securitySolution.riskScore.api.storedScript.create.errorMessageTitle": "无法创建存储脚本", - "xpack.securitySolution.riskScore.api.storedScript.delete.errorMessageTitle": "无法删除存储脚本", - "xpack.securitySolution.riskScore.api.transforms.create.errorMessageTitle": "无法创建转换", - "xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle": "无法删除{totalCount, plural, other {转换}}", - "xpack.securitySolution.riskScore.api.transforms.getState.errorMessageTitle": "无法获取转换状态", - "xpack.securitySolution.riskScore.api.transforms.getState.notFoundMessageTitle": "找不到转换", - "xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle": "无法启动{totalCount, plural, other {转换}}", - "xpack.securitySolution.riskScore.api.transforms.stop.errorMessageTitle": "无法停止{totalCount, plural, other {转换}}", "xpack.securitySolution.riskScore.enableButtonTitle": "启用", "xpack.securitySolution.riskScore.errorPanel.errors": "错误", "xpack.securitySolution.riskScore.errorPanel.message": "无法更改风险引擎状态。修复以下问题,然后重试:", @@ -41507,13 +41490,9 @@ "xpack.securitySolution.riskScore.errors.privileges.check": "检查权限", "xpack.securitySolution.riskScore.errors.privileges.needToHave": "您需要具有:", "xpack.securitySolution.riskScore.failSearchDescription": "无法对风险分数执行搜索", - "xpack.securitySolution.riskScore.hostRiskScoresEnabledTitle": "已启用主机风险分数", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelBody": "找不到任何主机风险分数数据。检查全局 KQL 搜索栏中是否具有任何全局筛选。如果刚刚启用了主机风险模块,风险引擎可能需要一小时才能生成并在此面板中显示主机风险分数数据。", "xpack.securitySolution.riskScore.hostsDashboardWarningPanelTitle": "没有可显示的主机风险分数数据", - "xpack.securitySolution.riskScore.install.errorMessageTitle": "安装错误", "xpack.securitySolution.riskScore.kpi.failSearchDescription": "无法对风险分数执行搜索", - "xpack.securitySolution.riskScore.maxSpacePanel.message": "在此工作区中启用实体风险评分之前,您可以在当前已启用实体风险评分的工作区中将其禁用", - "xpack.securitySolution.riskScore.maxSpacePanel.title": "无法在超过 {maxSpaces, plural, other {# 个 Kibana 工作区}}中启用实体风险评分。", "xpack.securitySolution.riskScore.moduleTurnedOff": "已关闭实体风险分数", "xpack.securitySolution.riskScore.moduleTurnedOn": "已打开实体风险分数", "xpack.securitySolution.riskScore.overview.alerts": "告警", @@ -41528,11 +41507,8 @@ "xpack.securitySolution.riskScore.previewTable.levelColumnTitle": "级别", "xpack.securitySolution.riskScore.previewTable.nameColumnTitle": "名称", "xpack.securitySolution.riskScore.previewTable.scoreNormColumnTitle": "评分标准", - "xpack.securitySolution.riskScore.restartButtonTitle": "重新启动", "xpack.securitySolution.riskScore.riskScorePreview.eaDocsDashboard": "实体分析仪表板", "xpack.securitySolution.riskScore.riskScorePreview.eaDocsEntities": "如何计算风险分数?", - "xpack.securitySolution.riskScore.riskScorePreview.eaDocsHosts": "主机风险分数", - "xpack.securitySolution.riskScore.riskScorePreview.eaDocsUsers": "用户风险分数", "xpack.securitySolution.riskScore.riskScorePreview.entityRiskScoring": "实体风险分数", "xpack.securitySolution.riskScore.riskScorePreview.errorMessage": "创建预览时出现了问题。请重试。", "xpack.securitySolution.riskScore.riskScorePreview.errorTitle": "预览失败", @@ -41550,35 +41526,6 @@ "xpack.securitySolution.riskScore.riskScorePreview.usefulLinks": "有用的链接", "xpack.securitySolution.riskScore.riskScorePreview.users.hide": "隐藏用户", "xpack.securitySolution.riskScore.riskScorePreview.users.show": "显示用户", - "xpack.securitySolution.riskScore.savedObjects.bulkCreateFailureTitle": "无法导入已保存对象", - "xpack.securitySolution.riskScore.savedObjects.bulkCreateSuccessTitle": "已成功导入 {totalCount} 个{totalCount, plural, other {已保存对象}}", - "xpack.securitySolution.riskScore.savedObjects.bulkDeleteFailureTitle": "无法删除已保存对象", - "xpack.securitySolution.riskScore.savedObjects.enableRiskScoreSuccessTitle": "已成功导入 {items}", - "xpack.securitySolution.riskScore.savedObjects.failedToCreateTagTitle": "无法导入已保存对象:未创建 {savedObjectTemplate},因为无法创建标签:{tagName}", - "xpack.securitySolution.riskScore.savedObjects.failedToFindTagTitle": "无法导入已保存对象:未创建 {savedObjectTemplate},因为找不到标签:{tagName}", - "xpack.securitySolution.riskScore.savedObjects.templateAlreadyExistsTitle": "无法导入已保存对象:未创建 {savedObjectTemplate},因为其已存在", - "xpack.securitySolution.riskScore.savedObjects.templateNotFoundTitle": "无法导入已保存对象:未创建 {savedObjectTemplate},因为找不到模板", - "xpack.securitySolution.riskScore.startUpdate": "开始更新", - "xpack.securitySolution.riskScore.technicalPreviewLabel": "公测版", - "xpack.securitySolution.riskScore.transform.notFoundTitle": "无法检查转换状态,因为找不到 {transformId}", - "xpack.securitySolution.riskScore.transform.start.stateConflictTitle": "未启动转换 {transformId},因为其状态为:{state}", - "xpack.securitySolution.riskScore.transform.transformExistsTitle": "无法创建转换,因为 {transformId} 已存在", - "xpack.securitySolution.riskScore.uninstall.errorMessageTitle": "卸载错误", - "xpack.securitySolution.riskScore.updateAvailable": "有可用更新", - "xpack.securitySolution.riskScore.updatePanel.Dismiss": "关闭", - "xpack.securitySolution.riskScore.updatePanel.goToManage": "管理", - "xpack.securitySolution.riskScore.updatePanel.message": "有新的实体风险评分引擎可用。立即进行更新以获取最新功能。", - "xpack.securitySolution.riskScore.updatePanel.title": "新的实体风险评分引擎可用", - "xpack.securitySolution.riskScore.updateRiskEngineModa.title": "是否要更新实体风险引擎?", - "xpack.securitySolution.riskScore.updateRiskEngineModal.buttonNo": "否,暂不更新", - "xpack.securitySolution.riskScore.updateRiskEngineModal.buttonYes": "是,立即更新!", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_1": "将不会删除旧版风险分数数据", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingData_2": ",它将仍然存在于索引中,但在用户界面中不再可用。您需要手动移除旧版风险分数数据。", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_1": "将删除现有用户和主机风险分数转换", - "xpack.securitySolution.riskScore.updateRiskEngineModal.existingUserHost_2": ",因为不再需要它们。", - "xpack.securitySolution.riskScore.updatingRiskEngine": "正在更新风险引擎......", - "xpack.securitySolution.riskScore.userRiskScoresEnabledTitle": "已启用用户风险分数", - "xpack.securitySolution.riskScore.usersDashboardRestartTooltip": "风险分数计算可能需要一段时间运行。但是,通过按'重新启动',您可以立即强制运行该计算。", "xpack.securitySolution.riskScore.usersDashboardWarningPanelBody": "找不到任何用户风险分数数据。检查全局 KQL 搜索栏中是否具有任何全局筛选。如果刚刚启用了用户风险模块,风险引擎可能需要一小时才能生成并在此面板中显示用户风险分数数据。", "xpack.securitySolution.riskScore.usersDashboardWarningPanelTitle": "没有可显示的用户风险分数数据", "xpack.securitySolution.riskTabBody.scoreOverTimeTitle": "一段时间的{riskEntity}风险分数", @@ -43115,8 +43062,8 @@ "xpack.slo.sloEmbeddable.config.sloSelector.placeholder": "选择 SLO", "xpack.slo.sloEmbeddable.displayName": "SLO 概览", "xpack.slo.sloEmbeddable.overview.sloNotFoundText": "SLO 已删除。您可以放心从仪表板中删除小组件。", - "xpack.slo.sLOGridItem.targetFlexItemLabel": "目标 {target}", "xpack.slo.sloGridItem.targetFlexItemLabel": "目标 {target}", + "xpack.slo.sLOGridItem.targetFlexItemLabel": "目标 {target}", "xpack.slo.sloGroupConfiguration.customFiltersLabel": "定制筛选", "xpack.slo.sloGroupConfiguration.customFiltersOptional": "可选", "xpack.slo.sloGroupConfiguration.customFilterText": "定制筛选", @@ -44588,8 +44535,8 @@ "xpack.stackConnectors.components.casesWebhookxpack.stackConnectors.components.casesWebhook.connectorTypeTitle": "Webhook - 案例管理数据", "xpack.stackConnectors.components.d3security.bodyCodeEditorAriaLabel": "代码编辑器", "xpack.stackConnectors.components.d3security.bodyFieldLabel": "正文", - "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3 Security", "xpack.stackConnectors.components.d3security.connectorTypeTitle": "D3 数据", + "xpack.stackConnectors.components.d3Security.connectorTypeTitle": "D3 Security", "xpack.stackConnectors.components.d3security.eventTypeFieldLabel": "事件类型", "xpack.stackConnectors.components.d3security.invalidActionText": "操作名称无效。", "xpack.stackConnectors.components.d3security.requiredActionText": "'操作'必填。", From 715f219f349e6475541549b9387942bf24fa6768 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 16:10:08 +0000 Subject: [PATCH 09/38] more type errors --- .../components/dashboard_enablement_panel.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx index 38449fa1e72ff..e2daffb7c6870 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_enablement_panel.tsx @@ -17,7 +17,10 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import type { UseQueryResult } from '@tanstack/react-query'; import type { GetEntityStoreStatusResponse } from '../../../../../common/api/entity_analytics/entity_store/status.gen'; -import type { StoreStatus } from '../../../../../common/api/entity_analytics'; +import type { + RiskEngineStatusResponse, + StoreStatus, +} from '../../../../../common/api/entity_analytics'; import { RiskEngineStatusEnum } from '../../../../../common/api/entity_analytics'; import { useInitRiskEngineMutation } from '../../../api/hooks/use_init_risk_engine_mutation'; import { useEnableEntityStoreMutation } from '../hooks/use_entity_store'; @@ -34,11 +37,10 @@ import { import type { Enablements } from './enablement_modal'; import { EntityStoreEnablementModal } from './enablement_modal'; import dashboardEnableImg from '../../../images/entity_store_dashboard.png'; -import type { RiskEngineStatus } from '../../../api/hooks/use_risk_engine_status'; interface EnableEntityStorePanelProps { state: { - riskEngine: UseQueryResult; + riskEngine: UseQueryResult; entityStore: UseQueryResult; }; } @@ -181,7 +183,7 @@ export const EnablementPanel: React.FC = ({ state } const getEnablementTexts = ( entityStoreStatus?: StoreStatus, - riskEngineStatus?: RiskEngineStatus['risk_engine_status'] + riskEngineStatus?: RiskEngineStatusResponse['risk_engine_status'] ): [string, string] => { if ( (entityStoreStatus === 'not_installed' || entityStoreStatus === 'stopped') && From 6ab5934b54b4e8f5a86246e9eb95b26728ed62a0 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:12:40 +0000 Subject: [PATCH 10/38] [CI] Auto-commit changed files from 'yarn openapi:generate' --- .../api/entity_analytics/risk_engine/engine_init_route.gen.ts | 1 + .../api/entity_analytics/risk_engine/engine_status_route.gen.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts index 6ffdea0775fce..ec394a721a97b 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts @@ -21,6 +21,7 @@ export const InitRiskEngineResult = z.object({ risk_engine_enabled: z.boolean(), risk_engine_resources_installed: z.boolean(), risk_engine_configuration_created: z.boolean(), + legacy_risk_engine_disabled: z.boolean(), errors: z.array(z.string()), }); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts index 1afd9c0d04e1d..0faf22c032e06 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts @@ -43,6 +43,7 @@ export const RiskEngineTaskStatus = z.object({ export type RiskEngineStatusResponse = z.infer; export const RiskEngineStatusResponse = z.object({ + legacy_risk_engine_status: RiskEngineStatus, risk_engine_status: RiskEngineStatus, risk_engine_task_status: RiskEngineTaskStatus.optional(), }); From 43245593ea13a6f3fe6b8943bd24aa3df95f83ac Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 2 Dec 2024 16:48:02 +0000 Subject: [PATCH 11/38] Remove legacy_risk_engine_disabled from InitRiskEngineResult and schema --- .../api/entity_analytics/risk_engine/engine_init_route.gen.ts | 1 - .../entity_analytics/risk_engine/engine_init_route.schema.yaml | 3 --- 2 files changed, 4 deletions(-) diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts index ec394a721a97b..6ffdea0775fce 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.gen.ts @@ -21,7 +21,6 @@ export const InitRiskEngineResult = z.object({ risk_engine_enabled: z.boolean(), risk_engine_resources_installed: z.boolean(), risk_engine_configuration_created: z.boolean(), - legacy_risk_engine_disabled: z.boolean(), errors: z.array(z.string()), }); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.schema.yaml index 58091241d97b7..2ccdc964b8d10 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_init_route.schema.yaml @@ -45,7 +45,6 @@ components: - risk_engine_enabled - risk_engine_resources_installed - risk_engine_configuration_created - - legacy_risk_engine_disabled - errors properties: risk_engine_enabled: @@ -54,8 +53,6 @@ components: type: boolean risk_engine_configuration_created: type: boolean - legacy_risk_engine_disabled: - type: boolean errors: type: array items: From d47b3799e633195f4086233e85be933e689a9725 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Tue, 3 Dec 2024 10:45:44 +0000 Subject: [PATCH 12/38] remove legacy_risk_engine_status refs --- .../entity_analytics/risk_engine/engine_status_route.gen.ts | 1 - .../risk_engine/engine_status_route.schema.yaml | 3 --- .../cypress/tasks/entity_analytics.ts | 1 - 3 files changed, 5 deletions(-) diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts index 0faf22c032e06..1afd9c0d04e1d 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.gen.ts @@ -43,7 +43,6 @@ export const RiskEngineTaskStatus = z.object({ export type RiskEngineStatusResponse = z.infer; export const RiskEngineStatusResponse = z.object({ - legacy_risk_engine_status: RiskEngineStatus, risk_engine_status: RiskEngineStatus, risk_engine_task_status: RiskEngineTaskStatus.optional(), }); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.schema.yaml index f4d074d67c2a4..90abd80aa3985 100644 --- a/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.schema.yaml +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/risk_engine/engine_status_route.schema.yaml @@ -57,11 +57,8 @@ components: RiskEngineStatusResponse: type: object required: - - legacy_risk_engine_status - risk_engine_status properties: - legacy_risk_engine_status: - $ref: '#/components/schemas/RiskEngineStatus' risk_engine_status: $ref: '#/components/schemas/RiskEngineStatus' risk_engine_task_status: diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts b/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts index e69739ae4b359..75f1886a7dce2 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/entity_analytics.ts @@ -64,7 +64,6 @@ export const mockRiskEngineEnabled = () => { statusCode: 200, body: { risk_engine_status: 'ENABLED', - legacy_risk_engine_status: 'INSTALLED', }, }).as('riskEngineStatus'); }; From d6a33a2aebabda0ae4a0221b6bdfa2441579ef46 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 4 Dec 2024 14:08:26 +0000 Subject: [PATCH 13/38] delete legacy test data --- .../es_archives/entity/host_risk/data.json | 120 ------- .../entity/host_risk/mappings.json | 35 -- .../tasks/api_calls/risk_scores/index.ts | 307 ------------------ .../es_archives/risk_hosts/data.json | 174 ---------- .../es_archives/risk_hosts/mappings.json | 94 ------ .../es_archives/risk_hosts_no_data/data.json | 0 .../risk_hosts_no_data/mappings.json | 94 ------ .../es_archives/risk_hosts_updated/data.json | 24 -- .../risk_hosts_updated/mappings.json | 94 ------ .../es_archives/risk_users/data.json | 199 ------------ .../es_archives/risk_users/mappings.json | 94 ------ .../es_archives/risk_users_no_data/data.json | 0 .../risk_users_no_data/mappings.json | 94 ------ 13 files changed, 1329 deletions(-) delete mode 100644 x-pack/test/functional/es_archives/entity/host_risk/data.json delete mode 100644 x-pack/test/functional/es_archives/entity/host_risk/mappings.json delete mode 100644 x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/index.ts delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts/mappings.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/mappings.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/mappings.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_users/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_users/mappings.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/data.json delete mode 100644 x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/mappings.json diff --git a/x-pack/test/functional/es_archives/entity/host_risk/data.json b/x-pack/test/functional/es_archives/entity/host_risk/data.json deleted file mode 100644 index 50979283a0582..0000000000000 --- a/x-pack/test/functional/es_archives/entity/host_risk/data.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "type": "doc", - "value": { - "index": "ml_host_risk_score_latest_default", - "id": "1", - "source": { - "host": { - "name": "suricata-zeek-sensor-toronto", - "risk": { - "calculated_score_norm": 96, - "calculated_level": "Critical" - } - }, - "ingest_timestamp": "2022-08-15T16:32:16.142561766Z", - "@timestamp": "2022-08-12T14:45:36.171Z" - }, - "type": "_doc" - } -} - -{ - "type": "doc", - "value": { - "id": "2", - "index": "ml_host_risk_score_latest_default", - "source": { - "host": { - "name": "suricata-sensor-london", - "risk": { - "calculated_score_norm": 20, - "calculated_level": "Low" - } - }, - "ingest_timestamp": "2022-08-15T16:32:16.142561766Z", - "@timestamp": "2022-08-12T14:45:36.171Z" - }, - "type": "_doc" - } -} - -{ - "type": "doc", - "value": { - "id": "3", - "index": "ml_host_risk_score_latest_default", - "source": { - "host": { - "name": "zeek-newyork-sha-aa8df15", - "risk": { - "calculated_score_norm": 23, - "calculated_level": "Low" - } - }, - "ingest_timestamp": "2022-08-15T16:32:16.142561766Z", - "@timestamp": "2022-08-12T14:45:36.171Z" - }, - "type": "_doc" - } -} - -{ - "type": "doc", - "value": { - "id": "4", - "index": "ml_host_risk_score_latest_default", - "source": { - "host": { - "name": "zeek-sensor-amsterdam", - "risk": { - "calculated_score_norm": 70, - "calculated_level": "Critical" - } - }, - "ingest_timestamp": "2022-08-15T16:32:16.142561766Z", - "@timestamp": "2022-08-12T14:45:36.171Z" - }, - "type": "_doc" - } -} - -{ - "type": "doc", - "value": { - "id": "5", - "index": "ml_host_risk_score_latest_default", - "source": { - "host": { - "name": "mothra", - "risk": { - "calculated_score_norm": 1, - "calculated_level": "Low" - } - }, - "ingest_timestamp": "2022-08-15T16:32:16.142561766Z", - "@timestamp": "2022-08-12T14:45:36.171Z" - }, - "type": "_doc" - } -} - -{ - "type": "doc", - "value": { - "id": "6", - "index": "ml_host_risk_score_latest_default", - "source": { - "host": { - "name": "host-0", - "risk": { - "calculated_score_norm": 1, - "calculated_level": "Low" - } - }, - "ingest_timestamp": "2022-08-15T16:32:16.142561766Z", - "@timestamp": "2022-08-12T14:45:36.171Z" - }, - "type": "_doc" - } -} - diff --git a/x-pack/test/functional/es_archives/entity/host_risk/mappings.json b/x-pack/test/functional/es_archives/entity/host_risk/mappings.json deleted file mode 100644 index 623ac12b2229a..0000000000000 --- a/x-pack/test/functional/es_archives/entity/host_risk/mappings.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - - "type": "index", - "value": { - "index": "ml_host_risk_score_latest_default", - "mappings": { - "properties": { - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "float" - } - } - } - } - } - } - }, - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_replicas": "0", - "number_of_shards": "1" - } - } - } -} diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/index.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/index.ts deleted file mode 100644 index 66f56def341fc..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/index.ts +++ /dev/null @@ -1,307 +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 { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { ENTITY_ANALYTICS_URL } from '../../../urls/navigation'; -import { RISK_SCORE_URL } from '../../../urls/risk_score'; -import { visitWithTimeRange } from '../../navigation'; -import { RiskScoreEntity } from '../../risk_scores/common'; -import { - getLegacyRiskScoreIndicesOptions, - getLegacyRiskScoreLatestIndicesOptions, -} from '../../risk_scores/indices'; -import { - getIngestPipelineName, - getLegacyIngestPipelineName, - getLegacyRiskScoreIngestPipelineOptions, -} from '../../risk_scores/ingest_pipelines'; -import { - getLegacyRiskHostCreateInitScriptOptions, - getLegacyRiskHostCreateLevelScriptOptions, - getLegacyRiskHostCreateMapScriptOptions, - getLegacyRiskHostCreateReduceScriptOptions, - getLegacyRiskScoreInitScriptId, - getLegacyRiskScoreLevelScriptId, - getLegacyRiskScoreMapScriptId, - getLegacyRiskScoreReduceScriptId, - getLegacyRiskUserCreateLevelScriptOptions, - getLegacyRiskUserCreateMapScriptOptions, - getLegacyRiskUserCreateReduceScriptOptions, - getRiskScoreInitScriptId, - getRiskScoreLevelScriptId, - getRiskScoreMapScriptId, - getRiskScoreReduceScriptId, -} from '../../risk_scores/stored_scripts'; -import { - createTransform, - deleteTransforms, - getCreateLegacyLatestTransformOptions, - getCreateLegacyMLHostPivotTransformOptions, - getCreateLegacyMLUserPivotTransformOptions, - getRiskScoreLatestTransformId, - getRiskScorePivotTransformId, - startTransforms, -} from '../../risk_scores/transforms'; -import { createIndex, deleteRiskScoreIndicies } from './indices'; -import { createIngestPipeline, deleteRiskScoreIngestPipelines } from './ingest_pipelines'; -import { deleteSavedObjects } from './saved_objects'; -import { createStoredScript, deleteStoredScripts } from './stored_scripts'; -import { rootRequest } from '../common'; - -export const deleteRiskScore = ({ - riskScoreEntity, - spaceId, -}: { - riskScoreEntity: RiskScoreEntity; - spaceId?: string; -}) => { - const transformIds = [ - getRiskScorePivotTransformId(riskScoreEntity, spaceId), - getRiskScoreLatestTransformId(riskScoreEntity, spaceId), - ]; - const legacyIngestPipelineNames = [getLegacyIngestPipelineName(riskScoreEntity)]; - const ingestPipelinesNames = [ - ...legacyIngestPipelineNames, - getIngestPipelineName(riskScoreEntity, spaceId), - ]; - - const legacyScriptIds = [ - ...(riskScoreEntity === RiskScoreEntity.host - ? [getLegacyRiskScoreInitScriptId(riskScoreEntity)] - : []), - getLegacyRiskScoreLevelScriptId(riskScoreEntity), - getLegacyRiskScoreMapScriptId(riskScoreEntity), - getLegacyRiskScoreReduceScriptId(riskScoreEntity), - ]; - const scripts = [ - ...legacyScriptIds, - ...(riskScoreEntity === RiskScoreEntity.host - ? [getRiskScoreInitScriptId(riskScoreEntity, spaceId)] - : []), - getRiskScoreLevelScriptId(riskScoreEntity, spaceId), - getRiskScoreMapScriptId(riskScoreEntity, spaceId), - getRiskScoreReduceScriptId(riskScoreEntity, spaceId), - ]; - - deleteTransforms(transformIds); - deleteRiskScoreIngestPipelines(ingestPipelinesNames); - deleteStoredScripts(scripts); - deleteSavedObjects(`${riskScoreEntity}RiskScoreDashboards`); - deleteRiskScoreIndicies(riskScoreEntity, spaceId); -}; - -/** - * Scripts id and ingest pipeline id do not have Space ID appended in 8.4. - * Scripts id and ingest pipeline id in 8.3 and after 8.5 do. - */ -const installLegacyHostRiskScoreModule = (spaceId: string, version?: '8.3' | '8.4') => { - /** - * Step 1 Upload script: ml_hostriskscore_levels_script - */ - createStoredScript(getLegacyRiskHostCreateLevelScriptOptions(version)) - .then(() => { - /** - * Step 2 Upload script: ml_hostriskscore_init_script - */ - return createStoredScript(getLegacyRiskHostCreateInitScriptOptions(version)); - }) - .then(() => { - /** - * Step 3 Upload script: ml_hostriskscore_map_script - */ - return createStoredScript(getLegacyRiskHostCreateMapScriptOptions(version)); - }) - .then(() => { - /** - * Step 4 Upload script: ml_hostriskscore_reduce_script - */ - return createStoredScript(getLegacyRiskHostCreateReduceScriptOptions(version)); - }) - .then(() => { - /** - * Step 5 Upload the ingest pipeline: ml_hostriskscore_ingest_pipeline - */ - return createIngestPipeline( - getLegacyRiskScoreIngestPipelineOptions(RiskScoreEntity.host, version) - ); - }) - .then(() => { - /** - * Step 6 create ml_host_risk_score_{spaceId} index - */ - return createIndex( - getLegacyRiskScoreIndicesOptions({ - spaceId, - riskScoreEntity: RiskScoreEntity.host, - }) - ); - }) - .then(() => { - /** - * Step 7 create transform: ml_hostriskscore_pivot_transform_{spaceId} - */ - return createTransform( - getRiskScorePivotTransformId(RiskScoreEntity.host, spaceId), - getCreateLegacyMLHostPivotTransformOptions({ spaceId, version }) - ); - }) - .then(() => { - /** - * Step 8 create ml_host_risk_score_latest_{spaceId} index - */ - return createIndex( - getLegacyRiskScoreLatestIndicesOptions({ - spaceId, - riskScoreEntity: RiskScoreEntity.host, - }) - ); - }) - .then(() => { - /** - * Step 9 create transform: ml_hostriskscore_latest_transform_{spaceId} - */ - return createTransform( - getRiskScoreLatestTransformId(RiskScoreEntity.host, spaceId), - getCreateLegacyLatestTransformOptions({ - spaceId, - riskScoreEntity: RiskScoreEntity.host, - }) - ); - }) - .then(() => { - /** - * Step 10 Start the pivot transform - * Step 11 Start the latest transform - */ - const transformIds = [ - getRiskScorePivotTransformId(RiskScoreEntity.host, spaceId), - getRiskScoreLatestTransformId(RiskScoreEntity.host, spaceId), - ]; - return startTransforms(transformIds); - }) - .then(() => { - // refresh page - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); -}; - -const installLegacyUserRiskScoreModule = async (spaceId = 'default', version?: '8.3' | '8.4') => { - /** - * Step 1 Upload script: ml_userriskscore_levels_script - */ - createStoredScript(getLegacyRiskUserCreateLevelScriptOptions(version)) - .then(() => { - /** - * Step 2 Upload script: ml_userriskscore_map_script - */ - return createStoredScript(getLegacyRiskUserCreateMapScriptOptions(version)); - }) - .then(() => { - /** - * Step 3 Upload script: ml_userriskscore_reduce_script - */ - return createStoredScript(getLegacyRiskUserCreateReduceScriptOptions(version)); - }) - .then(() => { - /** - * Step 4 Upload ingest pipeline: ml_userriskscore_ingest_pipeline - */ - return createIngestPipeline( - getLegacyRiskScoreIngestPipelineOptions(RiskScoreEntity.user, version) - ); - }) - .then(() => { - /** - * Step 5 create ml_user_risk_score_{spaceId} index - */ - return createIndex( - getLegacyRiskScoreIndicesOptions({ - spaceId, - riskScoreEntity: RiskScoreEntity.user, - }) - ); - }) - .then(() => { - /** - * Step 6 create Transform: ml_userriskscore_pivot_transform_{spaceId} - */ - return createTransform( - getRiskScorePivotTransformId(RiskScoreEntity.user, spaceId), - getCreateLegacyMLUserPivotTransformOptions({ spaceId, version }) - ); - }) - .then(() => { - /** - * Step 7 create ml_user_risk_score_latest_{spaceId} index - */ - return createIndex( - getLegacyRiskScoreLatestIndicesOptions({ - spaceId, - riskScoreEntity: RiskScoreEntity.user, - }) - ); - }) - .then(() => { - /** - * Step 8 create Transform: ml_userriskscore_latest_transform_{spaceId} - */ - return createTransform( - getRiskScoreLatestTransformId(RiskScoreEntity.user, spaceId), - getCreateLegacyLatestTransformOptions({ - spaceId, - riskScoreEntity: RiskScoreEntity.user, - }) - ); - }) - .then(() => { - /** - * Step 9 Start the pivot transform - * Step 10 Start the latest transform - */ - const transformIds = [ - getRiskScorePivotTransformId(RiskScoreEntity.user, spaceId), - getRiskScoreLatestTransformId(RiskScoreEntity.user, spaceId), - ]; - return startTransforms(transformIds); - }) - .then(() => { - visitWithTimeRange(ENTITY_ANALYTICS_URL); - }); -}; - -export const installLegacyRiskScoreModule = ( - riskScoreEntity: RiskScoreEntity, - spaceId = 'default', - version?: '8.3' | '8.4' -) => { - if (riskScoreEntity === RiskScoreEntity.user) { - installLegacyUserRiskScoreModule(spaceId, version); - } else { - installLegacyHostRiskScoreModule(spaceId, version); - } -}; - -export const interceptInstallRiskScoreModule = () => { - cy.intercept(`POST`, RISK_SCORE_URL).as('install'); -}; - -export const waitForInstallRiskScoreModule = () => { - cy.wait(['@install'], { requestTimeout: 50000 }); -}; - -export const installRiskScoreModule = () => { - rootRequest({ - url: RISK_SCORE_URL, - method: 'POST', - body: { - riskScoreEntity: 'host', - }, - headers: { - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - }); -}; diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts/data.json deleted file mode 100644 index b10cd1b6a1c0d..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts/data.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "a4cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "siem-kibana", - "risk": { - "calculated_level": "Low", - "calculated_score_norm": 21, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb71f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "fake-1", - "risk": { - "calculated_level": "Moderate", - "calculated_score_norm": 50, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb72f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "fake-2", - "risk": { - "calculated_level": "Moderate", - "calculated_score_norm": 50, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb73f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "fake-3", - "risk": { - "calculated_level": "Moderate", - "calculated_score_norm": 50, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "fake-4", - "risk": { - "calculated_level": "Moderate", - "calculated_score_norm": 50, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb75f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "fake-5", - "risk": { - "calculated_level": "Moderate", - "calculated_score_norm": 50, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a4cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f", - "index": "ml_host_risk_score_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "siem-kibana", - "risk": { - "calculated_level": "Low", - "calculated_score_norm": 21, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts/mappings.json deleted file mode 100644 index e250700644c15..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts/mappings.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} - - -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/data.json deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/mappings.json deleted file mode 100644 index e250700644c15..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_no_data/mappings.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} - - -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/data.json deleted file mode 100644 index 89ffd442b4786..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/data.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "a4cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f", - "index": "ml_host_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "host": { - "name": "siem-kibana", - "risk": { - "calculated_level": "Critical", - "calculated_score_norm": 90, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/mappings.json deleted file mode 100644 index e250700644c15..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_hosts_updated/mappings.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} - - -{ - "type": "index", - "value": { - "index": "ml_host_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "host": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_users/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_users/data.json deleted file mode 100644 index b513f934aac6b..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_users/data.json +++ /dev/null @@ -1,199 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "a4cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user1", - "risk": { - "calculated_level": "Low", - "calculated_score_norm": 21, - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb71f", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user2", - "risk": { - "calculated_score_norm": 50, - "calculated_level": "Moderate", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb72f", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user3", - "risk": { - "calculated_score_norm": 50, - "calculated_level": "Moderate", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb73f", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user4", - "risk": { - "calculated_score_norm": 50, - "calculated_level": "Moderate", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb74f", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user5", - "risk": { - "calculated_score_norm": 50, - "calculated_level": "Moderate", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a2cf452c1e0375c3d4412cb550bd1783358468a3b3b777da4829d72c7d6fb75f", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user6", - "risk": { - "calculated_score_norm": 50, - "calculated_level": "Moderate", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a4cf452c1e0375c3d4412cb550bd1783358468b3b3b777da4829d72c7d6fb74f", - "index": "ml_user_risk_score_default", - "source": { - "@timestamp": "2021-03-10T14:51:05.766Z", - "user": { - "name": "user1", - "risk": { - "calculated_score_norm": 21, - "calculated_level": "Low", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "a4cf452c1e0375c3d4412cb550bd1783358468b3123314829d72c7df6fb74", - "index": "ml_user_risk_score_latest_default", - "source": { - "@timestamp": "2021-03-10T14:52:05.766Z", - "user": { - "name": "test", - "risk": { - "calculated_score_norm": 21, - "calculated_level": "Low", - "rule_risks": [ - { - "rule_name": "Unusual Linux Username", - "rule_risk": 42 - } - ] - } - }, - "ingest_timestamp": "2021-03-09T18:02:08.319296053Z" - } - } -} \ No newline at end of file diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_users/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_users/mappings.json deleted file mode 100644 index 2591f2d216575..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_users/mappings.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_user_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "user": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} - - -{ - "type": "index", - "value": { - "index": "ml_user_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "user": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} \ No newline at end of file diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/data.json b/x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/data.json deleted file mode 100644 index e69de29bb2d1d..0000000000000 diff --git a/x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/mappings.json b/x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/mappings.json deleted file mode 100644 index 2591f2d216575..0000000000000 --- a/x-pack/test/security_solution_cypress/es_archives/risk_users_no_data/mappings.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "type": "index", - "value": { - "index": "ml_user_risk_score_latest_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "user": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} - - -{ - "type": "index", - "value": { - "index": "ml_user_risk_score_default", - "mappings": { - "properties": { - "@timestamp": { - "type": "date" - }, - "user": { - "properties": { - "name": { - "type": "keyword" - }, - "risk": { - "properties": { - "calculated_level": { - "type": "keyword" - }, - "calculated_score_norm": { - "type": "long" - } - } - } - } - }, - "ingest_timestamp": { - "type": "date" - } - } - }, - "settings": { - "index": { - "mapping": { - "total_fields": { - "limit": "10000" - } - }, - "max_docvalue_fields_search": "200", - "number_of_replicas": "1", - "number_of_shards": "1", - "refresh_interval": "5s" - } - } - } -} \ No newline at end of file From 22180bdeab0131269d65b5809727ea39b8638657 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 4 Dec 2024 14:09:06 +0000 Subject: [PATCH 14/38] remove telemetry --- .../telemetry_collection/get_data_telemetry/constants.ts | 4 ---- .../get_data_telemetry/get_data_telemetry.test.ts | 6 ------ 2 files changed, 10 deletions(-) diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts index 24e236a9858a3..6f16ac8c6b1a2 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/constants.ts @@ -129,10 +129,6 @@ export const DATA_DATASETS_INDEX_PATTERNS = [ // meow attacks { pattern: '*meow*', patternName: 'meow' }, - - // experimental ml - { pattern: 'ml_host_risk_score_latest_*', patternName: 'host_risk_score' }, - { pattern: 'ml_user_risk_score_latest_*', patternName: 'user_risk_score' }, ] as const; // Get the unique list of index patterns (some are duplicated for documentation purposes) diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts index 05513f9ae8cf3..e0dfeb1475313 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts @@ -76,12 +76,6 @@ describe('get_data_telemetry', () => { { name: 'some-random-logs', docCount: 100, sizeInBytes: 10 }, { name: 'my-prod-filebeat-123', docCount: 100, sizeInBytes: 10 }, { name: 'logs-endpoint.1234', docCount: 0 }, // Matching pattern with a dot in the name - { name: 'ml_host_risk_score_latest_default', docCount: 0 }, - { name: 'ml_host_risk_score_latest', docCount: 0 }, // This should not match, - { name: 'ml_host_risk_score', docCount: 0 }, // This should not match - { name: 'ml_user_risk_score_latest_default', docCount: 0 }, - { name: 'ml_user_risk_score_latest', docCount: 0 }, // This should not match, - { name: 'ml_user_risk_score', docCount: 0 }, // This should not match // New Indexing strategy: everything can be inferred from the constant_keyword values { name: '.ds-logs-nginx.access-default-000001', From 4b2eee5a385822314555d368ae6c5094c1dc3998 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 4 Dec 2024 14:09:13 +0000 Subject: [PATCH 15/38] fix unit test --- .../security_solution/factory/hosts/all/index.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts index 600c5414b4fbe..3cc85ddc9df29 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/hosts/all/index.test.ts @@ -127,10 +127,10 @@ describe('allHosts search strategy', () => { await allHosts.parse({ ...mockOptions, pagination }, mockSearchStrategyResponse, mockedDeps); expect(buildHostsRiskQuery).toHaveBeenCalledWith({ - defaultIndex: ['ml_host_risk_score_latest_test-space'], + defaultIndex: ['risk-score.risk-score-latest-test-space'], filterQuery: { terms: { 'host.name': [hostName] } }, riskScoreEntity: RiskScoreEntity.host, - factoryQueryType: expect.stringContaining('RiskScore'), + factoryQueryType: 'hostsRiskScore', }); }); From 3be12a38749348e2875df8c1dc84de45e04733cf Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 4 Dec 2024 14:10:46 +0000 Subject: [PATCH 16/38] fix user unit test --- .../security_solution/factory/users/all/index.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts index 4a654a5e86f61..13ca9fba8abf5 100644 --- a/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts +++ b/x-pack/plugins/security_solution/server/search_strategy/security_solution/factory/users/all/index.test.ts @@ -114,10 +114,10 @@ describe('allHosts search strategy', () => { await allUsers.parse({ ...mockOptions, pagination }, mockSearchStrategyResponse, mockedDeps); expect(buildHostsRiskQuery).toHaveBeenCalledWith({ - defaultIndex: ['ml_user_risk_score_latest_test-space'], + defaultIndex: ['risk-score.risk-score-latest-test-space'], filterQuery: { terms: { 'user.name': userName } }, riskScoreEntity: RiskScoreEntity.user, - factoryQueryType: expect.stringContaining('RiskScore'), + factoryQueryType: 'usersRiskScore', }); }); From 2b7c514547ddf0bd3c109925c30b0676c4f12bb6 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 4 Dec 2024 14:29:12 +0000 Subject: [PATCH 17/38] enrichment tests --- .../detection_engine/rule_types/utils/enrichments/index.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts index 415128d1d9f0d..8aca14228d665 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/utils/enrichments/index.test.ts @@ -185,7 +185,6 @@ describe('enrichEvents', () => { // disable risk score enrichments mockIsIndexExist.mockImplementationOnce(() => false); mockIsIndexExist.mockImplementationOnce(() => false); - mockIsIndexExist.mockImplementationOnce(() => false); // enable for asset criticality mockIsIndexExist.mockImplementation(() => true); From 549f7c63c98ac3131a321886d7afcd3720a24484 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Thu, 5 Dec 2024 11:04:53 +0000 Subject: [PATCH 18/38] remove unused types --- .../public/entity_analytics/api/types.ts | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/api/types.ts diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/types.ts b/x-pack/plugins/security_solution/public/entity_analytics/api/types.ts deleted file mode 100644 index 419ebc60c4923..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/types.ts +++ /dev/null @@ -1,20 +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 { HostRiskScore, UserRiskScore } from '../../../common/search_strategy'; - -export interface HostRisk { - loading: boolean; - isModuleEnabled: boolean; - result?: HostRiskScore[]; -} - -export interface UserRisk { - loading: boolean; - isModuleEnabled: boolean; - result?: UserRiskScore[]; -} From 27876041647e6b9d227e13c48e97087cd714caf6 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Thu, 5 Dec 2024 12:57:29 +0000 Subject: [PATCH 19/38] remove more legacy risk engine code, merge user and host enable buttons --- .../alerts/use_check_signal_index.tsx | 85 ------------------- .../api/hooks/use_risk_score.test.tsx | 6 +- .../components/enable_risk_score/index.tsx | 33 ++++--- .../index.test.tsx | 6 +- .../entity_analytics_risk_score/index.tsx | 12 +-- .../risk_details_tab_body/index.test.tsx | 2 +- .../risk_details_tab_body/index.tsx | 9 +- .../risk_score_enable_button.test.tsx | 40 --------- .../components/risk_score_enable_button.tsx | 47 ---------- .../user_risk_score_tab_body.test.tsx | 2 +- .../components/user_risk_score_tab_body.tsx | 7 +- .../navigation/host_risk_score_tab_body.tsx | 7 +- .../components/host_overview/index.test.tsx | 4 +- .../components/user_overview/index.test.tsx | 4 +- .../public/overview/pages/overview.test.tsx | 2 +- .../enable_risk_score_redirect.cy.ts | 20 +---- .../entity_analytics/risk_score.cy.ts | 9 +- .../cypress/screens/entity_analytics.ts | 21 +---- .../cypress/tasks/risk_scores/index.ts | 66 +------------- .../page_objects/entity_analytics_po.ts | 26 ++---- .../tests/enable_risk_score_redirect.spec.ts | 15 +--- 21 files changed, 52 insertions(+), 371 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_check_signal_index.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx delete mode 100644 x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx diff --git a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_check_signal_index.tsx b/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_check_signal_index.tsx deleted file mode 100644 index d8782ec72973c..0000000000000 --- a/x-pack/plugins/security_solution/public/detections/containers/detection_engine/alerts/use_check_signal_index.tsx +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { useEffect, useState } from 'react'; -import { isSecurityAppError } from '@kbn/securitysolution-t-grid'; - -import { useAppToasts } from '../../../../common/hooks/use_app_toasts'; -import { checkSignalIndex } from './api'; -import * as i18n from './translations'; -import { useAlertsPrivileges } from './use_alerts_privileges'; - -interface ReturnSignalIndex { - loading: boolean; - signalIndexExists: boolean | null; - signalIndexName: string | null; - signalIndexMappingOutdated: boolean | null; -} - -/** - * Hook for managing signal index - * - * - */ -export const useCheckSignalIndex = (): ReturnSignalIndex => { - const [loading, setLoading] = useState(true); - const [signalIndex, setSignalIndex] = useState>({ - signalIndexExists: null, - signalIndexName: null, - signalIndexMappingOutdated: null, - }); - const { addError } = useAppToasts(); - const { hasIndexRead } = useAlertsPrivileges(); - - useEffect(() => { - let isSubscribed = true; - const abortCtrl = new AbortController(); - - const fetchData = async () => { - try { - setLoading(true); - const signal = await checkSignalIndex({ signal: abortCtrl.signal }); - - if (isSubscribed && signal != null) { - setSignalIndex({ - signalIndexExists: signal?.indexExists, - signalIndexName: signal.name, - signalIndexMappingOutdated: signal.index_mapping_outdated, - }); - } - } catch (error) { - if (isSubscribed) { - setSignalIndex({ - signalIndexExists: false, - signalIndexName: null, - signalIndexMappingOutdated: null, - }); - if (isSecurityAppError(error) && error.body.status_code !== 404) { - addError(error, { title: i18n.SIGNAL_GET_NAME_FAILURE }); - } - } - } - if (isSubscribed) { - setLoading(false); - } - }; - - if (hasIndexRead) { - fetchData(); - } else { - // Skip data fetching as the current user doesn't have enough priviliges. - // Attempt to get the signal index will result in 500 error. - setLoading(false); - } - return () => { - isSubscribed = false; - abortCtrl.abort(); - }; - }, [addError, hasIndexRead]); - - return { loading, ...signalIndex }; -}; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx index 82cd125d7443d..c28fa72d4d551 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx @@ -32,7 +32,7 @@ const defaultRisk = { inspect: {}, isInspected: false, isAuthorized: true, - isModuleEnabled: true, + hasEngineBeenInstalled: true, isDeprecated: false, totalCount: 0, }; @@ -77,7 +77,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(result.current).toEqual({ loading: false, ...defaultRisk, - isModuleEnabled: false, + hasEngineBeenInstalled: false, refetch: result.current.refetch, }); }); @@ -112,7 +112,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(result.current).toEqual({ loading: false, ...defaultRisk, - isModuleEnabled: false, + hasEngineBeenInstalled: false, refetch: result.current.refetch, error: { attributes: { diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx index a6d3c57b4999b..daab25c76f114 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/enable_risk_score/index.tsx @@ -6,30 +6,22 @@ */ import { EuiEmptyPrompt, EuiPanel, EuiToolTip } from '@elastic/eui'; import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; import type { RiskScoreEntity } from '../../../../common/search_strategy'; -import { useCheckSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_check_signal_index'; -import type { inputsModel } from '../../../common/store'; import { HeaderSection } from '../../../common/components/header_section'; import * as i18n from './translations'; import { EntityAnalyticsLearnMoreLink } from '../entity_analytics_learn_more_link'; import { RiskScoreHeaderTitle } from '../risk_score_header_title'; -import { RiskScoreEnableButton } from '../risk_score_enable_button'; +import { SecuritySolutionLinkButton } from '../../../common/components/links'; +import { SecurityPageName } from '../../../../common/constants'; const EnableRiskScoreComponent = ({ isDisabled, entityType, - refetch, - timerange, }: { isDisabled: boolean; entityType: RiskScoreEntity; - refetch: inputsModel.Refetch; - timerange: { - from: string; - to: string; - }; }) => { - const { signalIndexExists } = useCheckSignalIndex(); if (!isDisabled) { return null; } @@ -47,13 +39,18 @@ const EnableRiskScoreComponent = ({ } actions={ - - + + + + } /> diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx index d398d380f8a5d..47b92c3963e08 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx @@ -54,7 +54,7 @@ const defaultProps = { data: undefined, inspect: null, refetch: () => {}, - isModuleEnabled: true, + hasEngineBeenInstalled: true, isAuthorized: true, loading: false, }; @@ -88,8 +88,8 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( mockUseRiskScore.mockReturnValue(defaultProps); }); - it('renders enable button when module is disable', () => { - mockUseRiskScore.mockReturnValue({ ...defaultProps, isModuleEnabled: false }); + it.only('renders enable button when module is disable', () => { + mockUseRiskScore.mockReturnValue({ ...defaultProps, hasEngineBeenInstalled: false }); const { getByTestId } = render( diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx index f6c48d77fb8c7..53dca5fc47646 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.tsx @@ -21,7 +21,6 @@ import { useGlobalTime } from '../../../common/containers/use_global_time'; import { InspectButtonContainer } from '../../../common/components/inspect'; import { useQueryToggle } from '../../../common/containers/query_toggle'; import { StyledBasicTable } from '../styled_basic_table'; -import { useRefetchQueries } from '../../../common/hooks/use_refetch_queries'; import { Loader } from '../../../common/components/loader'; import { Panel } from '../../../common/components/panel'; import { useEntityInfo } from './use_entity'; @@ -158,8 +157,6 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc setUpdatedAt(Date.now()); }, [isTableLoading, isKpiLoading]); // Update the time when data loads - const refreshPage = useRefetchQueries(); - const privileges = useMissingRiskEnginePrivileges(['read']); if (!isAuthorized) { @@ -177,14 +174,7 @@ const EntityAnalyticsRiskScoresComponent = ({ riskEntity }: { riskEntity: RiskSc } if (isDisabled) { - return ( - - ); + return ; } if (hasEngineBeenInstalled && selectedSeverity.length === 0 && data && data.length === 0) { diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx index c521542f1f7b1..6bebdae715f21 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.test.tsx @@ -47,7 +47,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( isInspected: false, totalCount: 0, refetch: jest.fn(), - isModuleEnabled: true, + hasEngineBeenInstalled: true, }); mockUseQueryToggle.mockReturnValue({ toggleStatus: true, setToggleStatus: jest.fn() }); }); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx index c8256395c337d..38786f0cf1f1d 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_details_tab_body/index.tsx @@ -113,14 +113,7 @@ const RiskDetailsTabBodyComponent: React.FC< }; if (status.isDisabled) { - return ( - - ); + return ; } if (hasEngineBeenInstalled && severitySelectionRedux.length === 0 && data && data.length === 0) { diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx deleted file mode 100644 index f2d42d335611d..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.test.tsx +++ /dev/null @@ -1,40 +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 { render, screen } from '@testing-library/react'; -import React from 'react'; -import { RiskScoreEntity } from '../../../common/search_strategy'; -import { TestProviders } from '../../common/mock'; - -import { RiskScoreEnableButton } from './risk_score_enable_button'; - -describe('RiskScoreEnableButton', () => { - const mockRefetch = jest.fn(); - const timerange = { - from: 'mockStartDate', - to: 'mockEndDate', - }; - beforeEach(() => { - jest.clearAllMocks(); - }); - describe.each([[RiskScoreEntity.host], [RiskScoreEntity.user]])('%s', (riskScoreEntity) => { - it('Renders expected children', () => { - render( - - - - ); - - expect(screen.getByTestId(`enable_${riskScoreEntity}_risk_score`)).toHaveTextContent( - 'Enable' - ); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx deleted file mode 100644 index 20a6b9fb8009d..0000000000000 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_button.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import type { RiskScoreEntity } from '../../../common/search_strategy'; -import type { inputsModel } from '../../common/store'; -import { SecuritySolutionLinkButton } from '../../common/components/links'; -import { SecurityPageName } from '../../../common/constants'; - -const RiskScoreEnableButtonComponent = ({ - refetch, - riskScoreEntity, - disabled = false, - timerange, -}: { - refetch: inputsModel.Refetch; - riskScoreEntity: RiskScoreEntity; - disabled?: boolean; - timerange: { - from: string; - to: string; - }; -}) => { - return ( - <> - - - - - ); -}; - -export const RiskScoreEnableButton = React.memo(RiskScoreEnableButtonComponent); -RiskScoreEnableButton.displayName = 'RiskScoreEnableButton'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx index 3103a8437f384..a8e1c2ac20fbf 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.test.tsx @@ -45,7 +45,7 @@ describe('All users query tab body', () => { isInspected: false, totalCount: 0, refetch: jest.fn(), - isModuleEnabled: true, + hasEngineBeenInstalled: true, }); mockUseRiskScoreKpi.mockReturnValue({ loading: false, diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx index d74966fceacf7..141323f933360 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/user_risk_score_tab_body.tsx @@ -100,12 +100,7 @@ export const UserRiskScoreQueryTabBody = ({ if (isDisabled) { return ( - + ); } diff --git a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx index 9a4e88c89a6ed..59b7d2e18692d 100644 --- a/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx +++ b/x-pack/plugins/security_solution/public/explore/hosts/pages/navigation/host_risk_score_tab_body.tsx @@ -98,12 +98,7 @@ export const HostRiskScoreQueryTabBody = ({ if (isDisabled) { return ( - + ); } diff --git a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx index 11aaa1276cd8d..6cbe1e2710f4e 100644 --- a/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/host_overview/index.test.tsx @@ -19,7 +19,7 @@ const defaultProps = { data: undefined, inspect: null, refetch: () => {}, - isModuleEnabled: true, + hasEngineBeenInstalled: true, isAuthorized: true, loading: true, }; @@ -46,7 +46,7 @@ describe('Host Summary Component', () => { beforeEach(() => { jest.clearAllMocks(); - mockUseRiskScore.mockReturnValue({ ...defaultProps, isModuleEnabled: false }); + mockUseRiskScore.mockReturnValue({ ...defaultProps, hasEngineBeenInstalled: false }); }); test('it renders the default Host Summary', () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx index 22c682306e12c..ac088b559d5bc 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx @@ -19,7 +19,7 @@ const defaultProps = { data: undefined, inspect: null, refetch: () => {}, - isModuleEnabled: true, + hasEngineBeenInstalled: true, isAuthorized: true, loading: false, }; @@ -59,7 +59,7 @@ describe('User Summary Component', () => { beforeEach(() => { jest.clearAllMocks(); - mockRiskScore.mockReturnValue({ ...defaultProps, loading: true, isModuleEnabled: false }); + mockRiskScore.mockReturnValue({ ...defaultProps, loading: true, hasEngineBeenInstalled: false }); }); test('it renders the default User Summary', () => { diff --git a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx index d998aed2de955..61d59eb2189de 100644 --- a/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/pages/overview.test.tsx @@ -98,7 +98,7 @@ useAllTiDataSourcesMock.mockReturnValue(mockTiDataSources); jest.mock('../../entity_analytics/api/hooks/use_risk_score'); const useRiskScoreMock = useRiskScore as jest.Mock; -useRiskScoreMock.mockReturnValue({ loading: false, data: [], isModuleEnabled: false }); +useRiskScoreMock.mockReturnValue({ loading: false, data: [], hasEngineBeenInstalled: false }); jest.mock('../../common/hooks/use_experimental_features'); const useIsExperimentalFeatureEnabledMock = useIsExperimentalFeatureEnabled as jest.Mock; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts index 5ffffadc798f4..40d5623f114fd 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts @@ -5,15 +5,11 @@ * 2.0. */ -import { - ENABLE_HOST_RISK_SCORE_BUTTON, - ENABLE_USER_RISK_SCORE_BUTTON, -} from '../../../screens/entity_analytics'; +import { ENABLE_RISK_SCORE_BUTTON } from '../../../screens/entity_analytics'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; import { clickEnableRiskScore } from '../../../tasks/risk_scores'; -import { RiskScoreEntity } from '../../../tasks/risk_scores/common'; import { ENTITY_ANALYTICS_URL } from '../../../urls/navigation'; import { PAGE_TITLE } from '../../../screens/entity_analytics_management'; @@ -36,18 +32,10 @@ describe( visit(ENTITY_ANALYTICS_URL); }); - it('host risk enable button should redirect to entity management page', () => { - cy.get(ENABLE_HOST_RISK_SCORE_BUTTON).should('exist'); + it('risk enable button should redirect to entity management page', () => { + cy.get(ENABLE_RISK_SCORE_BUTTON).should('exist'); - clickEnableRiskScore(RiskScoreEntity.host); - - cy.get(PAGE_TITLE).should('have.text', 'Entity Risk Score'); - }); - - it('user risk enable button should redirect to entity management page', () => { - cy.get(ENABLE_USER_RISK_SCORE_BUTTON).should('exist'); - - clickEnableRiskScore(RiskScoreEntity.user); + clickEnableRiskScore(); cy.get(PAGE_TITLE).should('have.text', 'Entity Risk Score'); }); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/risk_score.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/risk_score.cy.ts index 049efd116492e..3e0971c7e8454 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/risk_score.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/entity_analytics/risk_score.cy.ts @@ -14,8 +14,7 @@ import { ALERTS_URL, ENTITY_ANALYTICS_URL } from '../../../../urls/navigation'; import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { - ENABLE_HOST_RISK_SCORE_BUTTON, - ENABLE_USER_RISK_SCORE_BUTTON, + ENABLE_RISK_SCORE_BUTTON, HOSTS_DONUT_CHART, HOSTS_TABLE_ROWS, HOST_RISK_SCORE_NO_DATA_DETECTED, @@ -73,10 +72,8 @@ describe.skip('Entity Analytics Dashboard', { tags: ['@ess', '@serverless'] }, ( visitWithTimeRange(ENTITY_ANALYTICS_URL); }); - it('shows enable host and user risk button', () => { - cy.get(ENABLE_HOST_RISK_SCORE_BUTTON).should('be.visible'); - - cy.get(ENABLE_USER_RISK_SCORE_BUTTON).should('be.visible'); + it('shows enable risk button', () => { + cy.get(ENABLE_RISK_SCORE_BUTTON).should('be.visible'); }); }); diff --git a/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics.ts b/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics.ts index dccef9c6cfccd..4dfe3c3c74d4d 100644 --- a/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics.ts +++ b/x-pack/test/security_solution_cypress/cypress/screens/entity_analytics.ts @@ -7,24 +7,12 @@ import type { RiskScoreEntity } from '../tasks/risk_scores/common'; -export const ENABLE_HOST_RISK_SCORE_BUTTON = '[data-test-subj="enable_host_risk_score"]'; - -export const UPGRADE_HOST_RISK_SCORE_BUTTON = '[data-test-subj="host-risk-score-upgrade"]'; - -export const UPGRADE_USER_RISK_SCORE_BUTTON = '[data-test-subj="user-risk-score-upgrade"]'; - -export const UPGRADE_RISK_SCORE_BUTTON = '[data-test-subj="update-risk-score-button"]'; - export const HOST_RISK_SCORE_NO_DATA_DETECTED = '[data-test-subj="host-risk-score-no-data-detected"]'; export const USER_RISK_SCORE_NO_DATA_DETECTED = '[data-test-subj="user-risk-score-no-data-detected"]'; -export const RISK_SCORE_DASHBOARDS_INSTALLATION_SUCCESS_TOAST = ( - riskScoreEntity: RiskScoreEntity -) => `[data-test-subj="${riskScoreEntity}RiskScoreDashboardsSuccessToast"]`; - export const RISK_SCORE_INSTALLATION_SUCCESS_TOAST = (riskScoreEntity: RiskScoreEntity) => `[data-test-subj="${riskScoreEntity}EnableSuccessToast"]`; @@ -42,7 +30,7 @@ export const USERS_TABLE_ROWS = '[data-test-subj="entity_analytics_users"] .euiT export const USERS_TABLE = '[data-test-subj="entity_analytics_users"] #userRiskDashboardTable'; -export const ENABLE_USER_RISK_SCORE_BUTTON = '[data-test-subj="enable_user_risk_score"]'; +export const ENABLE_RISK_SCORE_BUTTON = '[data-test-subj="enable_risk_score"]'; export const ANOMALIES_TABLE = '[data-test-subj="entity_analytics_anomalies"] #entityAnalyticsDashboardAnomaliesTable'; @@ -58,13 +46,6 @@ export const ANOMALIES_TABLE_COUNT_COLUMN = '[data-test-subj="anomalies-table-co export const ANOMALIES_TABLE_NEXT_PAGE_BUTTON = '[data-test-subj="entity_analytics_anomalies"] [data-test-subj="pagination-button-next"]'; -export const UPGRADE_CONFIRMATION_MODAL = (riskScoreEntity: RiskScoreEntity) => - `[data-test-subj="${riskScoreEntity}-risk-score-upgrade-confirmation-modal"]`; - -export const UPGRADE_CONFIRMATION_BUTTON = '[data-test-subj="confirmModalConfirmButton"]'; - -export const UPGRADE_CANCELLATION_BUTTON = '[data-test-subj="confirmModalCancelButton"]'; - export const USERS_TABLE_ALERT_CELL = '[data-test-subj="entity_analytics_users"] [data-test-subj="risk-score-alerts"]'; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/index.ts b/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/index.ts index 6634eab16ec79..73138b420f0c0 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/index.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/index.ts @@ -6,74 +6,12 @@ */ import { - ENABLE_HOST_RISK_SCORE_BUTTON, - ENABLE_USER_RISK_SCORE_BUTTON, + ENABLE_RISK_SCORE_BUTTON, HOSTS_TABLE_ALERT_CELL, - UPGRADE_CONFIRMATION_BUTTON, - UPGRADE_RISK_SCORE_BUTTON, USERS_TABLE_ALERT_CELL, } from '../../screens/entity_analytics'; -import { - INGEST_PIPELINES_URL, - RISK_SCORE_SAVED_OBJECTS_URL, - STORED_SCRIPTS_URL, - TRANSFORMS_URL, -} from '../../urls/risk_score'; -import { interceptInstallRiskScoreModule } from '../api_calls/risk_scores'; - -import { RiskScoreEntity } from './common'; -import { getIngestPipelineName, getLegacyIngestPipelineName } from './ingest_pipelines'; - -export const interceptUpgradeRiskScoreModule = ( - riskScoreEntity: RiskScoreEntity, - version?: '8.3' | '8.4' -) => { - const ingestPipelinesNames = `${getLegacyIngestPipelineName( - riskScoreEntity - )},${getIngestPipelineName(riskScoreEntity)}`; - cy.intercept( - `POST`, - `${RISK_SCORE_SAVED_OBJECTS_URL}/_bulk_delete/${riskScoreEntity}RiskScoreDashboards` - ).as('deleteDashboards'); - cy.intercept(`POST`, `${TRANSFORMS_URL}/stop_transforms`).as('stopTransforms'); - cy.intercept(`POST`, `${TRANSFORMS_URL}/delete_transforms`).as('deleteTransforms'); - cy.intercept(`DELETE`, `${INGEST_PIPELINES_URL}/${ingestPipelinesNames}`).as( - 'deleteIngestPipelines' - ); - cy.intercept(`DELETE`, `${STORED_SCRIPTS_URL}/delete`).as('deleteScripts'); - interceptInstallRiskScoreModule(); -}; - -export const waitForUpgradeRiskScoreModule = () => { - cy.wait( - [ - '@deleteDashboards', - '@stopTransforms', - '@deleteTransforms', - '@deleteIngestPipelines', - '@deleteScripts', - '@install', - ], - { requestTimeout: 50000 } - ); -}; -export const clickEnableRiskScore = (riskScoreEntity: RiskScoreEntity) => { - const button = - riskScoreEntity === RiskScoreEntity.user - ? ENABLE_USER_RISK_SCORE_BUTTON - : ENABLE_HOST_RISK_SCORE_BUTTON; - - cy.get(button).click(); -}; - -export const clickUpgradeRiskScore = () => { - cy.get(UPGRADE_RISK_SCORE_BUTTON).click(); -}; - -export const clickUpgradeRiskScoreConfirmed = () => { - cy.get(UPGRADE_CONFIRMATION_BUTTON).click(); -}; +export const clickEnableRiskScore = () => cy.get(ENABLE_RISK_SCORE_BUTTON).click(); export const clickOnFirstUsersAlerts = () => { cy.get(USERS_TABLE_ALERT_CELL).first().click(); diff --git a/x-pack/test/security_solution_playwright/page_objects/entity_analytics_po.ts b/x-pack/test/security_solution_playwright/page_objects/entity_analytics_po.ts index 36e8a603ecd9a..e802e63925ebf 100644 --- a/x-pack/test/security_solution_playwright/page_objects/entity_analytics_po.ts +++ b/x-pack/test/security_solution_playwright/page_objects/entity_analytics_po.ts @@ -10,42 +10,30 @@ import { EntityAnalyticsManagementPage } from './entity_analytics_management_po' import { PageFactory } from './page_factory'; const PAGE_URL = '/app/security/entity_analytics'; -const ENABLE_HOST_RISK_SCORE_BUTTON = '[data-test-subj="enable_host_risk_score"]'; -const ENABLE_USER_RISK_SCORE_BUTTON = '[data-test-subj="enable_user_risk_score"]'; +const ENABLE_RISK_ENGINE_BUTTON = '[data-test-subj="enable_risk_score"]'; export class EntityAnalyticsPage { page: Page; - enableHostRiskScoreBtn!: Locator; - enableUserRiskScoreBtn!: Locator; + enableRiskEngineBtn!: Locator; constructor(page: Page) { this.page = page; } async initialize() { - this.enableHostRiskScoreBtn = this.page.locator(ENABLE_HOST_RISK_SCORE_BUTTON); - this.enableUserRiskScoreBtn = this.page.locator(ENABLE_USER_RISK_SCORE_BUTTON); + this.enableRiskEngineBtn = this.page.locator(ENABLE_RISK_ENGINE_BUTTON); } async navigates() { await this.page.goto(PAGE_URL); } - async enableHostRisk(): Promise { - await this.enableHostRiskScoreBtn.click(); + async enableRiskEngine(): Promise { + await this.enableRiskEngineBtn.click(); return await PageFactory.createEntityAnalyticsManagementPage(this.page); } - async enableUserRisk(): Promise { - await this.enableUserRiskScoreBtn.click(); - return await PageFactory.createEntityAnalyticsManagementPage(this.page); - } - - async waitForEnableHostRiskScoreToBePresent() { - await expect(this.enableHostRiskScoreBtn).toBeVisible(); - } - - async waitForEnableUserRiskScoreToBePresent() { - await expect(this.enableUserRiskScoreBtn).toBeVisible(); + async waitForEnableRiskEngineToBePresent() { + await expect(this.enableRiskEngineBtn).toBeVisible(); } } diff --git a/x-pack/test/security_solution_playwright/tests/enable_risk_score_redirect.spec.ts b/x-pack/test/security_solution_playwright/tests/enable_risk_score_redirect.spec.ts index 79222975ed121..d6564fa8d8bf6 100644 --- a/x-pack/test/security_solution_playwright/tests/enable_risk_score_redirect.spec.ts +++ b/x-pack/test/security_solution_playwright/tests/enable_risk_score_redirect.spec.ts @@ -25,18 +25,9 @@ test.describe('Enable risk scores from dashboard', { tag: ['@serverless', '@ess' entityAnalyticsPage = await PageFactory.createEntityAnalyticsPage(page); await entityAnalyticsPage.navigates(); }); - test('host risk enable button should redirect to entity management page', async () => { - await entityAnalyticsPage.waitForEnableHostRiskScoreToBePresent(); - entityAnalyticsManagementPage = await entityAnalyticsPage.enableHostRisk(); - - await expect(entityAnalyticsManagementPage.entityAnalyticsManagementPageTitle).toHaveText( - 'Entity Risk Score' - ); - }); - - test('user risk enable button should redirect to entity management page', async () => { - await entityAnalyticsPage.waitForEnableUserRiskScoreToBePresent(); - entityAnalyticsManagementPage = await entityAnalyticsPage.enableUserRisk(); + test('risk enable button should redirect to entity management page', async () => { + await entityAnalyticsPage.waitForEnableRiskEngineToBePresent(); + entityAnalyticsManagementPage = await entityAnalyticsPage.enableRiskEngine(); await expect(entityAnalyticsManagementPage.entityAnalyticsManagementPageTitle).toHaveText( 'Entity Risk Score' From 45497d315a0ddc293d5ca79993f98453cfcd76ee Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Thu, 5 Dec 2024 13:08:56 +0000 Subject: [PATCH 20/38] fix enable button tests --- .../components/entity_analytics_risk_score/index.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx index 47b92c3963e08..55ffd9a75df4c 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_analytics_risk_score/index.test.tsx @@ -88,7 +88,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( mockUseRiskScore.mockReturnValue(defaultProps); }); - it.only('renders enable button when module is disable', () => { + it('renders enable button when module is disable', () => { mockUseRiskScore.mockReturnValue({ ...defaultProps, hasEngineBeenInstalled: false }); const { getByTestId } = render( @@ -96,7 +96,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( ); - expect(getByTestId(`enable_${riskEntity}_risk_score`)).toBeInTheDocument(); + expect(getByTestId(`enable_risk_score`)).toBeInTheDocument(); }); it("doesn't render enable button when module is enable", () => { @@ -106,7 +106,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( ); - expect(queryByTestId(`enable_${riskEntity}_risk_score`)).not.toBeInTheDocument(); + expect(queryByTestId(`enable_risk_score`)).not.toBeInTheDocument(); }); it('queries when toggleStatus is true', () => { From 03ebb66e7bf35fe58576f9003ed5a61b27157a12 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:56:26 +0000 Subject: [PATCH 21/38] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- .../public/overview/components/user_overview/index.test.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx index ac088b559d5bc..87a62b6853cde 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx @@ -59,7 +59,11 @@ describe('User Summary Component', () => { beforeEach(() => { jest.clearAllMocks(); - mockRiskScore.mockReturnValue({ ...defaultProps, loading: true, hasEngineBeenInstalled: false }); + mockRiskScore.mockReturnValue({ + ...defaultProps, + loading: true, + hasEngineBeenInstalled: false, + }); }); test('it renders the default User Summary', () => { From 37813198e6d2c100a3c4470a5779c15a73b1df47 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Thu, 5 Dec 2024 14:41:23 +0000 Subject: [PATCH 22/38] lint --- .../public/overview/components/user_overview/index.test.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx index ac088b559d5bc..87a62b6853cde 100644 --- a/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/user_overview/index.test.tsx @@ -59,7 +59,11 @@ describe('User Summary Component', () => { beforeEach(() => { jest.clearAllMocks(); - mockRiskScore.mockReturnValue({ ...defaultProps, loading: true, hasEngineBeenInstalled: false }); + mockRiskScore.mockReturnValue({ + ...defaultProps, + loading: true, + hasEngineBeenInstalled: false, + }); }); test('it renders the default User Summary', () => { From b1d2cd56ddc91ecfefcc2bb44c95e2a90a099ab8 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 6 Dec 2024 13:53:10 +0000 Subject: [PATCH 23/38] telemetry test --- .../get_data_telemetry/get_data_telemetry.test.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts index e0dfeb1475313..24c49cf2be4d7 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts @@ -193,16 +193,6 @@ describe('get_data_telemetry', () => { index_count: 1, doc_count: 0, }, - { - pattern_name: 'host_risk_score', - index_count: 1, - doc_count: 0, - }, - { - pattern_name: 'user_risk_score', - index_count: 1, - doc_count: 0, - }, { data_stream: { dataset: 'nginx.access', type: 'logs' }, shipper: 'filebeat', From f2582cc2792481e2afe965bd4a63d4a0f37e39d9 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 6 Dec 2024 13:53:41 +0000 Subject: [PATCH 24/38] risk score donut snapshot --- .../__snapshots__/risk_score_donut.test.ts.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_donut.test.ts.snap b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_donut.test.ts.snap index a5f31e844b5c4..bdc76c34f4f98 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_donut.test.ts.snap +++ b/x-pack/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_donut.test.ts.snap @@ -11,11 +11,11 @@ Object { "fieldAttrs": Object {}, "fieldFormats": Object {}, "id": "d594baeb-5eca-480c-8885-ba79eaf41372", - "name": "ml_host_risk_score_latest_mockSpaceId_no_timestamp", + "name": "ea_host_risk_score_latest_mockSpaceId_no_timestamp", "runtimeFieldMap": Object {}, "sourceFilters": Array [], "timeFieldName": "", - "title": "ml_host_risk_score_latest_mockSpaceId", + "title": "ea_host_risk_score_latest_mockSpaceId", }, }, "datasourceStates": Object { From c9b19ea97430d602a14206c3dde42d7547ee0656 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 6 Dec 2024 17:08:39 +0000 Subject: [PATCH 25/38] use_risk_score tests --- .../api/hooks/use_risk_score.test.tsx | 92 +++++++++++-------- .../api/hooks/use_risk_score.tsx | 4 +- 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx index c28fa72d4d551..04ae828df913f 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.test.tsx @@ -11,6 +11,17 @@ import { useSearchStrategy } from '../../../common/containers/use_search_strateg import { useAppToasts } from '../../../common/hooks/use_app_toasts'; import { useAppToastsMock } from '../../../common/hooks/use_app_toasts.mock'; import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { useRiskEngineStatus } from './use_risk_engine_status'; +import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities'; +import type { RiskEngineStatusResponse } from '../../../../common/api/entity_analytics'; +jest.mock('../../../common/components/ml/hooks/use_ml_capabilities', () => ({ + useMlCapabilities: jest.fn(), +})); + +jest.mock('../../../helper_hooks', () => ({ + useHasSecurityCapability: jest.fn().mockReturnValue(true), +})); + jest.mock('../../../common/containers/use_search_strategy', () => ({ useSearchStrategy: jest.fn(), })); @@ -20,22 +31,27 @@ jest.mock('../../../common/hooks/use_space_id', () => ({ })); jest.mock('../../../common/hooks/use_app_toasts'); -jest.mock('./use_risk_engine_status'); +jest.mock('./use_risk_engine_status', () => ({ + useRiskEngineStatus: jest.fn(), +})); +const mockUseMlCapabilities = useMlCapabilities as jest.Mock; const mockUseSearchStrategy = useSearchStrategy as jest.Mock; +const mockUseRiskEngineStatus = useRiskEngineStatus as jest.Mock; const mockSearch = jest.fn(); let appToastsMock: jest.Mocked>; const defaultRisk = { data: undefined, + error: undefined, inspect: {}, isInspected: false, isAuthorized: true, - hasEngineBeenInstalled: true, - isDeprecated: false, + hasEngineBeenInstalled: false, totalCount: 0, }; + const defaultSearchResponse = { loading: false, result: { @@ -47,6 +63,25 @@ const defaultSearchResponse = { inspect: {}, error: undefined, }; + +const makeLicenseInvalid = () => { + mockUseMlCapabilities.mockClear(); + mockUseMlCapabilities.mockReturnValue({ + isPlatinumOrTrialLicense: false, + }); +}; + +const mockRiskEngineStatus = (status: RiskEngineStatusResponse['risk_engine_status']) => { + mockUseRiskEngineStatus.mockClear(); + mockUseRiskEngineStatus.mockReturnValue({ + data: { + risk_engine_status: status, + risk_engine_task_status: { status: 'idle', runAt: '2021-09-29T15:00:00Z' }, + } as RiskEngineStatusResponse, + isLoading: false, + isFetching: false, + }); +}; describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( 'useRiskScore entityType: %s', (riskEntity) => { @@ -55,9 +90,15 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( appToastsMock = useAppToastsMock.create(); (useAppToasts as jest.Mock).mockReturnValue(appToastsMock); mockUseSearchStrategy.mockReturnValue(defaultSearchResponse); + mockUseMlCapabilities.mockReturnValue({ + isPlatinumOrTrialLicense: true, + }); }); test('does not search if license is not valid', () => { + makeLicenseInvalid(); + mockRiskEngineStatus('ENABLED'); + const { result } = renderHook(() => useRiskScore({ riskEntity }), { wrapper: TestProviders, }); @@ -65,11 +106,13 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(result.current).toEqual({ loading: false, ...defaultRisk, + hasEngineBeenInstalled: true, isAuthorized: false, refetch: result.current.refetch, }); }); - test('does not search if feature is not enabled', () => { + test('does not search if engine is not installed', () => { + mockRiskEngineStatus('NOT_INSTALLED'); const { result } = renderHook(() => useRiskScore({ riskEntity }), { wrapper: TestProviders, }); @@ -77,25 +120,12 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(result.current).toEqual({ loading: false, ...defaultRisk, - hasEngineBeenInstalled: false, - refetch: result.current.refetch, - }); - }); - - test('does not search if index is deprecated ', () => { - const { result } = renderHook(() => useRiskScore({ riskEntity, skip: true }), { - wrapper: TestProviders, - }); - expect(mockSearch).not.toHaveBeenCalled(); - expect(result.current).toEqual({ - loading: false, - ...defaultRisk, - isDeprecated: true, refetch: result.current.refetch, }); }); test('handle index not found error', () => { + mockRiskEngineStatus('ENABLED'); mockUseSearchStrategy.mockReturnValue({ ...defaultSearchResponse, error: { @@ -112,7 +142,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(result.current).toEqual({ loading: false, ...defaultRisk, - hasEngineBeenInstalled: false, + hasEngineBeenInstalled: true, refetch: result.current.refetch, error: { attributes: { @@ -125,6 +155,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( }); test('show error toast', () => { + mockRiskEngineStatus('ENABLED'); const error = new Error(); mockUseSearchStrategy.mockReturnValue({ ...defaultSearchResponse, @@ -138,35 +169,23 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( }); }); - test('runs search if feature is enabled and not deprecated', () => { + test('runs search if engine is enabled', () => { + mockRiskEngineStatus('ENABLED'); renderHook(() => useRiskScore({ riskEntity }), { wrapper: TestProviders, }); - expect(mockSearch).toHaveBeenCalledTimes(1); expect(mockSearch).toHaveBeenCalledWith({ - defaultIndex: [`ml_${riskEntity}_risk_score_latest_default`], + defaultIndex: [`risk-score.risk-score-latest-default`], factoryQueryType: `${riskEntity}sRiskScore`, riskScoreEntity: riskEntity, includeAlertsCount: false, }); }); - test('runs search with new index if feature is enabled and not deprecated and new module installed', () => { - renderHook(() => useRiskScore({ riskEntity }), { - wrapper: TestProviders, - }); - - expect(mockSearch).toHaveBeenCalledTimes(1); - expect(mockSearch).toHaveBeenCalledWith({ - defaultIndex: ['risk-score.risk-score-latest-default'], - factoryQueryType: `${riskEntity}sRiskScore`, - riskScoreEntity: riskEntity, - includeAlertsCount: false, - }); - }); + test('returns result', async () => { + mockRiskEngineStatus('ENABLED'); - test('return result', async () => { mockUseSearchStrategy.mockReturnValue({ ...defaultSearchResponse, result: { @@ -181,6 +200,7 @@ describe.each([RiskScoreEntity.host, RiskScoreEntity.user])( expect(result.current).toEqual({ loading: false, ...defaultRisk, + hasEngineBeenInstalled: true, data: [], refetch: result.current.refetch, }); diff --git a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx index f34aad9064567..6f3d39f8a7d88 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/api/hooks/use_risk_score.tsx @@ -179,10 +179,10 @@ export const useRiskScore = { - if (!skip && riskScoreRequest != null && isAuthorized) { + if (!skip && riskScoreRequest != null && isAuthorized && hasEngineBeenInstalled) { search(riskScoreRequest); } - }, [isAuthorized, riskScoreRequest, search, skip]); + }, [hasEngineBeenInstalled, isAuthorized, riskScoreRequest, search, skip]); const result = { ...riskScoreResponse, loading: loading || isStatusLoading }; From bcedb0acf7da818fa2483d0a3ac7c57ba2eca903 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 6 Dec 2024 17:08:55 +0000 Subject: [PATCH 26/38] remove legacy risk score enrichment test --- .../custom_query.ts | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/query/trial_license_complete_tier/custom_query.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/query/trial_license_complete_tier/custom_query.ts index 5828a29eccb54..09887716041d0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/query/trial_license_complete_tier/custom_query.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/query/trial_license_complete_tier/custom_query.ts @@ -1482,62 +1482,6 @@ export default ({ getService }: FtrProviderContext) => { expect(logEntry.errors.length).toEqual(0); } }); - - describe('with host risk index', () => { - before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/entity/host_risk'); - }); - - after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/entity/host_risk'); - }); - - it('should be enriched with host risk score', async () => { - const rule: QueryRuleCreateProps = { - ...getRuleForAlertTesting(['suppression-data']), - query: `host.name: "host-0"`, - alert_suppression: { - group_by: ['host.name'], - duration: { - value: 30, - unit: 'm', - }, - }, - from: 'now-1h', - interval: '1h', - }; - - const { previewId } = await previewRule({ - supertest, - rule, - timeframeEnd: new Date('2020-10-28T06:30:00.000Z'), - invocationCount: 1, - }); - const previewAlerts = await getPreviewAlerts({ - es, - previewId, - sort: [ALERT_ORIGINAL_TIME], - }); - expect(previewAlerts.length).toEqual(1); - expect(previewAlerts[0]._source).toEqual({ - ...previewAlerts[0]._source, - [ALERT_SUPPRESSION_TERMS]: [ - { - field: 'host.name', - value: 'host-0', - }, - ], - [TIMESTAMP]: '2020-10-28T06:30:00.000Z', - [ALERT_LAST_DETECTED]: '2020-10-28T06:30:00.000Z', - [ALERT_ORIGINAL_TIME]: '2020-10-28T06:00:00.000Z', - [ALERT_SUPPRESSION_START]: '2020-10-28T06:00:00.000Z', - [ALERT_SUPPRESSION_END]: '2020-10-28T06:00:02.000Z', - [ALERT_SUPPRESSION_DOCS_COUNT]: 5, - }); - expect(previewAlerts[0]._source?.host?.risk?.calculated_level).toEqual('Low'); - expect(previewAlerts[0]._source?.host?.risk?.calculated_score_norm).toEqual(1); - }); - }); }); // when missing_fields_strategy set to "doNotSuppress", each document with missing grouped by field From f76576d94855a1ee776d249a113a15c4cd5c194d Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 9 Dec 2024 10:36:22 +0000 Subject: [PATCH 27/38] legacy data cypress tests --- .../cypress/e2e/entity_analytics/enrichments.cy.ts | 5 ----- .../cypress/e2e/explore/users/users_tabs.cy.ts | 8 +++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts index fe10f84608167..bbbd46cb5fb1c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts @@ -38,11 +38,6 @@ describe.skip('Enrichment', { tags: ['@ess'] }, () => { before(() => { cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_updated' }); - cy.task('esArchiverLoad', { archiveName: 'risk_users' }); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_users' }); }); describe('Custom query rule', () => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/users/users_tabs.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/users/users_tabs.cy.ts index 1a563156415ab..d7c14137922c5 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/users/users_tabs.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/users/users_tabs.cy.ts @@ -12,19 +12,18 @@ import { AUTHENTICATIONS_TABLE, } from '../../../screens/users/user_authentications'; import { EVENTS_TAB, EVENTS_TAB_CONTENT } from '../../../screens/users/user_events'; -import { RISK_SCORE_TAB, RISK_SCORE_TAB_CONTENT } from '../../../screens/users/user_risk_score'; +import { RISK_SCORE_TAB } from '../../../screens/users/user_risk_score'; import { login } from '../../../tasks/login'; import { visitUserDetailsPage, visitWithTimeRange } from '../../../tasks/navigation'; import { usersUrl } from '../../../urls/navigation'; import { waitForTabToBeLoaded } from '../../../tasks/common'; +import { ENABLE_RISK_SCORE_BUTTON } from '../../../screens/entity_analytics'; describe('Users stats and tables', { tags: ['@ess', '@serverless'] }, () => { before(() => { cy.task('esArchiverLoad', { archiveName: 'users' }); - - cy.task('esArchiverLoad', { archiveName: 'risk_users' }); }); beforeEach(() => { @@ -34,7 +33,6 @@ describe('Users stats and tables', { tags: ['@ess', '@serverless'] }, () => { after(() => { cy.task('esArchiverUnload', { archiveName: 'users' }); - cy.task('esArchiverUnload', { archiveName: 'risk_users' }); }); describe('Users page tabs', () => { @@ -72,7 +70,7 @@ describe('Users stats and tables', { tags: ['@ess', '@serverless'] }, () => { it(`renders users risk tab`, { tags: ['@skipInServerless'] }, () => { waitForTabToBeLoaded(RISK_SCORE_TAB); - cy.get(RISK_SCORE_TAB_CONTENT).should('exist'); + cy.get(ENABLE_RISK_SCORE_BUTTON).should('exist'); }); }); From 4e20fdde6a416228aa793d596a0256a16d8c3263 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 9 Dec 2024 12:04:46 +0000 Subject: [PATCH 28/38] remove unused snapshot --- .../risk_score_modules.test.ts.snap | 736 ------------------ 1 file changed, 736 deletions(-) delete mode 100644 x-pack/plugins/security_solution/common/utils/__snapshots__/risk_score_modules.test.ts.snap diff --git a/x-pack/plugins/security_solution/common/utils/__snapshots__/risk_score_modules.test.ts.snap b/x-pack/plugins/security_solution/common/utils/__snapshots__/risk_score_modules.test.ts.snap deleted file mode 100644 index 86b80dbe0113f..0000000000000 --- a/x-pack/plugins/security_solution/common/utils/__snapshots__/risk_score_modules.test.ts.snap +++ /dev/null @@ -1,736 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Risk Score Modules getCreateLatestTransformOptions - host 1`] = ` -Object { - "dest": Object { - "index": "ml_host_risk_score_latest_customSpaceId", - }, - "frequency": "1h", - "latest": Object { - "sort": "@timestamp", - "unique_key": Array [ - "host.name", - ], - }, - "source": Object { - "index": Array [ - "ml_host_risk_score_customSpaceId", - ], - }, - "sync": Object { - "time": Object { - "delay": "2s", - "field": "ingest_timestamp", - }, - }, -} -`; - -exports[`Risk Score Modules getCreateLatestTransformOptions - user 1`] = ` -Object { - "dest": Object { - "index": "ml_user_risk_score_latest_customSpaceId", - }, - "frequency": "1h", - "latest": Object { - "sort": "@timestamp", - "unique_key": Array [ - "user.name", - ], - }, - "source": Object { - "index": Array [ - "ml_user_risk_score_customSpaceId", - ], - }, - "sync": Object { - "time": Object { - "delay": "2s", - "field": "ingest_timestamp", - }, - }, -} -`; - -exports[`Risk Score Modules getCreateMLHostPivotTransformOptions 1`] = ` -Object { - "dest": Object { - "index": "ml_host_risk_score_customSpaceId", - "pipeline": "ml_hostriskscore_ingest_pipeline_customSpaceId", - }, - "frequency": "1h", - "pivot": Object { - "aggregations": Object { - "@timestamp": Object { - "max": Object { - "field": "@timestamp", - }, - }, - "host.risk": Object { - "scripted_metric": Object { - "combine_script": "return state", - "init_script": Object { - "id": "ml_hostriskscore_init_script_customSpaceId", - }, - "map_script": Object { - "id": "ml_hostriskscore_map_script_customSpaceId", - }, - "params": Object { - "lookback_time": 72, - "max_risk": 100, - "p": 1.5, - "server_multiplier": 1.5, - "tactic_base_multiplier": 0.25, - "tactic_weights": Object { - "TA0001": 1, - "TA0002": 2, - "TA0003": 3, - "TA0004": 4, - "TA0005": 4, - "TA0006": 4, - "TA0007": 4, - "TA0008": 5, - "TA0009": 6, - "TA0010": 7, - "TA0011": 6, - "TA0040": 8, - "TA0042": 1, - "TA0043": 1, - }, - "time_decay_constant": 6, - "zeta_constant": 2.612, - }, - "reduce_script": Object { - "id": "ml_hostriskscore_reduce_script_customSpaceId", - }, - }, - }, - }, - "group_by": Object { - "host.name": Object { - "terms": Object { - "field": "host.name", - }, - }, - }, - }, - "source": Object { - "index": Array [ - ".alerts-security.alerts-customSpaceId", - ], - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "range": Object { - "@timestamp": Object { - "gte": "now-5d", - }, - }, - }, - ], - }, - }, - }, - "sync": Object { - "time": Object { - "delay": "120s", - "field": "@timestamp", - }, - }, -} -`; - -exports[`Risk Score Modules getCreateMLUserPivotTransformOptions 1`] = ` -Object { - "dest": Object { - "index": "ml_user_risk_score_customSpaceId", - "pipeline": "ml_userriskscore_ingest_pipeline_customSpaceId", - }, - "frequency": "1h", - "pivot": Object { - "aggregations": Object { - "@timestamp": Object { - "max": Object { - "field": "@timestamp", - }, - }, - "user.risk": Object { - "scripted_metric": Object { - "combine_script": "return state", - "init_script": "state.rule_risk_stats = new HashMap();", - "map_script": Object { - "id": "ml_userriskscore_map_script_customSpaceId", - }, - "params": Object { - "max_risk": 100, - "p": 1.5, - "zeta_constant": 2.612, - }, - "reduce_script": Object { - "id": "ml_userriskscore_reduce_script_customSpaceId", - }, - }, - }, - }, - "group_by": Object { - "user.name": Object { - "terms": Object { - "field": "user.name", - }, - }, - }, - }, - "source": Object { - "index": Array [ - ".alerts-security.alerts-customSpaceId", - ], - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "range": Object { - "@timestamp": Object { - "gte": "now-90d", - }, - }, - }, - Object { - "match": Object { - "signal.status": "open", - }, - }, - ], - }, - }, - }, - "sync": Object { - "time": Object { - "delay": "120s", - "field": "@timestamp", - }, - }, -} -`; - -exports[`Risk Score Modules getCreateRiskScoreIndicesOptions - host 1`] = ` -Object { - "index": "ml_host_risk_score_customSpaceId", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "host": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - "ingest_timestamp": Object { - "type": "date", - }, - }, - }, -} -`; - -exports[`Risk Score Modules getCreateRiskScoreIndicesOptions - user 1`] = ` -Object { - "index": "ml_user_risk_score_customSpaceId", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "ingest_timestamp": Object { - "type": "date", - }, - "user": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - }, - }, -} -`; - -exports[`Risk Score Modules getCreateRiskScoreLatestIndicesOptions - host 1`] = ` -Object { - "index": "ml_host_risk_score_latest_customSpaceId", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "host": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - "ingest_timestamp": Object { - "type": "date", - }, - }, - }, -} -`; - -exports[`Risk Score Modules getCreateRiskScoreLatestIndicesOptions - user 1`] = ` -Object { - "index": "ml_user_risk_score_latest_customSpaceId", - "mappings": Object { - "properties": Object { - "@timestamp": Object { - "type": "date", - }, - "ingest_timestamp": Object { - "type": "date", - }, - "user": Object { - "properties": Object { - "name": Object { - "type": "keyword", - }, - "risk": Object { - "properties": Object { - "calculated_level": Object { - "type": "keyword", - }, - "calculated_score_norm": Object { - "type": "float", - }, - "multipliers": Object { - "type": "keyword", - }, - "rule_risks": Object { - "properties": Object { - "rule_id": Object { - "type": "keyword", - }, - "rule_name": Object { - "fields": Object { - "keyword": Object { - "type": "keyword", - }, - }, - "type": "text", - }, - "rule_risk": Object { - "type": "float", - }, - }, - }, - }, - }, - }, - }, - }, - }, -} -`; - -exports[`Risk Score Modules getRiskHostCreateInitScriptOptions 1`] = ` -Object { - "id": "ml_hostriskscore_init_script_default", - "script": Object { - "lang": "painless", - "source": "state.rule_risk_stats = new HashMap(); -state.host_variant_set = false; -state.host_variant = new String(); -state.tactic_ids = new HashSet();", - }, -} -`; - -exports[`Risk Score Modules getRiskHostCreateLevelScriptOptions 1`] = ` -Object { - "id": "ml_hostriskscore_levels_script_default", - "script": Object { - "lang": "painless", - "source": "double risk_score = (def)ctx.getByPath(params.risk_score); -if (risk_score < 20) { - ctx['host']['risk']['calculated_level'] = 'Unknown' -} -else if (risk_score >= 20 && risk_score < 40) { - ctx['host']['risk']['calculated_level'] = 'Low' -} -else if (risk_score >= 40 && risk_score < 70) { - ctx['host']['risk']['calculated_level'] = 'Moderate' -} -else if (risk_score >= 70 && risk_score < 90) { - ctx['host']['risk']['calculated_level'] = 'High' -} -else if (risk_score >= 90) { - ctx['host']['risk']['calculated_level'] = 'Critical' -}", - }, -} -`; - -exports[`Risk Score Modules getRiskHostCreateMapScriptOptions 1`] = ` -Object { - "id": "ml_hostriskscore_map_script_default", - "script": Object { - "lang": "painless", - "source": "// Get the host variant -if (state.host_variant_set == false) { - if (doc.containsKey(\\"host.os.full\\") && doc[\\"host.os.full\\"].size() != 0) { - state.host_variant = doc[\\"host.os.full\\"].value; - state.host_variant_set = true; - } -} -// Aggregate all the tactics seen on the host -if (doc.containsKey(\\"signal.rule.threat.tactic.id\\") && doc[\\"signal.rule.threat.tactic.id\\"].size() != 0) { - state.tactic_ids.add(doc[\\"signal.rule.threat.tactic.id\\"].value); -} -// Get running sum of time-decayed risk score per rule name per shard -String rule_name = doc[\\"signal.rule.name\\"].value; -def stats = state.rule_risk_stats.getOrDefault(rule_name, [0.0,\\"\\",false]); -int time_diff = (int)((System.currentTimeMillis() - doc[\\"@timestamp\\"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0)); -double risk_derate = Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant)); -stats[0] = Math.max(stats[0], doc[\\"signal.rule.risk_score\\"].value * risk_derate); -if (stats[2] == false) { - stats[1] = doc[\\"kibana.alert.rule.uuid\\"].value; - stats[2] = true; -} -state.rule_risk_stats.put(rule_name, stats);", - }, -} -`; - -exports[`Risk Score Modules getRiskHostCreateReduceScriptOptions 1`] = ` -Object { - "id": "ml_hostriskscore_reduce_script_default", - "script": Object { - "lang": "painless", - "source": "// Consolidating time decayed risks and tactics from across all shards -Map total_risk_stats = new HashMap(); -String host_variant = new String(); -def tactic_ids = new HashSet(); -for (state in states) { - for (key in state.rule_risk_stats.keySet()) { - def rule_stats = state.rule_risk_stats.get(key); - def stats = total_risk_stats.getOrDefault(key, [0.0,\\"\\",false]); - stats[0] = Math.max(stats[0], rule_stats[0]); - if (stats[2] == false) { - stats[1] = rule_stats[1]; - stats[2] = true; - } - total_risk_stats.put(key, stats); - } - if (host_variant.length() == 0) { - host_variant = state.host_variant; - } - tactic_ids.addAll(state.tactic_ids); -} -// Consolidating individual rule risks and arranging them in decreasing order -List risks = new ArrayList(); -for (key in total_risk_stats.keySet()) { - risks.add(total_risk_stats[key][0]) -} -Collections.sort(risks, Collections.reverseOrder()); -// Calculating total host risk score -double total_risk = 0.0; -double risk_cap = params.max_risk * params.zeta_constant; -for (int i=0;i= 40 && total_norm_risk < 50) { - total_norm_risk = 85 + (total_norm_risk - 40); -} -else { - total_norm_risk = 95 + (total_norm_risk - 50) / 10; -} -// Calculating multipliers to the host risk score -double risk_multiplier = 1.0; -List multipliers = new ArrayList(); -// Add a multiplier if host is a server -if (host_variant.toLowerCase().contains(\\"server\\")) { - risk_multiplier *= params.server_multiplier; - multipliers.add(\\"Host is a server\\"); -} -// Add multipliers based on number and diversity of tactics seen on the host -for (String tactic : tactic_ids) { - multipliers.add(\\"Tactic \\"+tactic); - risk_multiplier *= 1 + params.tactic_base_multiplier * params.tactic_weights.getOrDefault(tactic, 0); -} -// Calculating final risk -double final_risk = total_norm_risk; -if (risk_multiplier > 1.0) { - double prior_odds = (total_norm_risk) / (100 - total_norm_risk); - double updated_odds = prior_odds * risk_multiplier; - final_risk = 100 * updated_odds / (1 + updated_odds); -} -// Adding additional metadata -List rule_stats = new ArrayList(); -for (key in total_risk_stats.keySet()) { - Map temp = new HashMap(); - temp[\\"rule_name\\"] = key; - temp[\\"rule_risk\\"] = total_risk_stats[key][0]; - temp[\\"rule_id\\"] = total_risk_stats[key][1]; - rule_stats.add(temp); -} - -return [\\"calculated_score_norm\\": final_risk, \\"rule_risks\\": rule_stats, \\"multipliers\\": multipliers];", - }, -} -`; - -exports[`Risk Score Modules getRiskScoreIngestPipelineOptions - host 1`] = ` -Object { - "name": "ml_hostriskscore_ingest_pipeline_default", - "processors": Array [ - Object { - "set": Object { - "field": "ingest_timestamp", - "value": "{{_ingest.timestamp}}", - }, - }, - Object { - "fingerprint": Object { - "fields": Array [ - "@timestamp", - "_id", - ], - "method": "SHA-256", - "target_field": "_id", - }, - }, - Object { - "script": Object { - "id": "ml_hostriskscore_levels_script_default", - "params": Object { - "risk_score": "host.risk.calculated_score_norm", - }, - }, - }, - ], -} -`; - -exports[`Risk Score Modules getRiskScoreIngestPipelineOptions - user 1`] = ` -Object { - "name": "ml_userriskscore_ingest_pipeline_default", - "processors": Array [ - Object { - "set": Object { - "field": "ingest_timestamp", - "value": "{{_ingest.timestamp}}", - }, - }, - Object { - "fingerprint": Object { - "fields": Array [ - "@timestamp", - "_id", - ], - "method": "SHA-256", - "target_field": "_id", - }, - }, - Object { - "script": Object { - "id": "ml_userriskscore_levels_script_default", - "params": Object { - "risk_score": "user.risk.calculated_score_norm", - }, - }, - }, - ], -} -`; - -exports[`Risk Score Modules getRiskUserCreateLevelScriptOptions 1`] = ` -Object { - "id": "ml_userriskscore_levels_script_default", - "script": Object { - "lang": "painless", - "source": "double risk_score = (def)ctx.getByPath(params.risk_score); -if (risk_score < 20) { - ctx['user']['risk']['calculated_level'] = 'Unknown' -} -else if (risk_score >= 20 && risk_score < 40) { - ctx['user']['risk']['calculated_level'] = 'Low' -} -else if (risk_score >= 40 && risk_score < 70) { - ctx['user']['risk']['calculated_level'] = 'Moderate' -} -else if (risk_score >= 70 && risk_score < 90) { - ctx['user']['risk']['calculated_level'] = 'High' -} -else if (risk_score >= 90) { - ctx['user']['risk']['calculated_level'] = 'Critical' -}", - }, -} -`; - -exports[`Risk Score Modules getRiskUserCreateMapScriptOptions 1`] = ` -Object { - "id": "ml_userriskscore_map_script_default", - "script": Object { - "lang": "painless", - "source": "// Get running sum of risk score per rule name per shard\\\\\\\\ -String rule_name = doc[\\"signal.rule.name\\"].value; -def stats = state.rule_risk_stats.getOrDefault(rule_name, 0.0); -stats = doc[\\"signal.rule.risk_score\\"].value; -state.rule_risk_stats.put(rule_name, stats);", - }, -} -`; - -exports[`Risk Score Modules getRiskUserCreateReduceScriptOptions 1`] = ` -Object { - "id": "ml_userriskscore_reduce_script_default", - "script": Object { - "lang": "painless", - "source": "// Consolidating time decayed risks from across all shards -Map total_risk_stats = new HashMap(); -for (state in states) { - for (key in state.rule_risk_stats.keySet()) { - def rule_stats = state.rule_risk_stats.get(key); - def stats = total_risk_stats.getOrDefault(key, 0.0); - stats = rule_stats; - total_risk_stats.put(key, stats); - } -} -// Consolidating individual rule risks and arranging them in decreasing order -List risks = new ArrayList(); -for (key in total_risk_stats.keySet()) { - risks.add(total_risk_stats[key]) -} -Collections.sort(risks, Collections.reverseOrder()); -// Calculating total risk and normalizing it to a range -double total_risk = 0.0; -double risk_cap = params.max_risk * params.zeta_constant; -for (int i=0;i= 40 && total_norm_risk < 50) { - total_norm_risk = 85 + (total_norm_risk - 40); -} -else { - total_norm_risk = 95 + (total_norm_risk - 50) / 10; -} - -List rule_stats = new ArrayList(); -for (key in total_risk_stats.keySet()) { - Map temp = new HashMap(); - temp[\\"rule_name\\"] = key; - temp[\\"rule_risk\\"] = total_risk_stats[key]; - rule_stats.add(temp); -} - -return [\\"calculated_score_norm\\": total_norm_risk, \\"rule_risks\\": rule_stats];", - }, -} -`; From a25493be84e209c70ea0c774df86d5d58de85cf7 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Wed, 11 Dec 2024 10:29:16 +0000 Subject: [PATCH 29/38] run node scripts/i18n_check.js --fix --- .../plugins/private/translations/translations/fr-FR.json | 2 +- .../plugins/private/translations/translations/ja-JP.json | 2 +- .../plugins/private/translations/translations/zh-CN.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 11ad859d3373d..3ad8d74371a57 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -26154,9 +26154,9 @@ "xpack.lens.app.settingsAriaLabel": "Ouvrir le menu de paramètres Lens", "xpack.lens.app.share.defaultDashboardTitle": "Visualisation Lens [{date}]", "xpack.lens.app.shareButtonDisabledWarning": "La visualisation ne comprend aucune donnée à partager.", - "xpack.lens.app.shareModal.title": "Partager cette visualisation Lens", "xpack.lens.app.shareModal.draftModeCallout.link.warning": "Copiez le lien afin d’obtenir un lien temporaire. Enregistrez la visualisation Lens pour créer un lien permanent.", "xpack.lens.app.shareModal.draftModeCallout.title": "Modifications non enregistrées", + "xpack.lens.app.shareModal.title": "Partager cette visualisation Lens", "xpack.lens.app.shareTitle": "Partager", "xpack.lens.app.shareTitleAria": "Partager la visualisation", "xpack.lens.app.showUnderlyingDataMultipleLayers": "Impossible d’afficher les données sous-jacentes pour les visualisations avec plusieurs calques.", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index ad56e50ab6ee3..ddbc903d5a3e1 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -26013,9 +26013,9 @@ "xpack.lens.app.settingsAriaLabel": "Lens設定メニューを開く", "xpack.lens.app.share.defaultDashboardTitle": "Lensビジュアライゼーション[{date}]", "xpack.lens.app.shareButtonDisabledWarning": "ビジュアライゼーションには共有するデータがありません。", - "xpack.lens.app.shareModal.title": "このLensビジュアライゼーションを共有", "xpack.lens.app.shareModal.draftModeCallout.link.warning": "リンクをコピーして、一時リンクを取得します。Lensビジュアライゼーションを保存して、永続リンクを作成します。", "xpack.lens.app.shareModal.draftModeCallout.title": "保存されていない変更", + "xpack.lens.app.shareModal.title": "このLensビジュアライゼーションを共有", "xpack.lens.app.shareTitle": "共有", "xpack.lens.app.shareTitleAria": "ビジュアライゼーションを共有", "xpack.lens.app.showUnderlyingDataMultipleLayers": "複数レイヤーのビジュアライゼーションでは、基本データを表示できません", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 3ad5f497e90d7..b303bb9d4f1e5 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -25575,9 +25575,9 @@ "xpack.lens.app.settingsAriaLabel": "打开 Lens 设置菜单", "xpack.lens.app.share.defaultDashboardTitle": "Lens 可视化 [{date}]", "xpack.lens.app.shareButtonDisabledWarning": "此可视化没有可共享的数据。", - "xpack.lens.app.shareModal.title": "共享此 Lens 可视化", "xpack.lens.app.shareModal.draftModeCallout.link.warning": "复制链接以获取临时链接。保存 Lens 可视化以创建永久链接。", "xpack.lens.app.shareModal.draftModeCallout.title": "未保存的更改", + "xpack.lens.app.shareModal.title": "共享此 Lens 可视化", "xpack.lens.app.shareTitle": "共享", "xpack.lens.app.shareTitleAria": "共享可视化", "xpack.lens.app.showUnderlyingDataMultipleLayers": "无法显示具有多个图层的可视化的底层数据", From 6debc22f063fa2119515cfaf6afd797a54ab77b9 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Tue, 17 Dec 2024 11:14:14 +0000 Subject: [PATCH 30/38] remover unused files --- .../entity_analytics_learn_more_link.tsx | 37 +++++++++++++++++++ .../components/risk_score_header_title.tsx | 36 ++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx create mode 100644 x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx diff --git a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx new file mode 100644 index 0000000000000..b0e590db8f0e6 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/entity_analytics_learn_more_link.tsx @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiLink } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React from 'react'; +import { useKibana } from '../../common/lib/kibana'; + +const EntityAnalyticsLearnMoreLinkComponent = ({ title }: { title?: string | React.ReactNode }) => { + const { docLinks } = useKibana().services; + const entityAnalyticsLinks = docLinks.links.securitySolution.entityAnalytics; + + return ( + + {title ? ( + title + ) : ( + + )} + + ); +}; + +export const EntityAnalyticsLearnMoreLink = React.memo(EntityAnalyticsLearnMoreLinkComponent); + +EntityAnalyticsLearnMoreLink.displayName = 'EntityAnalyticsLearnMoreLink'; diff --git a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx new file mode 100644 index 0000000000000..2693c859f9ed8 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/risk_score_header_title.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { RiskScoreEntity } from '../../../common/search_strategy'; + +const RiskScoreHeaderTitleComponent = ({ + riskScoreEntity, + title, +}: { + riskScoreEntity: RiskScoreEntity; + title?: string; +}) => ( + <> + {title ?? + (riskScoreEntity === RiskScoreEntity.user ? ( + + ) : ( + + ))} + +); + +export const RiskScoreHeaderTitle = React.memo(RiskScoreHeaderTitleComponent); +RiskScoreHeaderTitle.displayName = 'RiskScoreHeaderTitle'; From 9743e359c6f1c530b1e6caeaa940badd280ef466 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:38:05 +0000 Subject: [PATCH 31/38] [CI] Auto-commit changed files from 'node scripts/styled_components_mapping' --- packages/kbn-babel-preset/styled_components_files.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/kbn-babel-preset/styled_components_files.js b/packages/kbn-babel-preset/styled_components_files.js index 1829c9cf28885..930a868f89ab5 100644 --- a/packages/kbn-babel-preset/styled_components_files.js +++ b/packages/kbn-babel-preset/styled_components_files.js @@ -412,7 +412,6 @@ module.exports = { /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]risk_details_tab_body[\/\\]index.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]risk_information[\/\\]index.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]risk_score_donut_chart[\/\\]index.tsx/, - /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]risk_score_onboarding[\/\\]use_risk_score_toast_content.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]severity[\/\\]common[\/\\]index.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]severity[\/\\]severity_bar.tsx/, /x-pack[\/\\]solutions[\/\\]security[\/\\]plugins[\/\\]security_solution[\/\\]public[\/\\]entity_analytics[\/\\]components[\/\\]styled_basic_table.tsx/, From eca93439c45fe5bb0b94f57039a6eb823970fb62 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 6 Jan 2025 15:08:19 +0000 Subject: [PATCH 32/38] more legacy code thanks @machadoum --- .../risk_score_over_time_area.ts | 4 +- .../tasks/api_calls/risk_scores/indices.ts | 59 --- .../cypress/tasks/risk_scores/indices.ts | 71 ---- .../tasks/risk_scores/ingest_pipelines.ts | 54 --- .../tasks/risk_scores/stored_scripts.ts | 131 ------- .../cypress/tasks/risk_scores/transforms.ts | 355 ------------------ 6 files changed, 2 insertions(+), 672 deletions(-) delete mode 100644 x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/indices.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/indices.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/ingest_pipelines.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/stored_scripts.ts delete mode 100644 x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/transforms.ts diff --git a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts index 06bebcb4e1339..f8481cd03a822 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/risk_score_over_time_area.ts @@ -180,14 +180,14 @@ export const getRiskScoreOverTimeAreaAttributes: GetLensAttributes = ( adHocDataViews: { [internalReferenceId]: { id: internalReferenceId, - title: `ml_${stackByField}_risk_score_${extraOptions.spaceId}`, + title: `ea_${stackByField}_risk_score_${extraOptions.spaceId}`, timeFieldName: '@timestamp', sourceFilters: [], fieldFormats: {}, runtimeFieldMap: {}, fieldAttrs: {}, allowNoIndex: false, - name: `ml_${stackByField}_risk_score_${extraOptions.spaceId}`, + name: `ea_${stackByField}_risk_score_${extraOptions.spaceId}`, }, }, }, diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/indices.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/indices.ts deleted file mode 100644 index 296a487a47f7b..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/risk_scores/indices.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 { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { INDICES_URL } from '../../../urls/risk_score'; -import type { RiskScoreEntity } from '../../risk_scores/common'; -import { getLatestTransformIndex, getPivotTransformIndex } from '../../risk_scores/indices'; - -export const createIndex = (options: { - index: string; - mappings: string | Record; -}) => { - return cy.request({ - method: 'put', - url: `${INDICES_URL}/create`, - body: options, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - }); -}; - -export const deleteRiskScoreIndicies = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => { - return cy - .request({ - method: 'post', - url: `${INDICES_URL}/delete`, - body: { - indices: [getPivotTransformIndex(riskScoreEntity, spaceId)], - }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - failOnStatusCode: false, - }) - .then(() => { - return cy.request({ - method: 'post', - url: `${INDICES_URL}/delete`, - body: { - indices: [getLatestTransformIndex(riskScoreEntity, spaceId)], - }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - failOnStatusCode: false, - }); - }); -}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/indices.ts b/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/indices.ts deleted file mode 100644 index 1d064fcdbb59b..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/indices.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { RiskScoreEntity } from './common'; - -export const getPivotTransformIndex = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}_risk_score_${spaceId}`; - -export const getLatestTransformIndex = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}_risk_score_latest_${spaceId}`; - -export const getLegacyRiskScoreMapping = (riskScoreEntity: RiskScoreEntity) => { - return { - properties: { - [`${riskScoreEntity}.name`]: { - type: 'keyword', - }, - '@timestamp': { - type: 'date', - }, - ingest_timestamp: { - type: 'date', - }, - risk: { - type: 'text', - fields: { - keyword: { - type: 'keyword', - }, - }, - }, - risk_stats: { - properties: { - risk_score: { - type: 'float', - }, - }, - }, - }, - }; -}; - -export const getLegacyRiskScoreIndicesOptions = ({ - spaceId = 'default', - riskScoreEntity, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; -}) => { - return { - index: getPivotTransformIndex(riskScoreEntity, spaceId), - mappings: getLegacyRiskScoreMapping(riskScoreEntity), - }; -}; - -export const getLegacyRiskScoreLatestIndicesOptions = ({ - spaceId = 'default', - riskScoreEntity, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; -}) => { - return { - index: getLatestTransformIndex(riskScoreEntity, spaceId), - mappings: getLegacyRiskScoreMapping(riskScoreEntity), - }; -}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/ingest_pipelines.ts b/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/ingest_pipelines.ts deleted file mode 100644 index 2efedeb71836e..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/ingest_pipelines.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { RiskScoreEntity } from './common'; -import { getLegacyRiskScoreLevelScriptId, getRiskScoreLevelScriptId } from './stored_scripts'; - -export const getIngestPipelineName = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_ingest_pipeline_${spaceId}`; - -export const getLegacyIngestPipelineName = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_ingest_pipeline`; - -export const getLegacyRiskScoreIngestPipelineOptions = ( - riskScoreEntity: RiskScoreEntity, - version = '8.4' -) => { - const processors = [ - { - set: { - field: 'ingest_timestamp', - value: '{{_ingest.timestamp}}', - }, - }, - { - fingerprint: { - fields: ['@timestamp', '_id'], - method: 'SHA-256', - target_field: '_id', - }, - }, - { - script: { - id: - version === '8.4' - ? getLegacyRiskScoreLevelScriptId(riskScoreEntity) - : getRiskScoreLevelScriptId(riskScoreEntity), - params: { - risk_score: 'risk_stats.risk_score', - }, - }, - }, - ]; - return { - name: - version === '8.4' - ? getLegacyIngestPipelineName(riskScoreEntity) - : getIngestPipelineName(riskScoreEntity), - processors, - }; -}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/stored_scripts.ts b/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/stored_scripts.ts deleted file mode 100644 index 0e510e1247e19..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/stored_scripts.ts +++ /dev/null @@ -1,131 +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 { RiskScoreEntity } from './common'; - -export const getRiskScoreLevelScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_levels_script_${spaceId}`; -export const getRiskScoreInitScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_init_script_${spaceId}`; -export const getRiskScoreMapScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_map_script_${spaceId}`; -export const getRiskScoreReduceScriptId = (riskScoreEntity: RiskScoreEntity, spaceId = 'default') => - `ml_${riskScoreEntity}riskscore_reduce_script_${spaceId}`; - -export const getLegacyRiskScoreLevelScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_levels_script`; -export const getLegacyRiskScoreInitScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_init_script`; -export const getLegacyRiskScoreMapScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_map_script`; -export const getLegacyRiskScoreReduceScriptId = (riskScoreEntity: RiskScoreEntity) => - `ml_${riskScoreEntity}riskscore_reduce_script`; - -export const getLegacyRiskHostCreateLevelScriptOptions = (version = '8.4') => { - const source = - "double risk_score = (def)ctx.getByPath(params.risk_score);\nif (risk_score < 20) {\n ctx['risk'] = 'Unknown'\n}\nelse if (risk_score >= 20 && risk_score < 40) {\n ctx['risk'] = 'Low'\n}\nelse if (risk_score >= 40 && risk_score < 70) {\n ctx['risk'] = 'Moderate'\n}\nelse if (risk_score >= 70 && risk_score < 90) {\n ctx['risk'] = 'High'\n}\nelse if (risk_score >= 90) {\n ctx['risk'] = 'Critical'\n}"; - return { - id: - version === '8.4' - ? getLegacyRiskScoreLevelScriptId(RiskScoreEntity.host) - : getRiskScoreLevelScriptId(RiskScoreEntity.host), - script: { - lang: 'painless', - source, - }, - }; -}; - -export const getLegacyRiskHostCreateInitScriptOptions = (version = '8.4') => { - const source = - 'state.rule_risk_stats = new HashMap();\nstate.host_variant_set = false;\nstate.host_variant = new String();\nstate.tactic_ids = new HashSet();'; - return { - id: - version === '8.4' - ? getLegacyRiskScoreInitScriptId(RiskScoreEntity.host) - : getRiskScoreInitScriptId(RiskScoreEntity.host), - script: { - lang: 'painless', - source, - }, - }; -}; - -export const getLegacyRiskHostCreateMapScriptOptions = (version = '8.4') => { - const source = - '// Get the host variant\nif (state.host_variant_set == false) {\n if (doc.containsKey("host.os.full") && doc["host.os.full"].size() != 0) {\n state.host_variant = doc["host.os.full"].value;\n state.host_variant_set = true;\n }\n}\n// Aggregate all the tactics seen on the host\nif (doc.containsKey("signal.rule.threat.tactic.id") && doc["signal.rule.threat.tactic.id"].size() != 0) {\n state.tactic_ids.add(doc["signal.rule.threat.tactic.id"].value);\n}\n// Get running sum of time-decayed risk score per rule name per shard\nString rule_name = doc["signal.rule.name"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, [0.0,"",false]);\nint time_diff = (int)((System.currentTimeMillis() - doc["@timestamp"].value.toInstant().toEpochMilli()) / (1000.0 * 60.0 * 60.0));\ndouble risk_derate = Math.min(1, Math.exp((params.lookback_time - time_diff) / params.time_decay_constant));\nstats[0] = Math.max(stats[0], doc["signal.rule.risk_score"].value * risk_derate);\nif (stats[2] == false) {\n stats[1] = doc["kibana.alert.rule.uuid"].value;\n stats[2] = true;\n}\nstate.rule_risk_stats.put(rule_name, stats);'; - return { - id: - version === '8.4' - ? getLegacyRiskScoreMapScriptId(RiskScoreEntity.host) - : getRiskScoreMapScriptId(RiskScoreEntity.host), - script: { - lang: 'painless', - source, - }, - }; -}; - -export const getLegacyRiskHostCreateReduceScriptOptions = (version = '8.4') => { - const source = - '// Consolidating time decayed risks and tactics from across all shards\nMap total_risk_stats = new HashMap();\nString host_variant = new String();\ndef tactic_ids = new HashSet();\nfor (state in states) {\n for (key in state.rule_risk_stats.keySet()) {\n def rule_stats = state.rule_risk_stats.get(key);\n def stats = total_risk_stats.getOrDefault(key, [0.0,"",false]);\n stats[0] = Math.max(stats[0], rule_stats[0]);\n if (stats[2] == false) {\n stats[1] = rule_stats[1];\n stats[2] = true;\n } \n total_risk_stats.put(key, stats);\n }\n if (host_variant.length() == 0) {\n host_variant = state.host_variant;\n }\n tactic_ids.addAll(state.tactic_ids);\n}\n// Consolidating individual rule risks and arranging them in decreasing order\nList risks = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n risks.add(total_risk_stats[key][0])\n}\nCollections.sort(risks, Collections.reverseOrder());\n// Calculating total host risk score\ndouble total_risk = 0.0;\ndouble risk_cap = params.max_risk * params.zeta_constant;\nfor (int i=0;i= 40 && total_norm_risk < 50) {\n total_norm_risk = 85 + (total_norm_risk - 40);\n}\nelse {\n total_norm_risk = 95 + (total_norm_risk - 50) / 10;\n}\n// Calculating multipliers to the host risk score\ndouble risk_multiplier = 1.0;\nList multipliers = new ArrayList();\n// Add a multiplier if host is a server\nif (host_variant.toLowerCase().contains("server")) {\n risk_multiplier *= params.server_multiplier;\n multipliers.add("Host is a server");\n}\n// Add multipliers based on number and diversity of tactics seen on the host\nfor (String tactic : tactic_ids) {\n multipliers.add("Tactic "+tactic);\n risk_multiplier *= 1 + params.tactic_base_multiplier * params.tactic_weights.getOrDefault(tactic, 0);\n}\n// Calculating final risk\ndouble final_risk = total_norm_risk;\nif (risk_multiplier > 1.0) {\n double prior_odds = (total_norm_risk) / (100 - total_norm_risk);\n double updated_odds = prior_odds * risk_multiplier; \n final_risk = 100 * updated_odds / (1 + updated_odds);\n}\n// Adding additional metadata\nList rule_stats = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n Map temp = new HashMap();\n temp["rule_name"] = key;\n temp["rule_risk"] = total_risk_stats[key][0];\n temp["rule_id"] = total_risk_stats[key][1];\n rule_stats.add(temp);\n}\n\nreturn ["calculated_score_norm": final_risk, "rule_risks": rule_stats, "multipliers": multipliers];'; - return { - id: - version === '8.4' - ? getLegacyRiskScoreReduceScriptId(RiskScoreEntity.host) - : getRiskScoreReduceScriptId(RiskScoreEntity.host), - script: { - lang: 'painless', - source, - }, - }; -}; - -export const getLegacyRiskUserCreateLevelScriptOptions = (version = '8.4') => { - const source = - "double risk_score = (def)ctx.getByPath(params.risk_score);\nif (risk_score < 20) {\n ctx['risk'] = 'Unknown'\n}\nelse if (risk_score >= 20 && risk_score < 40) {\n ctx['risk'] = 'Low'\n}\nelse if (risk_score >= 40 && risk_score < 70) {\n ctx['risk'] = 'Moderate'\n}\nelse if (risk_score >= 70 && risk_score < 90) {\n ctx['risk'] = 'High'\n}\nelse if (risk_score >= 90) {\n ctx['risk'] = 'Critical'\n}"; - return { - id: - version === '8.4' - ? getLegacyRiskScoreLevelScriptId(RiskScoreEntity.user) - : getRiskScoreLevelScriptId(RiskScoreEntity.user), - script: { - lang: 'painless', - source, - }, - }; -}; - -export const getLegacyRiskUserCreateMapScriptOptions = (version = '8.4') => { - const source = - '// Get running sum of risk score per rule name per shard\\\\\nString rule_name = doc["signal.rule.name"].value;\ndef stats = state.rule_risk_stats.getOrDefault(rule_name, 0.0);\nstats = doc["signal.rule.risk_score"].value;\nstate.rule_risk_stats.put(rule_name, stats);'; - return { - id: - version === '8.4' - ? getLegacyRiskScoreMapScriptId(RiskScoreEntity.user) - : getRiskScoreMapScriptId(RiskScoreEntity.user), - script: { - lang: 'painless', - source, - }, - }; -}; - -export const getLegacyRiskUserCreateReduceScriptOptions = (version = '8.4') => { - const source = - '// Consolidating time decayed risks from across all shards\nMap total_risk_stats = new HashMap();\nfor (state in states) {\n for (key in state.rule_risk_stats.keySet()) {\n def rule_stats = state.rule_risk_stats.get(key);\n def stats = total_risk_stats.getOrDefault(key, 0.0);\n stats = rule_stats;\n total_risk_stats.put(key, stats);\n }\n}\n// Consolidating individual rule risks and arranging them in decreasing order\nList risks = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n risks.add(total_risk_stats[key])\n}\nCollections.sort(risks, Collections.reverseOrder());\n// Calculating total risk and normalizing it to a range\ndouble total_risk = 0.0;\ndouble risk_cap = params.max_risk * params.zeta_constant;\nfor (int i=0;i= 40 && total_norm_risk < 50) {\n total_norm_risk = 85 + (total_norm_risk - 40);\n}\nelse {\n total_norm_risk = 95 + (total_norm_risk - 50) / 10;\n}\n\nList rule_stats = new ArrayList();\nfor (key in total_risk_stats.keySet()) {\n Map temp = new HashMap();\n temp["rule_name"] = key;\n temp["rule_risk"] = total_risk_stats[key];\n rule_stats.add(temp);\n}\n\nreturn ["risk_score": total_norm_risk, "rule_risks": rule_stats];'; - return { - id: - version === '8.4' - ? getLegacyRiskScoreReduceScriptId(RiskScoreEntity.user) - : getRiskScoreReduceScriptId(RiskScoreEntity.user), - script: { - lang: 'painless', - source, - }, - }; -}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/transforms.ts b/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/transforms.ts deleted file mode 100644 index 8e04a4a5ac557..0000000000000 --- a/x-pack/test/security_solution_cypress/cypress/tasks/risk_scores/transforms.ts +++ /dev/null @@ -1,355 +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 { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; -import { TRANSFORMS_URL } from '../../urls/risk_score'; -import { RiskScoreEntity } from './common'; -import { getLatestTransformIndex, getPivotTransformIndex } from './indices'; -import { getIngestPipelineName, getLegacyIngestPipelineName } from './ingest_pipelines'; -import { - getLegacyRiskScoreInitScriptId, - getLegacyRiskScoreMapScriptId, - getLegacyRiskScoreReduceScriptId, - getRiskScoreInitScriptId, - getRiskScoreMapScriptId, - getRiskScoreReduceScriptId, -} from './stored_scripts'; - -const DEFAULT_ALERTS_INDEX = '.alerts-security.alerts' as const; -const getAlertsIndex = (spaceId = 'default') => `${DEFAULT_ALERTS_INDEX}-${spaceId}`; - -export const getRiskScorePivotTransformId = ( - riskScoreEntity: RiskScoreEntity, - spaceId = 'default' -) => `ml_${riskScoreEntity}riskscore_pivot_transform_${spaceId}`; - -export const getRiskScoreLatestTransformId = ( - riskScoreEntity: RiskScoreEntity, - spaceId = 'default' -) => `ml_${riskScoreEntity}riskscore_latest_transform_${spaceId}`; - -export const getTransformState = (transformId: string) => { - return cy.request<{ transforms: Array<{ id: string; state: string }>; count: number }>({ - method: 'get', - url: `${TRANSFORMS_URL}/transforms/${transformId}/_stats`, - headers: { - 'kbn-xsrf': 'cypress-creds-via-config', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - }); -}; - -export const startTransforms = (transformIds: string[]) => { - return cy.request({ - method: 'post', - url: `${TRANSFORMS_URL}/start_transforms`, - headers: { - 'kbn-xsrf': 'cypress-creds-via-config', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - body: transformIds.map((id) => ({ - id, - })), - }); -}; - -const stopTransform = (state: { - transforms: Array<{ id: string; state: string }>; - count: number; -}) => { - return cy.request({ - method: 'post', - url: `${TRANSFORMS_URL}/stop_transforms`, - headers: { - 'kbn-xsrf': 'cypress-creds-via-config', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - body: - state != null && state.transforms.length > 0 - ? [ - { - id: state.transforms[0].id, - state: state.transforms[0].state, - }, - ] - : ([] as Array<{ id: string; state: string }>), - }); -}; - -export const createTransform = (transformId: string, options: string | Record) => { - return cy.request({ - method: 'put', - url: `${TRANSFORMS_URL}/transforms/${transformId}`, - headers: { - 'kbn-xsrf': 'cypress-creds-via-config', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - body: options, - }); -}; - -const deleteTransform = (transformId: string) => { - return cy.request({ - method: 'post', - url: `${TRANSFORMS_URL}/delete_transforms`, - headers: { - 'kbn-xsrf': 'cypress-creds-via-config', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: '1', - }, - failOnStatusCode: false, - body: { - transformsInfo: [ - { - id: transformId, - state: 'stopped', - }, - ], - deleteDestIndex: true, - deleteDestDataView: true, - forceDelete: false, - }, - }); -}; - -export const deleteTransforms = (transformIds: string[]) => { - const deleteSingleTransform = (transformId: string) => - getTransformState(transformId) - .then(({ body: result }) => { - return stopTransform(result); - }) - .then(() => { - deleteTransform(transformId); - }); - - transformIds.map((transformId) => deleteSingleTransform(transformId)); -}; - -export const getCreateLegacyMLHostPivotTransformOptions = ({ - spaceId = 'default', - version = '8.4', -}: { - spaceId?: string; - version?: '8.3' | '8.4'; -}) => { - const options = { - dest: { - index: getPivotTransformIndex(RiskScoreEntity.host, spaceId), - pipeline: - version === '8.4' - ? getLegacyIngestPipelineName(RiskScoreEntity.host) - : getIngestPipelineName(RiskScoreEntity.host, spaceId), - }, - frequency: '1h', - pivot: { - aggregations: { - '@timestamp': { - max: { - field: '@timestamp', - }, - }, - risk_stats: { - scripted_metric: { - combine_script: 'return state', - init_script: { - id: - version === '8.4' - ? getLegacyRiskScoreInitScriptId(RiskScoreEntity.host) - : getRiskScoreInitScriptId(RiskScoreEntity.host, spaceId), - }, - map_script: { - id: - version === '8.4' - ? getLegacyRiskScoreMapScriptId(RiskScoreEntity.host) - : getRiskScoreMapScriptId(RiskScoreEntity.host, spaceId), - }, - params: { - lookback_time: 72, - max_risk: 100, - p: 1.5, - server_multiplier: 1.5, - tactic_base_multiplier: 0.25, - tactic_weights: { - TA0001: 1, - TA0002: 2, - TA0003: 3, - TA0004: 4, - TA0005: 4, - TA0006: 4, - TA0007: 4, - TA0008: 5, - TA0009: 6, - TA0010: 7, - TA0011: 6, - TA0040: 8, - TA0042: 1, - TA0043: 1, - }, - time_decay_constant: 6, - zeta_constant: 2.612, - }, - reduce_script: { - id: - version === '8.4' - ? getLegacyRiskScoreReduceScriptId(RiskScoreEntity.host) - : getRiskScoreReduceScriptId(RiskScoreEntity.host, spaceId), - }, - }, - }, - }, - group_by: { - [`${RiskScoreEntity.host}.name`]: { - terms: { - field: `${RiskScoreEntity.host}.name`, - }, - }, - }, - }, - source: { - index: [getAlertsIndex(spaceId)], - query: { - bool: { - filter: [ - { - range: { - '@timestamp': { - gte: 'now-5d', - }, - }, - }, - ], - }, - }, - }, - sync: { - time: { - delay: '120s', - field: '@timestamp', - }, - }, - }; - - return options; -}; - -export const getCreateLegacyMLUserPivotTransformOptions = ({ - spaceId = 'default', - version = '8.4', -}: { - spaceId?: string; - version?: '8.3' | '8.4'; -}) => { - const options = { - dest: { - index: getPivotTransformIndex(RiskScoreEntity.user, spaceId), - pipeline: - version === '8.4' - ? getLegacyIngestPipelineName(RiskScoreEntity.user) - : getIngestPipelineName(RiskScoreEntity.user), - }, - frequency: '1h', - pivot: { - aggregations: { - '@timestamp': { - max: { - field: '@timestamp', - }, - }, - risk_stats: { - scripted_metric: { - combine_script: 'return state', - init_script: 'state.rule_risk_stats = new HashMap();', - map_script: { - id: - version === '8.4' - ? getLegacyRiskScoreMapScriptId(RiskScoreEntity.user) - : getRiskScoreMapScriptId(RiskScoreEntity.user), - }, - params: { - max_risk: 100, - p: 1.5, - zeta_constant: 2.612, - }, - reduce_script: { - id: - version === '8.4' - ? getLegacyRiskScoreReduceScriptId(RiskScoreEntity.user) - : getRiskScoreReduceScriptId(RiskScoreEntity.user), - }, - }, - }, - }, - group_by: { - 'user.name': { - terms: { - field: 'user.name', - }, - }, - }, - }, - source: { - index: [getAlertsIndex(spaceId)], - query: { - bool: { - filter: [ - { - range: { - '@timestamp': { - gte: 'now-90d', - }, - }, - }, - { - match: { - 'signal.status': 'open', - }, - }, - ], - }, - }, - }, - sync: { - time: { - delay: '120s', - field: '@timestamp', - }, - }, - }; - return options; -}; - -export const getCreateLegacyLatestTransformOptions = ({ - spaceId = 'default', - riskScoreEntity, -}: { - spaceId?: string; - riskScoreEntity: RiskScoreEntity; -}) => { - const options = { - dest: { - index: getLatestTransformIndex(riskScoreEntity, spaceId), - }, - frequency: '1h', - latest: { - sort: '@timestamp', - unique_key: [`${riskScoreEntity}.name`], - }, - source: { - index: [getPivotTransformIndex(riskScoreEntity, spaceId)], - }, - sync: { - time: { - delay: '2s', - field: 'ingest_timestamp', - }, - }, - }; - return options; -}; From 48f9902d9de46f56f3b31b527629abc0bf2fb9ec Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Tue, 7 Jan 2025 11:19:27 +0000 Subject: [PATCH 33/38] fix test snapshot --- .../__snapshots__/risk_score_over_time_area.test.ts.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_over_time_area.test.ts.snap b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_over_time_area.test.ts.snap index 1780bfc11046d..6419075faeee2 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_over_time_area.test.ts.snap +++ b/x-pack/solutions/security/plugins/security_solution/public/entity_analytics/lens_attributes/__snapshots__/risk_score_over_time_area.test.ts.snap @@ -11,11 +11,11 @@ Object { "fieldAttrs": Object {}, "fieldFormats": Object {}, "id": "d594baeb-5eca-480c-8885-ba79eaf41372", - "name": "ml_host_risk_score_mockSpaceId", + "name": "ea_host_risk_score_mockSpaceId", "runtimeFieldMap": Object {}, "sourceFilters": Array [], "timeFieldName": "@timestamp", - "title": "ml_host_risk_score_mockSpaceId", + "title": "ea_host_risk_score_mockSpaceId", }, }, "datasourceStates": Object { From 818cbdd3f4b70af23f9beb7f634a7b3fbd84e87a Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 10 Jan 2025 08:45:55 +0000 Subject: [PATCH 34/38] remove unused feature flag from test --- .../dashboards/enable_risk_score_redirect.cy.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts index 40d5623f114fd..478f3c741ffd9 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts @@ -18,13 +18,6 @@ describe( 'Enable risk scores from dashboard', { tags: ['@ess', '@serverless'], - env: { - ftrConfig: { - kbnServerArgs: [ - `--xpack.securitySolution.enableExperimental=${JSON.stringify(['entityStoreDisabled'])}`, - ], - }, - }, }, () => { beforeEach(() => { From e81d87c6dcc205c36e992d87046c7e725486175d Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 10 Jan 2025 08:55:58 +0000 Subject: [PATCH 35/38] remove extra describe --- .../hosts/host_risk_tab.cy.ts | 72 +++++++++---------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts index 18358f6145e41..639e5b96ef00d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/host_risk_tab.cy.ts @@ -22,51 +22,49 @@ import { hostsUrl } from '../../../urls/navigation'; import { kqlSearch } from '../../../tasks/security_header'; import { mockRiskEngineEnabled } from '../../../tasks/entity_analytics'; -describe('risk tab', { tags: ['@ess'] }, () => { - describe('with risk score', { tags: ['@serverless'] }, () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); - }); +describe('risk tab', { tags: ['@ess', '@serverless'] }, () => { + before(() => { + cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); + }); - beforeEach(() => { - login(); - mockRiskEngineEnabled(); - visitWithTimeRange(hostsUrl('allHosts')); - // by some reason after navigate to host risk, page is sometimes is reload or go to all host tab - // this fix wait until we fave host in all host table, and then we go to risk tab - cy.contains('siem-kibana'); - navigateToHostRiskDetailTab(); - }); + beforeEach(() => { + login(); + mockRiskEngineEnabled(); + visitWithTimeRange(hostsUrl('allHosts')); + // by some reason after navigate to host risk, page is sometimes is reload or go to all host tab + // this fix wait until we fave host in all host table, and then we go to risk tab + cy.contains('siem-kibana'); + navigateToHostRiskDetailTab(); + }); - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); - }); + after(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); + }); - it('renders the table', () => { - kqlSearch('host.name: "siem-kibana" {enter}'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(4).should('have.text', 'siem-kibana'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(5).should('have.text', 'Mar 10, 2021 @ 14:51:05.766'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(6).should('have.text', '90.00'); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(7).should('have.text', 'Critical'); - }); + it('renders the table', () => { + kqlSearch('host.name: "siem-kibana" {enter}'); + cy.get(HOST_BY_RISK_TABLE_CELL).eq(4).should('have.text', 'siem-kibana'); + cy.get(HOST_BY_RISK_TABLE_CELL).eq(5).should('have.text', 'Mar 10, 2021 @ 14:51:05.766'); + cy.get(HOST_BY_RISK_TABLE_CELL).eq(6).should('have.text', '90.00'); + cy.get(HOST_BY_RISK_TABLE_CELL).eq(7).should('have.text', 'Critical'); + }); - it('filters the table', () => { - openRiskTableFilterAndSelectTheCriticalOption(); + it('filters the table', () => { + openRiskTableFilterAndSelectTheCriticalOption(); - cy.get(HOST_BY_RISK_TABLE_CELL).eq(3).should('not.have.text', 'siem-kibana'); + cy.get(HOST_BY_RISK_TABLE_CELL).eq(3).should('not.have.text', 'siem-kibana'); - removeCriticalFilterAndCloseRiskTableFilter(); - }); + removeCriticalFilterAndCloseRiskTableFilter(); + }); - it('should be able to change items count per page', () => { - selectFiveItemsPerPageOption(); + it('should be able to change items count per page', () => { + selectFiveItemsPerPageOption(); - cy.get(HOST_BY_RISK_TABLE_HOSTNAME_CELL).should('have.length', 5); - }); + cy.get(HOST_BY_RISK_TABLE_HOSTNAME_CELL).should('have.length', 5); + }); - it('should not allow page change when page is empty', () => { - kqlSearch('host.name: "nonexistent_host" {enter}'); - cy.get(HOST_BY_RISK_TABLE_NEXT_PAGE_BUTTON).should(`not.exist`); - }); + it('should not allow page change when page is empty', () => { + kqlSearch('host.name: "nonexistent_host" {enter}'); + cy.get(HOST_BY_RISK_TABLE_NEXT_PAGE_BUTTON).should(`not.exist`); }); }); From 6ea6296d34a6ccf1c87ee310530f41289d59be10 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 10 Jan 2025 08:57:50 +0000 Subject: [PATCH 36/38] remove extra describe block --- .../hosts/hosts_risk_column.cy.ts | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts index d8a9bdc18b7bf..c5b1745feca93 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/hosts/hosts_risk_column.cy.ts @@ -12,27 +12,22 @@ import { TABLE_CELL } from '../../../screens/alerts_details'; import { kqlSearch } from '../../../tasks/security_header'; import { mockRiskEngineEnabled } from '../../../tasks/entity_analytics'; -describe('All hosts table', { tags: ['@ess'] }, () => { - describe('with risk score', { tags: ['@serverless'] }, () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); - }); - - beforeEach(() => { - login(); - mockRiskEngineEnabled(); - }); +describe('All hosts table', { tags: ['@ess', '@serverless'] }, () => { + before(() => { + cy.task('esArchiverLoad', { archiveName: 'risk_scores_new' }); + login(); + mockRiskEngineEnabled(); + }); - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); - }); + after(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new' }); + }); - it('it renders risk column', () => { - visitWithTimeRange(hostsUrl('allHosts')); - kqlSearch('host.name: "siem-kibana" {enter}'); + it('it renders risk column', () => { + visitWithTimeRange(hostsUrl('allHosts')); + kqlSearch('host.name: "siem-kibana" {enter}'); - cy.get('[data-test-subj="tableHeaderCell_node.risk_4"]').should('exist'); - cy.get(TABLE_CELL).eq(4).should('have.text', 'Critical'); - }); + cy.get('[data-test-subj="tableHeaderCell_node.risk_4"]').should('exist'); + cy.get(TABLE_CELL).eq(4).should('have.text', 'Critical'); }); }); From dd58dd96d9d6f1728495f210150321de92382230 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 10 Jan 2025 10:40:55 +0000 Subject: [PATCH 37/38] remove describe block --- .../host_details/risk_tab.cy.ts | 66 +++++++++---------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts index 6a4ce7f7253dd..3468af4c5af89 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/host_details/risk_tab.cy.ts @@ -14,39 +14,37 @@ import { RISK_INFORMATION_FLYOUT_HEADER } from '../../../screens/entity_analytic import { navigateToHostRiskDetailTab } from '../../../tasks/host_risk'; import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; -describe('risk tab', { tags: ['@ess'] }, () => { - describe('with risk score', { tags: ['@serverless'] }, () => { - before(() => { - cy.task('esArchiverLoad', { archiveName: 'risk_scores_new_complete_data' }); - cy.task('esArchiverLoad', { archiveName: 'query_alert', useCreate: true, docsOnly: true }); - }); - - beforeEach(() => { - mockRiskEngineEnabled(); - login(); - }); - - after(() => { - cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_complete_data' }); - deleteAlertsAndRules(); // esArchiverUnload doesn't work properly when using with `useCreate` and `docsOnly` flags - deleteRiskEngineConfiguration(); - }); - - it('renders risk tab', () => { - visitHostDetailsPage('Host-fwarau82er'); - navigateToHostRiskDetailTab(); - - cy.get(ALERTS_COUNT).should('have.text', '1 alert'); - cy.get(ALERT_GRID_CELL).contains('Endpoint Security'); - }); - - it('shows risk information overlay when button is clicked', () => { - visitHostDetailsPage('siem-kibana'); - navigateToHostRiskDetailTab(); - - openRiskInformationFlyout(); - - cy.get(RISK_INFORMATION_FLYOUT_HEADER).contains('Entity Risk Analytics'); - }); +describe('risk tab', { tags: ['@ess', '@serverless'] }, () => { + before(() => { + cy.task('esArchiverLoad', { archiveName: 'risk_scores_new_complete_data' }); + cy.task('esArchiverLoad', { archiveName: 'query_alert', useCreate: true, docsOnly: true }); + }); + + beforeEach(() => { + mockRiskEngineEnabled(); + login(); + }); + + after(() => { + cy.task('esArchiverUnload', { archiveName: 'risk_scores_new_complete_data' }); + deleteAlertsAndRules(); // esArchiverUnload doesn't work properly when using with `useCreate` and `docsOnly` flags + deleteRiskEngineConfiguration(); + }); + + it('renders risk tab', () => { + visitHostDetailsPage('Host-fwarau82er'); + navigateToHostRiskDetailTab(); + + cy.get(ALERTS_COUNT).should('have.text', '1 alert'); + cy.get(ALERT_GRID_CELL).contains('Endpoint Security'); + }); + + it('shows risk information overlay when button is clicked', () => { + visitHostDetailsPage('siem-kibana'); + navigateToHostRiskDetailTab(); + + openRiskInformationFlyout(); + + cy.get(RISK_INFORMATION_FLYOUT_HEADER).contains('Entity Risk Analytics'); }); }); From 2adf1ae6f074aa426a91cf37403b489f07445af9 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Fri, 10 Jan 2025 12:18:13 +0000 Subject: [PATCH 38/38] Revert "remove unused feature flag from test" This reverts commit 818cbdd3f4b70af23f9beb7f634a7b3fbd84e87a. --- .../dashboards/enable_risk_score_redirect.cy.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts index 478f3c741ffd9..40d5623f114fd 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/dashboards/enable_risk_score_redirect.cy.ts @@ -18,6 +18,13 @@ describe( 'Enable risk scores from dashboard', { tags: ['@ess', '@serverless'], + env: { + ftrConfig: { + kbnServerArgs: [ + `--xpack.securitySolution.enableExperimental=${JSON.stringify(['entityStoreDisabled'])}`, + ], + }, + }, }, () => { beforeEach(() => {