Skip to content

Commit 9df3fca

Browse files
[9.1] [Security Solution] Stop showing ML rule installation and upgrade errors on Basic license (#224676) (#226352)
# Backport This will backport the following commits from `main` to `9.1`: - [[Security Solution] Stop showing ML rule installation and upgrade errors on Basic license (#224676)](#224676) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Nikita Indik","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-07-03T08:43:07Z","message":"[Security Solution] Stop showing ML rule installation and upgrade errors on Basic license (#224676)\n\n**Resolves: https://github.com/elastic/kibana/issues/197246**\n**Resolves: https://github.com/elastic/kibana/issues/190753**\n\n**Flaky test runner**:\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8483\n\n\n\n## Summary\nThis PR addresses an issue where users with Basic or Essentials licenses\nencountered errors when attempting to install ML rules. This problem\narose because Basic and Essentials licenses do not permit the\ninstallation or upgrading of ML rules. The PR resolves this by excluding\nML rules from the installation and upgrade `_review` endpoint responses\nfor users with insufficient license.\n\n## Changes\n- `installation/_review` and `upgrade/_review` don't return ML rules for\nusers on Basic/Essentials.\n- `prebuilt_rules/status` does not include ML rules in the count of\nrules to install or upgrade.\n- `installation/_perform` and `upgrade/_perform` now skip ML rules when\ncalled with `ALL_RULES` mode if the license is insufficient.\n- Added API integration tests for installing and upgrading prebuilt\nrules on Basic and Essentials, as well as for checking their status.\n- Now, installation and upgrade errors are displayed in a separate \"red\"\ntoast if any rules fail to install or upgrade.\n- Added tests for toasts as well.\n\n## Screenshots and screen recordings\n### Installing all prebuilt rules\n\n<details>\n <summary>Click to see screen recordings</summary>\n <b>Before</b>\n\n\nhttps://github.com/user-attachments/assets/4e68d4c8-5523-495f-9157-41a5f037d261\n\n <b>After</b>\n\n\nhttps://github.com/user-attachments/assets/465a2bc0-fd89-49cc-9bdb-78d45a6545ea\n\n</details>\n\n### Upgrading all prebuilt rules\n<details>\n <summary>Click to see screen recordings</summary>\n <b>Before</b>\n\n\nhttps://github.com/user-attachments/assets/6e7e4299-2348-43b3-b5f6-ed31cf350a69\n\n <b>After</b>\n\n\nhttps://github.com/user-attachments/assets/84303135-2ed0-4014-a677-d182f2a105c9\n\n</details>\n\n### Errors during installation (unrelated to ML rules)\n<details>\n <summary>Click to see screenshots</summary>\n\n **Before: a green toast with combined success and error text**\n \n<img width=\"2561\" alt=\"installation_toast_before\"\nsrc=\"https://github.com/user-attachments/assets/35d4134b-643b-4e91-8971-de8d63a4c885\"\n/>\n\n\n **After: two toasts – one for success, one for errors**\n\n<img width=\"2561\" alt=\"installation_toast_after_1\"\nsrc=\"https://github.com/user-attachments/assets/cc967445-e8fc-4508-a39d-a13116c4087b\"\n/>\n<img width=\"2561\" alt=\"installation_toast_after_2\"\nsrc=\"https://github.com/user-attachments/assets/0c2fcbae-484f-4458-8151-29de2a09e243\"\n/>\n\n\n</details>\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>","sha":"e19fdf8dd600e849413b680c730b03ac9aa2f725","branchLabelMapping":{"^v9.2.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Detections and Resp","Team: SecuritySolution","Team:Detection Rule Management","Feature:Prebuilt Detection Rules","backport:version","v9.1.0","v8.19.0","v9.2.0","v8.18.4","v9.0.4"],"title":"[Security Solution] Stop showing ML rule installation and upgrade errors on Basic license","number":224676,"url":"https://github.com/elastic/kibana/pull/224676","mergeCommit":{"message":"[Security Solution] Stop showing ML rule installation and upgrade errors on Basic license (#224676)\n\n**Resolves: https://github.com/elastic/kibana/issues/197246**\n**Resolves: https://github.com/elastic/kibana/issues/190753**\n\n**Flaky test runner**:\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8483\n\n\n\n## Summary\nThis PR addresses an issue where users with Basic or Essentials licenses\nencountered errors when attempting to install ML rules. This problem\narose because Basic and Essentials licenses do not permit the\ninstallation or upgrading of ML rules. The PR resolves this by excluding\nML rules from the installation and upgrade `_review` endpoint responses\nfor users with insufficient license.\n\n## Changes\n- `installation/_review` and `upgrade/_review` don't return ML rules for\nusers on Basic/Essentials.\n- `prebuilt_rules/status` does not include ML rules in the count of\nrules to install or upgrade.\n- `installation/_perform` and `upgrade/_perform` now skip ML rules when\ncalled with `ALL_RULES` mode if the license is insufficient.\n- Added API integration tests for installing and upgrading prebuilt\nrules on Basic and Essentials, as well as for checking their status.\n- Now, installation and upgrade errors are displayed in a separate \"red\"\ntoast if any rules fail to install or upgrade.\n- Added tests for toasts as well.\n\n## Screenshots and screen recordings\n### Installing all prebuilt rules\n\n<details>\n <summary>Click to see screen recordings</summary>\n <b>Before</b>\n\n\nhttps://github.com/user-attachments/assets/4e68d4c8-5523-495f-9157-41a5f037d261\n\n <b>After</b>\n\n\nhttps://github.com/user-attachments/assets/465a2bc0-fd89-49cc-9bdb-78d45a6545ea\n\n</details>\n\n### Upgrading all prebuilt rules\n<details>\n <summary>Click to see screen recordings</summary>\n <b>Before</b>\n\n\nhttps://github.com/user-attachments/assets/6e7e4299-2348-43b3-b5f6-ed31cf350a69\n\n <b>After</b>\n\n\nhttps://github.com/user-attachments/assets/84303135-2ed0-4014-a677-d182f2a105c9\n\n</details>\n\n### Errors during installation (unrelated to ML rules)\n<details>\n <summary>Click to see screenshots</summary>\n\n **Before: a green toast with combined success and error text**\n \n<img width=\"2561\" alt=\"installation_toast_before\"\nsrc=\"https://github.com/user-attachments/assets/35d4134b-643b-4e91-8971-de8d63a4c885\"\n/>\n\n\n **After: two toasts – one for success, one for errors**\n\n<img width=\"2561\" alt=\"installation_toast_after_1\"\nsrc=\"https://github.com/user-attachments/assets/cc967445-e8fc-4508-a39d-a13116c4087b\"\n/>\n<img width=\"2561\" alt=\"installation_toast_after_2\"\nsrc=\"https://github.com/user-attachments/assets/0c2fcbae-484f-4458-8151-29de2a09e243\"\n/>\n\n\n</details>\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>","sha":"e19fdf8dd600e849413b680c730b03ac9aa2f725"}},"sourceBranch":"main","suggestedTargetBranches":["9.1","8.19","8.18","9.0"],"targetPullRequestStates":[{"branch":"9.1","label":"v9.1.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.2.0","branchLabelMappingKey":"^v9.2.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/224676","number":224676,"mergeCommit":{"message":"[Security Solution] Stop showing ML rule installation and upgrade errors on Basic license (#224676)\n\n**Resolves: https://github.com/elastic/kibana/issues/197246**\n**Resolves: https://github.com/elastic/kibana/issues/190753**\n\n**Flaky test runner**:\nhttps://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/8483\n\n\n\n## Summary\nThis PR addresses an issue where users with Basic or Essentials licenses\nencountered errors when attempting to install ML rules. This problem\narose because Basic and Essentials licenses do not permit the\ninstallation or upgrading of ML rules. The PR resolves this by excluding\nML rules from the installation and upgrade `_review` endpoint responses\nfor users with insufficient license.\n\n## Changes\n- `installation/_review` and `upgrade/_review` don't return ML rules for\nusers on Basic/Essentials.\n- `prebuilt_rules/status` does not include ML rules in the count of\nrules to install or upgrade.\n- `installation/_perform` and `upgrade/_perform` now skip ML rules when\ncalled with `ALL_RULES` mode if the license is insufficient.\n- Added API integration tests for installing and upgrading prebuilt\nrules on Basic and Essentials, as well as for checking their status.\n- Now, installation and upgrade errors are displayed in a separate \"red\"\ntoast if any rules fail to install or upgrade.\n- Added tests for toasts as well.\n\n## Screenshots and screen recordings\n### Installing all prebuilt rules\n\n<details>\n <summary>Click to see screen recordings</summary>\n <b>Before</b>\n\n\nhttps://github.com/user-attachments/assets/4e68d4c8-5523-495f-9157-41a5f037d261\n\n <b>After</b>\n\n\nhttps://github.com/user-attachments/assets/465a2bc0-fd89-49cc-9bdb-78d45a6545ea\n\n</details>\n\n### Upgrading all prebuilt rules\n<details>\n <summary>Click to see screen recordings</summary>\n <b>Before</b>\n\n\nhttps://github.com/user-attachments/assets/6e7e4299-2348-43b3-b5f6-ed31cf350a69\n\n <b>After</b>\n\n\nhttps://github.com/user-attachments/assets/84303135-2ed0-4014-a677-d182f2a105c9\n\n</details>\n\n### Errors during installation (unrelated to ML rules)\n<details>\n <summary>Click to see screenshots</summary>\n\n **Before: a green toast with combined success and error text**\n \n<img width=\"2561\" alt=\"installation_toast_before\"\nsrc=\"https://github.com/user-attachments/assets/35d4134b-643b-4e91-8971-de8d63a4c885\"\n/>\n\n\n **After: two toasts – one for success, one for errors**\n\n<img width=\"2561\" alt=\"installation_toast_after_1\"\nsrc=\"https://github.com/user-attachments/assets/cc967445-e8fc-4508-a39d-a13116c4087b\"\n/>\n<img width=\"2561\" alt=\"installation_toast_after_2\"\nsrc=\"https://github.com/user-attachments/assets/0c2fcbae-484f-4458-8151-29de2a09e243\"\n/>\n\n\n</details>\n\n---------\n\nCo-authored-by: kibanamachine <[email protected]>","sha":"e19fdf8dd600e849413b680c730b03ac9aa2f725"}},{"branch":"8.18","label":"v8.18.4","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"9.0","label":"v9.0.4","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Nikita Indik <[email protected]>
1 parent ccdd2be commit 9df3fca

File tree

40 files changed

+1163
-232
lines changed

40 files changed

+1163
-232
lines changed

.buildkite/ftr_security_serverless_configs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ enabled:
8181
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/customization_enabled/configs/serverless.config.ts
8282
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/customization_enabled/upgrade_prebuilt_rules/diffable_rule_fields/common_fields/configs/serverless.config.ts
8383
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/customization_enabled/upgrade_prebuilt_rules/diffable_rule_fields/type_specific_fields/configs/serverless.config.ts
84+
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/ml_disabled/configs/serverless_essentials_tier.config.ts
8485
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/serverless.config.ts
8586
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/trial_license_complete_tier/configs/serverless.config.ts
8687
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/basic_license_essentials_tier/configs/serverless.config.ts

.buildkite/ftr_security_stateful_configs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ enabled:
6767
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/customization_enabled/configs/ess.config.ts
6868
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/customization_enabled/upgrade_prebuilt_rules/diffable_rule_fields/common_fields/configs/ess.config.ts
6969
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/customization_enabled/upgrade_prebuilt_rules/diffable_rule_fields/type_specific_fields/configs/ess.config.ts
70+
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/ml_disabled/configs/ess_basic_license.config.ts
7071
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_bulk_actions/trial_license_complete_tier/configs/ess.config.ts
7172
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/trial_license_complete_tier/configs/ess.config.ts
7273
- x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_delete/basic_license_essentials_tier/configs/ess.config.ts

x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/prebuilt_rules/perform_rule_upgrade/perform_rule_upgrade_route.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ describe('Perform Rule Upgrade Route Schemas', () => {
261261
);
262262
});
263263

264-
test('rejects paylaod with missing rules array', () => {
264+
test('rejects payload with missing rules array', () => {
265265
const invalid = { ...validRequest, rules: undefined };
266266
const result = UpgradeSpecificRulesRequest.safeParse(invalid);
267267
expectParseError(result);

x-pack/solutions/security/plugins/security_solution/public/common/components/utils.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useMemo, useState } from 'react';
1010
import useResizeObserver from 'use-resize-observer/polyfilled';
1111
import { niceTimeFormatByDay, timeFormatter } from '@elastic/charts';
1212
import moment from 'moment-timezone';
13+
import type { IToasts } from '@kbn/core/public';
1314

1415
export const getDaysDiff = (minDate: moment.Moment, maxDate: moment.Moment) => {
1516
const diff = maxDate.diff(minDate, 'days');
@@ -35,3 +36,32 @@ export const useThrottledResizeObserver = (wait = 100) => {
3536

3637
return { ref, ...size };
3738
};
39+
40+
/**
41+
* Displays an error toast with a specified title and a short message.
42+
* Also allows to set a detailed message that will appear in the modal when user clicks the "See full error" button.
43+
*
44+
* @param title The title of the toast notification. Appears in both the toast header and the modal header.
45+
* @param shortMessage An optional short message. Appears under toast header.
46+
* @param fullMessage The full error message. Appears in the modal when user clicks the "See full error" button.
47+
* @param toasts The toasts service instance.
48+
*/
49+
export function showErrorToast({
50+
title,
51+
shortMessage,
52+
fullMessage,
53+
toasts,
54+
}: {
55+
title: string;
56+
shortMessage?: string;
57+
fullMessage: string;
58+
toasts: IToasts;
59+
}) {
60+
const error = new Error('Error details');
61+
error.stack = fullMessage;
62+
toasts.addError(error, {
63+
title,
64+
// Fall back to a space to ensure that the toast component does not render its default message
65+
toastMessage: shortMessage ?? ' ',
66+
});
67+
}

x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/translations.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const RULE_INSTALLATION_FAILED = i18n.translate(
1616

1717
export const INSTALL_RULE_SUCCESS = (succeeded: number) =>
1818
i18n.translate('xpack.securitySolution.detectionEngine.prebuiltRules.toast.installRuleSuccess', {
19-
defaultMessage: '{succeeded, plural, one {# rule} other {# rules}} installed successfully.',
19+
defaultMessage: '{succeeded, plural, one {# rule} other {# rules}} installed successfully',
2020
values: { succeeded },
2121
});
2222

@@ -29,7 +29,7 @@ export const INSTALL_RULE_SKIPPED = (skipped: number) =>
2929

3030
export const INSTALL_RULE_FAILED = (failed: number) =>
3131
i18n.translate('xpack.securitySolution.detectionEngine.prebuiltRules.toast.installRuleFailed', {
32-
defaultMessage: '{failed, plural, one {# rule} other {# rules}} failed to install.',
32+
defaultMessage: '{failed, plural, one {# rule} other {# rules}} failed to install',
3333
values: { failed },
3434
});
3535

@@ -42,7 +42,7 @@ export const RULE_UPGRADE_FAILED = i18n.translate(
4242

4343
export const UPGRADE_RULE_SUCCESS = (succeeded: number) =>
4444
i18n.translate('xpack.securitySolution.detectionEngine.prebuiltRules.toast.upgradeRuleSuccess', {
45-
defaultMessage: '{succeeded, plural, one {# rule} other {# rules}} updated successfully.',
45+
defaultMessage: '{succeeded, plural, one {# rule} other {# rules}} updated successfully',
4646
values: { succeeded },
4747
});
4848

@@ -55,7 +55,7 @@ export const UPGRADE_RULE_SKIPPED = (skipped: number) =>
5555

5656
export const UPGRADE_RULE_FAILED = (failed: number) =>
5757
i18n.translate('xpack.securitySolution.detectionEngine.prebuiltRules.toast.upgradeRuleFailed', {
58-
defaultMessage: '{failed, plural, one {# rule} other {# rules}} failed to update.',
58+
defaultMessage: '{failed, plural, one {# rule} other {# rules}} failed to update',
5959
values: { failed },
6060
});
6161

x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/use_perform_rule_install.ts

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,58 +4,81 @@
44
* 2.0; you may not use this file except in compliance with the Elastic License
55
* 2.0.
66
*/
7-
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
7+
import type { IToasts } from '@kbn/core/public';
8+
import type { PerformRuleInstallationResponseBody } from '../../../../../common/api/detection_engine';
9+
import { useToasts } from '../../../../common/lib/kibana';
810
import { usePerformAllRulesInstallMutation } from '../../api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation';
911
import { usePerformSpecificRulesInstallMutation } from '../../api/hooks/prebuilt_rules/use_perform_specific_rules_install_mutation';
1012

1113
import * as i18n from './translations';
14+
import { showErrorToast } from '../../../../common/components/utils';
1215

1316
export const usePerformInstallAllRules = () => {
14-
const { addError, addSuccess } = useAppToasts();
17+
const toasts = useToasts();
1518

1619
return usePerformAllRulesInstallMutation({
17-
onError: (err) => {
18-
addError(err, { title: i18n.RULE_INSTALLATION_FAILED });
20+
onError: (error) => {
21+
handleErrorResponse(error, toasts);
1922
},
2023
onSuccess: (result) => {
21-
addSuccess(getSuccessToastMessage(result));
24+
handleSuccessResponse(result, toasts);
2225
},
2326
});
2427
};
2528

2629
export const usePerformInstallSpecificRules = () => {
27-
const { addError, addSuccess } = useAppToasts();
30+
const toasts = useToasts();
2831

2932
return usePerformSpecificRulesInstallMutation({
30-
onError: (err) => {
31-
addError(err, { title: i18n.RULE_INSTALLATION_FAILED });
33+
onError: (error) => {
34+
handleErrorResponse(error, toasts);
3235
},
3336
onSuccess: (result) => {
34-
addSuccess(getSuccessToastMessage(result));
37+
handleSuccessResponse(result, toasts);
3538
},
3639
});
3740
};
3841

39-
const getSuccessToastMessage = (result: {
42+
function handleErrorResponse(error: unknown, toasts: IToasts) {
43+
showErrorToast({
44+
title: i18n.RULE_INSTALLATION_FAILED,
45+
fullMessage: JSON.stringify(error, null, 2),
46+
toasts,
47+
});
48+
}
49+
50+
function handleSuccessResponse(result: PerformRuleInstallationResponseBody, toasts: IToasts) {
51+
const successToastMessage = getSuccessToastMessage(result);
52+
if (successToastMessage) {
53+
toasts.addSuccess(successToastMessage);
54+
}
55+
56+
if (result.summary.failed > 0) {
57+
showErrorToast({
58+
title: i18n.INSTALL_RULE_FAILED(result.summary.failed),
59+
fullMessage: JSON.stringify(result.errors, null, 2),
60+
toasts,
61+
});
62+
}
63+
}
64+
65+
function getSuccessToastMessage(result: {
4066
summary: {
4167
total: number;
4268
succeeded: number;
4369
skipped: number;
4470
failed: number;
4571
};
46-
}) => {
72+
}): string {
4773
const toastMessages: string[] = [];
4874
const {
49-
summary: { succeeded, skipped, failed },
75+
summary: { succeeded, skipped },
5076
} = result;
5177
if (succeeded > 0) {
5278
toastMessages.push(i18n.INSTALL_RULE_SUCCESS(succeeded));
5379
}
5480
if (skipped > 0) {
5581
toastMessages.push(i18n.INSTALL_RULE_SKIPPED(skipped));
5682
}
57-
if (failed > 0) {
58-
toastMessages.push(i18n.INSTALL_RULE_FAILED(failed));
59-
}
6083
return toastMessages.join(' ');
61-
};
84+
}

x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management/logic/prebuilt_rules/use_perform_rule_upgrade.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,42 @@
44
* 2.0; you may not use this file except in compliance with the Elastic License
55
* 2.0.
66
*/
7-
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
7+
8+
import { showErrorToast } from '../../../../common/components/utils';
9+
import { useToasts } from '../../../../common/lib/kibana';
810
import { usePerformRulesUpgradeMutation } from '../../api/hooks/prebuilt_rules/use_perform_rules_upgrade_mutation';
911

1012
import * as i18n from './translations';
1113

1214
export const usePerformUpgradeRules = () => {
13-
const { addError, addSuccess } = useAppToasts();
15+
const toasts = useToasts();
1416

1517
return usePerformRulesUpgradeMutation({
16-
onError: (err) => {
17-
addError(err, { title: i18n.RULE_UPGRADE_FAILED });
18+
onError: (error) => {
19+
showErrorToast({
20+
title: i18n.RULE_UPGRADE_FAILED,
21+
fullMessage: JSON.stringify(error, null, 2),
22+
toasts,
23+
});
1824
},
1925
onSuccess: (result, vars) => {
2026
if (vars.dry_run) {
2127
// This is a preflight check, no need to show toast
2228
return;
2329
}
24-
addSuccess(getSuccessToastMessage(result));
30+
31+
const successToastMessage = getSuccessToastMessage(result);
32+
if (successToastMessage) {
33+
toasts.addSuccess(getSuccessToastMessage(result));
34+
}
35+
36+
if (result.summary.failed > 0) {
37+
showErrorToast({
38+
title: i18n.UPGRADE_RULE_FAILED(result.summary.failed),
39+
fullMessage: JSON.stringify(result.errors, null, 2),
40+
toasts,
41+
});
42+
}
2543
},
2644
});
2745
};
@@ -36,16 +54,13 @@ const getSuccessToastMessage = (result: {
3654
}) => {
3755
const toastMessage: string[] = [];
3856
const {
39-
summary: { succeeded, skipped, failed },
57+
summary: { succeeded, skipped },
4058
} = result;
4159
if (succeeded > 0) {
4260
toastMessage.push(i18n.UPGRADE_RULE_SUCCESS(succeeded));
4361
}
4462
if (skipped > 0) {
4563
toastMessage.push(i18n.UPGRADE_RULE_SKIPPED(skipped));
4664
}
47-
if (failed > 0) {
48-
toastMessage.push(i18n.UPGRADE_RULE_FAILED(failed));
49-
}
5065
return toastMessage.join(' ');
5166
};

x-pack/solutions/security/plugins/security_solution/public/detection_engine/rule_management_ui/components/rule_import_modal/utils.ts

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import type { IToasts } from '@kbn/core/public';
1111
import * as i18n from './translations';
1212

1313
import type { ErrorSchema, ImportRulesResponse } from '../../../../../common/api/detection_engine';
14+
import { showErrorToast } from '../../../../common/components/utils';
1415

1516
export function getFailedConnectorsCount(actionConnectorsErrors: ErrorSchema[]) {
1617
const connectorIds = new Set(
@@ -46,25 +47,6 @@ function getUserFriendlyConnectorMessages(actionConnectorsErrors: ErrorSchema[])
4647
return mappedErrors;
4748
}
4849

49-
function showErrorToast({
50-
title,
51-
shortMessage,
52-
fullMessage,
53-
toasts,
54-
}: {
55-
title: string;
56-
shortMessage: string;
57-
fullMessage: string;
58-
toasts: IToasts;
59-
}) {
60-
const error = new Error('Error details');
61-
error.stack = fullMessage;
62-
toasts.addError(error, {
63-
title,
64-
toastMessage: shortMessage,
65-
});
66-
}
67-
6850
export function showToast({
6951
importResponse,
7052
toasts,

x-pack/solutions/security/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/api/get_prebuilt_rules_status/get_prebuilt_rules_status_route.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { SecuritySolutionPluginRouter } from '../../../../../types';
1212
import { buildSiemResponse } from '../../../routes/utils';
1313
import { createPrebuiltRuleAssetsClient } from '../../logic/rule_assets/prebuilt_rule_assets_client';
1414
import { createPrebuiltRuleObjectsClient } from '../../logic/rule_objects/prebuilt_rule_objects_client';
15+
import { excludeLicenseRestrictedRules, getPossibleUpgrades } from '../../logic/utils';
1516

1617
export const getPrebuiltRulesStatusRoute = (router: SecuritySolutionPluginRouter) => {
1718
router.versioned
@@ -33,11 +34,12 @@ export const getPrebuiltRulesStatusRoute = (router: SecuritySolutionPluginRouter
3334
const siemResponse = buildSiemResponse(response);
3435

3536
try {
36-
const ctx = await context.resolve(['core', 'alerting']);
37+
const ctx = await context.resolve(['core', 'alerting', 'securitySolution']);
3738
const soClient = ctx.core.savedObjects.client;
3839
const rulesClient = await ctx.alerting.getRulesClient();
3940
const ruleAssetsClient = createPrebuiltRuleAssetsClient(soClient);
4041
const ruleObjectsClient = createPrebuiltRuleObjectsClient(rulesClient);
42+
const mlAuthz = ctx.securitySolution.getMlAuthz();
4143

4244
const currentRuleVersions = await ruleObjectsClient.fetchInstalledRuleVersions();
4345
const latestRuleVersions = await ruleAssetsClient.fetchLatestVersions();
@@ -47,24 +49,39 @@ export const getPrebuiltRulesStatusRoute = (router: SecuritySolutionPluginRouter
4749
const latestRuleVersionsMap = new Map(
4850
latestRuleVersions.map((rule) => [rule.rule_id, rule])
4951
);
50-
const installableRules = latestRuleVersions.filter(
52+
const allInstallableRules = latestRuleVersions.filter(
5153
(rule) => !currentRuleVersionsMap.has(rule.rule_id)
5254
);
53-
const upgradeableRules = currentRuleVersions.filter((rule) => {
54-
const latestVersion = latestRuleVersionsMap.get(rule.rule_id);
55-
return latestVersion != null && rule.version < latestVersion.version;
56-
});
55+
56+
const installableRuleAssets = await excludeLicenseRestrictedRules(
57+
allInstallableRules,
58+
mlAuthz
59+
);
60+
61+
const upgradableRules = await getPossibleUpgrades(
62+
currentRuleVersions,
63+
latestRuleVersionsMap,
64+
mlAuthz
65+
);
66+
67+
const upgradeableRulesTags = upgradableRules.reduce<string[]>((tags, rule) => {
68+
const ruleTags = currentRuleVersionsMap.get(rule.rule_id)?.tags;
69+
if (ruleTags) {
70+
tags.push(...ruleTags);
71+
}
72+
return tags;
73+
}, []);
5774

5875
const body: GetPrebuiltRulesStatusResponseBody = {
5976
stats: {
6077
num_prebuilt_rules_installed: currentRuleVersions.length,
61-
num_prebuilt_rules_to_install: installableRules.length,
62-
num_prebuilt_rules_to_upgrade: upgradeableRules.length,
78+
num_prebuilt_rules_to_install: installableRuleAssets.length,
79+
num_prebuilt_rules_to_upgrade: upgradableRules.length,
6380
num_prebuilt_rules_total_in_package: latestRuleVersions.length,
6481
},
6582
aggregated_fields: {
6683
upgradeable_rules: {
67-
tags: [...new Set(upgradeableRules.flatMap((rule) => rule.tags))],
84+
tags: [...new Set(upgradeableRulesTags)],
6885
},
6986
},
7087
};

0 commit comments

Comments
 (0)