From fdb45a90ffe5b77d7696f58f7092480b42340527 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 12 Feb 2024 14:09:23 +0100 Subject: [PATCH] [Security Solution] Fix losing data upon prebuilt rule upgrade to a new version in which the rule's type is different (#176421) **Fixes:** https://github.com/elastic/kibana/issues/169480 ## Summary This PR fixes losing the following rule data upon prebuilt rule upgrade to a new version in which the rule's type is different - Saved Object id - exceptions list (default and shared) - Timeline id - Timeline title ## Details The problem occurs when user upgrades a prebuilt rule to a newer version which has a different rule type. Checking the code it's not so hard to find [`upgradeRule()`](https://github.com/elastic/kibana/blob/main/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts#L49) function which performs prebuilt rule upgrade. It has the following comment > If we're trying to change the type of a prepackaged rule, we need to delete the old one and replace it with the new rule, keeping the enabled setting, actions, throttle, id, and exception lists from the old rule. Looking below in the code it's clear that only enabled state and actions get restored upon rule upgrade. Missing to restore `exceptions lists` leads to disappearing exceptions upon rule upgrade. On top of this `execution results` and `execution events` also get lost due to missing to restore saved object `id`. Execution log isn't gone anywhere but can't be bound to a new id. Direct links to rule details page won't work neither after upgrade. This PR fixes the problem by restoring rule bound data after upgrade. FTR tests were restructured to accommodate extra tests to cover this bug fix. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --- .../installation_and_upgrade.md | 34 ++ .../upgrade_prebuilt_rules.test.ts | 184 ++++++- .../rule_objects/upgrade_prebuilt_rules.ts | 43 +- .../rule_assets/prebuilt_rule_asset.mock.ts | 24 +- .../config/ess/config.base.ts | 16 +- .../config/serverless/config.base.ts | 2 + .../config/shared.ts | 32 ++ .../trial_license_complete_tier/index.ts | 5 +- .../install_and_upgrade_prebuilt_rules.ts | 450 ------------------ .../install_prebuilt_rules.ts | 133 ++++++ ...prebuilt_rules_with_historical_versions.ts | 160 +++++++ .../upgrade_prebuilt_rules.ts | 268 +++++++++++ ...prebuilt_rules_with_historical_versions.ts | 152 ++++++ .../export_rules.ts | 3 +- .../create_prebuilt_rule_saved_objects.ts | 5 +- .../tsconfig.json | 1 + 16 files changed, 991 insertions(+), 521 deletions(-) create mode 100644 x-pack/test/security_solution_api_integration/config/shared.ts delete mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_and_upgrade_prebuilt_rules.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules_with_historical_versions.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts diff --git a/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md index 19a15b64b5046..b60609b45be9d 100644 --- a/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md +++ b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/installation_and_upgrade.md @@ -13,6 +13,7 @@ Status: `in progress`. The current test plan matches `Milestone 2` of the [Rule - [Non-functional requirements](#non-functional-requirements) - [Functional requirements](#functional-requirements) - [Scenarios](#scenarios) + - [Package installation](#package-installation) - [**Scenario: Package is installed via Fleet**](#scenario-package-is-installed-via-fleet) - [**Scenario: Package is installed via bundled Fleet package in Kibana**](#scenario-package-is-installed-via-bundled-fleet-package-in-kibana) @@ -63,6 +64,9 @@ Status: `in progress`. The current test plan matches `Milestone 2` of the [Rule - [**Scenario: Properties with semantically equal values should not be shown as modified**](#scenario-properties-with-semantically-equal-values-should-not-be-shown-as-modified) - [**Scenario: Unchanged sections of a rule should be hidden by default**](#scenario-unchanged-sections-of-a-rule-should-be-hidden-by-default) - [**Scenario: Properties should be sorted alphabetically**](#scenario-properties-should-be-sorted-alphabetically) + - [Rule upgrade workflow: preserving rule bound data](#rule-upgrade-workflow-preserving-rule-bound-data) + - [**Scenario: Rule bound data is preserved after upgrading a rule to a newer version with the same rule type**](#scenario-rule-bound-data-is-preserved-after-upgrading-a-rule-to-a-newer-version-with-the-same-rule-type) + - [**Scenario: Rule bound data is preserved after upgrading a rule to a newer version with a different rule type**](#scenario-rule-bound-data-is-preserved-after-upgrading-a-rule-to-a-newer-version-with-a-different-rule-type) - [Rule upgrade workflow: misc cases](#rule-upgrade-workflow-misc-cases) - [**Scenario: User doesn't see the Rule Updates tab until the package installation is completed**](#scenario-user-doesnt-see-the-rule-updates-tab-until-the-package-installation-is-completed) - [Error handling](#error-handling) @@ -949,6 +953,36 @@ When a user expands all hidden sections Then all properties of the rule should be sorted alphabetically ``` +### Rule upgrade workflow: preserving rule bound data + +#### **Scenario: Rule bound data is preserved after upgrading a rule to a newer version with the same rule type** + +**Automation**: 1 unit test per case, 1 integration test + +```Gherkin +Given a prebuilt rule is installed in Kibana +And this rule has an update available +And the update has the same rule type +When a user upgrades the rule +Then the rule bound data should be preserved +``` + +Examples: generated alerts, exception lists (rule exception list, shared exception list, endpoint exception list), timeline reference, actions, enabled state, execution results and execution events. + +#### **Scenario: Rule bound data is preserved after upgrading a rule to a newer version with a different rule type** + +**Automation**: 1 unit test per case, 1 integration test + +```Gherkin +Given a prebuilt rule is installed in Kibana +And this rule has an update available +And the update has a different rule type +When a user upgrades the rule +Then the rule bound data should be preserved +``` + +Examples: generated alerts, exception lists (rule exception list, shared exception list, endpoint exception list), timeline reference, actions, enabled state, execution results and execution events. + ### Rule upgrade workflow: misc cases #### **Scenario: User doesn't see the Rule Updates tab until the package installation is completed** diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.test.ts index 2990533dc0f89..f4845be99c68e 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.test.ts @@ -5,17 +5,23 @@ * 2.0. */ +import { omit } from 'lodash'; import { rulesClientMock } from '@kbn/alerting-plugin/server/mocks'; import { getRuleMock, getFindResultWithSingleHit, + getFindResultWithMultiHits, } from '../../../routes/__mocks__/request_responses'; import { upgradePrebuiltRules } from './upgrade_prebuilt_rules'; import { patchRules } from '../../../rule_management/logic/crud/patch_rules'; +import { createRules } from '../../../rule_management/logic/crud/create_rules'; +import { deleteRules } from '../../../rule_management/logic/crud/delete_rules'; import { getPrebuiltRuleMock, getPrebuiltThreatMatchRuleMock } from '../../mocks'; -import { getThreatRuleParams } from '../../../rule_schema/mocks'; +import { getQueryRuleParams, getThreatRuleParams } from '../../../rule_schema/mocks'; jest.mock('../../../rule_management/logic/crud/patch_rules'); +jest.mock('../../../rule_management/logic/crud/create_rules'); +jest.mock('../../../rule_management/logic/crud/delete_rules'); describe('updatePrebuiltRules', () => { let rulesClient: ReturnType; @@ -24,35 +30,173 @@ describe('updatePrebuiltRules', () => { rulesClient = rulesClientMock.create(); }); - it('should omit actions and enabled when calling patchRules', async () => { + describe('when upgrading a prebuilt rule to a newer version with the same rule type', () => { + const prepackagedRule = getPrebuiltRuleMock({ + rule_id: 'rule-to-upgrade', + }); + + beforeEach(() => { + const installedRule = getRuleMock( + getQueryRuleParams({ + ruleId: 'rule-to-upgrade', + }) + ); + + rulesClient.find.mockResolvedValue( + getFindResultWithMultiHits({ + data: [installedRule], + }) + ); + }); + + it('patches existing rule with incoming version data', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(patchRules).toHaveBeenCalledWith( + expect.objectContaining({ + nextParams: expect.objectContaining(prepackagedRule), + }) + ); + }); + + it('makes sure enabled state is preserved', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(patchRules).toHaveBeenCalledWith( + expect.objectContaining({ + nextParams: expect.objectContaining({ + enabled: undefined, + }), + }) + ); + }); + }); + + describe('when upgrading a prebuilt rule to a newer version with a different rule type', () => { + const prepackagedRule = getPrebuiltRuleMock({ + rule_id: 'rule-to-upgrade', + type: 'eql', + language: 'eql', + query: 'host where host.name == "something"', + }); const actions = [ { group: 'group', id: 'id', - action_type_id: 'action_type_id', + actionTypeId: 'action_type_id', params: {}, }, ]; - const prepackagedRule = getPrebuiltRuleMock(); - rulesClient.find.mockResolvedValue(getFindResultWithSingleHit()); + const installedRule = getRuleMock( + getQueryRuleParams({ + ruleId: 'rule-to-upgrade', + type: 'query', + exceptionsList: [ + { + id: 'exception_list_1', + list_id: 'exception_list_1', + namespace_type: 'agnostic', + type: 'rule_default', + }, + ], + timelineId: 'some-timeline-id', + timelineTitle: 'Some timeline title', + }), + { + id: 'installed-rule-so-id', + actions, + } + ); - await upgradePrebuiltRules(rulesClient, [{ ...prepackagedRule, actions }]); + beforeEach(() => { + rulesClient.find.mockResolvedValue( + getFindResultWithMultiHits({ + data: [installedRule], + }) + ); + }); - expect(patchRules).toHaveBeenCalledWith( - expect.objectContaining({ - nextParams: expect.objectContaining({ - actions: undefined, - }), - }) - ); + it('deletes rule before creation', async () => { + let lastCalled!: string; - expect(patchRules).toHaveBeenCalledWith( - expect.objectContaining({ - nextParams: expect.objectContaining({ - enabled: undefined, - }), - }) - ); + (deleteRules as jest.Mock).mockImplementation(() => (lastCalled = 'deleteRules')); + (createRules as jest.Mock).mockImplementation(() => (lastCalled = 'createRules')); + + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(deleteRules).toHaveBeenCalledTimes(1); + expect(createRules).toHaveBeenCalledTimes(1); + expect(lastCalled).toBe('createRules'); + }); + + it('recreates a rule with incoming version data', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(createRules).toHaveBeenCalledWith( + expect.objectContaining({ + immutable: true, + params: expect.objectContaining(prepackagedRule), + }) + ); + }); + + it('restores saved object id', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(createRules).toHaveBeenCalledWith( + expect.objectContaining({ + id: 'installed-rule-so-id', + }) + ); + }); + + it('restores enabled state', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(createRules).toHaveBeenCalledWith( + expect.objectContaining({ + params: expect.objectContaining({ enabled: installedRule.enabled }), + }) + ); + }); + + it('restores actions', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(createRules).toHaveBeenCalledWith( + expect.objectContaining({ + params: expect.objectContaining({ + actions: actions.map((a) => ({ + ...omit(a, 'actionTypeId'), + action_type_id: a.actionTypeId, + })), + }), + }) + ); + }); + + it('restores exceptions list', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(createRules).toHaveBeenCalledWith( + expect.objectContaining({ + params: expect.objectContaining({ exceptions_list: installedRule.params.exceptionsList }), + }) + ); + }); + + it('restores timeline reference', async () => { + await upgradePrebuiltRules(rulesClient, [prepackagedRule]); + + expect(createRules).toHaveBeenCalledWith( + expect.objectContaining({ + params: expect.objectContaining({ + timeline_id: installedRule.params.timelineId, + timeline_title: installedRule.params.timelineTitle, + }), + }) + ); + }); }); it('should update threat match rules', async () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts index a06b5dc17825f..98afa86114e4f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/rule_objects/upgrade_prebuilt_rules.ts @@ -72,36 +72,39 @@ const upgradeRule = async ( return createRules({ rulesClient, immutable: true, + id: existingRule.id, params: { ...rule, // Force the prepackaged rule to use the enabled state from the existing rule, // regardless of what the prepackaged rule says enabled: existingRule.enabled, + exceptions_list: existingRule.params.exceptionsList, actions: existingRule.actions.map(transformAlertToRuleAction), + timeline_id: existingRule.params.timelineId, + timeline_title: existingRule.params.timelineTitle, }, }); - } else { - await patchRules({ - rulesClient, - existingRule, - nextParams: { - ...rule, - // Force enabled to use the enabled state from the existing rule by passing in undefined to patchRules - enabled: undefined, - actions: undefined, - }, - }); + } - const updatedRule = await readRules({ - rulesClient, - ruleId: rule.rule_id, - id: undefined, - }); + await patchRules({ + rulesClient, + existingRule, + nextParams: { + ...rule, + // Force enabled to use the enabled state from the existing rule by passing in undefined to patchRules + enabled: undefined, + }, + }); - if (!updatedRule) { - throw new PrepackagedRulesError(`Rule ${rule.rule_id} not found after upgrade`, 500); - } + const updatedRule = await readRules({ + rulesClient, + ruleId: rule.rule_id, + id: undefined, + }); - return updatedRule; + if (!updatedRule) { + throw new PrepackagedRulesError(`Rule ${rule.rule_id} not found after upgrade`, 500); } + + return updatedRule; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts index 8329204637c3b..c73203c2871ab 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/model/rule_assets/prebuilt_rule_asset.mock.ts @@ -7,17 +7,19 @@ import type { PrebuiltRuleAsset } from './prebuilt_rule_asset'; -export const getPrebuiltRuleMock = (): PrebuiltRuleAsset => ({ - description: 'some description', - name: 'Query with a rule id', - query: 'user.name: root or user.name: admin', - severity: 'high', - type: 'query', - risk_score: 55, - language: 'kuery', - rule_id: 'rule-1', - version: 1, -}); +export const getPrebuiltRuleMock = (rewrites?: Partial): PrebuiltRuleAsset => + ({ + description: 'some description', + name: 'Query with a rule id', + query: 'user.name: root or user.name: admin', + severity: 'high', + type: 'query', + risk_score: 55, + language: 'kuery', + rule_id: 'rule-1', + version: 1, + ...rewrites, + } as PrebuiltRuleAsset); export const getPrebuiltRuleWithExceptionsMock = (): PrebuiltRuleAsset => ({ description: 'A rule with an exception list', diff --git a/x-pack/test/security_solution_api_integration/config/ess/config.base.ts b/x-pack/test/security_solution_api_integration/config/ess/config.base.ts index 6a9232050c3f0..c105b81263362 100644 --- a/x-pack/test/security_solution_api_integration/config/ess/config.base.ts +++ b/x-pack/test/security_solution_api_integration/config/ess/config.base.ts @@ -8,6 +8,7 @@ import { CA_CERT_PATH } from '@kbn/dev-utils'; import { FtrConfigProviderContext, kbnTestConfig, kibanaTestUser } from '@kbn/test'; import { services } from '../../../api_integration/services'; +import { PRECONFIGURED_ACTION_CONNECTORS } from '../shared'; interface CreateTestConfigOptions { license: string; @@ -85,20 +86,7 @@ export function createTestConfig(options: CreateTestConfigOptions, testFiles?: s 'alertSuppressionForIndicatorMatchRuleEnabled', ])}`, '--xpack.task_manager.poll_interval=1000', - `--xpack.actions.preconfigured=${JSON.stringify({ - 'my-test-email': { - actionTypeId: '.email', - name: 'TestEmail#xyz', - config: { - from: 'me@test.com', - service: '__json', - }, - secrets: { - user: 'user', - password: 'password', - }, - }, - })}`, + `--xpack.actions.preconfigured=${JSON.stringify(PRECONFIGURED_ACTION_CONNECTORS)}`, ...(ssl ? [ `--elasticsearch.hosts=${servers.elasticsearch.protocol}://${servers.elasticsearch.hostname}:${servers.elasticsearch.port}`, diff --git a/x-pack/test/security_solution_api_integration/config/serverless/config.base.ts b/x-pack/test/security_solution_api_integration/config/serverless/config.base.ts index 374538e593efa..ae3b17ce086c3 100644 --- a/x-pack/test/security_solution_api_integration/config/serverless/config.base.ts +++ b/x-pack/test/security_solution_api_integration/config/serverless/config.base.ts @@ -12,6 +12,7 @@ export interface CreateTestConfigOptions { kbnTestServerEnv?: Record; } import { services } from '../../../../test_serverless/api_integration/services'; +import { PRECONFIGURED_ACTION_CONNECTORS } from '../shared'; export function createTestConfig(options: CreateTestConfigOptions) { return async ({ readConfigFile }: FtrConfigProviderContext) => { @@ -28,6 +29,7 @@ export function createTestConfig(options: CreateTestConfigOptions) { serverArgs: [ ...svlSharedConfig.get('kbnTestServer.serverArgs'), '--serverless=security', + `--xpack.actions.preconfigured=${JSON.stringify(PRECONFIGURED_ACTION_CONNECTORS)}`, ...(options.kbnTestServerArgs || []), ], env: { diff --git a/x-pack/test/security_solution_api_integration/config/shared.ts b/x-pack/test/security_solution_api_integration/config/shared.ts new file mode 100644 index 0000000000000..f8c55deef484a --- /dev/null +++ b/x-pack/test/security_solution_api_integration/config/shared.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Connector } from '@kbn/actions-plugin/server/application/connector/types'; + +interface PreconfiguredConnector extends Pick { + secrets: { + user: string; + password: string; + }; +} + +export const PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID = 'my-test-email'; + +export const PRECONFIGURED_ACTION_CONNECTORS: Record = { + [PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID]: { + actionTypeId: '.email', + name: 'TestEmail#xyz', + config: { + from: 'me@test.com', + service: '__json', + }, + secrets: { + user: 'user', + password: 'password', + }, + }, +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index 16c37cd09eb5b..5625d00b5293d 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -11,7 +11,10 @@ export default ({ loadTestFile }: FtrProviderContext): void => { describe('Rules Management - Prebuilt Rules - Prebuilt Rules Management', function () { loadTestFile(require.resolve('./get_prebuilt_rules_status')); loadTestFile(require.resolve('./get_prebuilt_timelines_status')); - loadTestFile(require.resolve('./install_and_upgrade_prebuilt_rules')); + loadTestFile(require.resolve('./install_prebuilt_rules')); + loadTestFile(require.resolve('./install_prebuilt_rules_with_historical_versions')); + loadTestFile(require.resolve('./upgrade_prebuilt_rules')); + loadTestFile(require.resolve('./upgrade_prebuilt_rules_with_historical_versions')); loadTestFile(require.resolve('./fleet_integration')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_and_upgrade_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_and_upgrade_prebuilt_rules.ts deleted file mode 100644 index c3d39c532f9ca..0000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_and_upgrade_prebuilt_rules.ts +++ /dev/null @@ -1,450 +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 expect from 'expect'; -import { FtrProviderContext } from '../../../../../../ftr_provider_context'; -import { - deleteAllRules, - deleteAllTimelines, - deleteAllPrebuiltRuleAssets, - createRuleAssetSavedObject, - createPrebuiltRuleAssetSavedObjects, - installPrebuiltRulesAndTimelines, - deleteRule, - getPrebuiltRulesAndTimelinesStatus, - createHistoricalPrebuiltRuleAssetSavedObjects, - getPrebuiltRulesStatus, - installPrebuiltRules, - getInstalledRules, - upgradePrebuiltRules, -} from '../../../../utils'; - -export default ({ getService }: FtrProviderContext): void => { - const es = getService('es'); - const supertest = getService('supertest'); - const log = getService('log'); - - describe('@ess @serverless @skipInQA install and upgrade prebuilt rules with mock rule assets', () => { - beforeEach(async () => { - await deleteAllRules(supertest, log); - await deleteAllTimelines(es, log); - await deleteAllPrebuiltRuleAssets(es, log); - }); - - describe(`rule package without historical versions`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), - createRuleAssetSavedObject({ rule_id: 'rule-3', version: 3 }), - createRuleAssetSavedObject({ rule_id: 'rule-4', version: 4 }), - ]; - const RULES_COUNT = 4; - - describe('using legacy endpoint', () => { - it('should install prebuilt rules', async () => { - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - const body = await installPrebuiltRulesAndTimelines(es, supertest); - - expect(body.rules_installed).toBe(RULES_COUNT); - expect(body.rules_updated).toBe(0); - }); - - it('should install correct prebuilt rule versions', async () => { - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Get installed rules - const rulesResponse = await getInstalledRules(supertest); - - // Check that all prebuilt rules were actually installed and their versions match the latest - expect(rulesResponse.total).toBe(RULES_COUNT); - expect(rulesResponse.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ rule_id: 'rule-1', version: 1 }), - expect.objectContaining({ rule_id: 'rule-2', version: 2 }), - expect.objectContaining({ rule_id: 'rule-3', version: 3 }), - expect.objectContaining({ rule_id: 'rule-4', version: 4 }), - ]) - ); - }); - - it('should install missing prebuilt rules', async () => { - // Install all prebuilt detection rules - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Delete one of the installed rules - await deleteRule(supertest, 'rule-1'); - - // Check that one prebuilt rule is missing - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_installed).toBe(1); - - // Call the install prebuilt rules again and check that the missing rule was installed - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(1); - expect(response.rules_updated).toBe(0); - }); - - it('should update outdated prebuilt rules', async () => { - // Install all prebuilt detection rules - const ruleAssetSavedObjects = getRuleAssetSavedObjects(); - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - // Increment the version of one of the installed rules and create the new rule assets - ruleAssetSavedObjects[0]['security-rule'].version += 1; - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_updated).toBe(1); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(1); - }); - - it('should not install prebuilt rules if they are up to date', async () => { - // Install all prebuilt detection rules - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Check that all prebuilt rules were installed - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_installed).toBe(0); - expect(statusResponse.rules_not_updated).toBe(0); - - // Call the install prebuilt rules again and check that no rules were installed - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(0); - }); - }); - - describe('using current endpoint', () => { - it('should install prebuilt rules', async () => { - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - const body = await installPrebuiltRules(es, supertest); - - expect(body.summary.succeeded).toBe(RULES_COUNT); - expect(body.summary.failed).toBe(0); - expect(body.summary.skipped).toBe(0); - }); - - it('should install correct prebuilt rule versions', async () => { - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - const body = await installPrebuiltRules(es, supertest); - - // Check that all prebuilt rules were actually installed and their versions match the latest - expect(body.results.created).toEqual( - expect.arrayContaining([ - expect.objectContaining({ rule_id: 'rule-1', version: 1 }), - expect.objectContaining({ rule_id: 'rule-2', version: 2 }), - expect.objectContaining({ rule_id: 'rule-3', version: 3 }), - expect.objectContaining({ rule_id: 'rule-4', version: 4 }), - ]) - ); - }); - - it('should install missing prebuilt rules', async () => { - // Install all prebuilt detection rules - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Delete one of the installed rules - await deleteRule(supertest, 'rule-1'); - - // Check that one prebuilt rule is missing - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(1); - - // Call the install prebuilt rules again and check that the missing rule was installed - const response = await installPrebuiltRules(es, supertest); - expect(response.summary.succeeded).toBe(1); - }); - - it('should update outdated prebuilt rules', async () => { - // Install all prebuilt detection rules - const ruleAssetSavedObjects = getRuleAssetSavedObjects(); - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - // Increment the version of one of the installed rules and create the new rule assets - ruleAssetSavedObjects[0]['security-rule'].version += 1; - await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await upgradePrebuiltRules(es, supertest); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.skipped).toBe(0); - }); - - it('should not install prebuilt rules if they are up to date', async () => { - // Install all prebuilt detection rules - await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Check that all prebuilt rules were installed - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(0); - - // Call the install prebuilt rules again and check that no rules were installed - const installResponse = await installPrebuiltRules(es, supertest); - expect(installResponse.summary.succeeded).toBe(0); - expect(installResponse.summary.skipped).toBe(0); - - // Call the upgrade prebuilt rules endpoint and check that no rules were updated - const upgradeResponse = await upgradePrebuiltRules(es, supertest); - expect(upgradeResponse.summary.succeeded).toBe(0); - expect(upgradeResponse.summary.skipped).toBe(0); - }); - }); - }); - - describe(`rule package with historical versions`, () => { - const getRuleAssetSavedObjects = () => [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 2 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 1 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), - createRuleAssetSavedObject({ rule_id: 'rule-2', version: 3 }), - ]; - const RULES_COUNT = 2; - - describe('using legacy endpoint', () => { - it('should install prebuilt rules', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - const body = await installPrebuiltRulesAndTimelines(es, supertest); - - expect(body.rules_installed).toBe(RULES_COUNT); - expect(body.rules_updated).toBe(0); - }); - - it('should install correct prebuilt rule versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Get installed rules - const rulesResponse = await getInstalledRules(supertest); - - // Check that all prebuilt rules were actually installed and their versions match the latest - expect(rulesResponse.total).toBe(RULES_COUNT); - expect(rulesResponse.data).toEqual( - expect.arrayContaining([ - expect.objectContaining({ rule_id: 'rule-1', version: 2 }), - expect.objectContaining({ rule_id: 'rule-2', version: 3 }), - ]) - ); - }); - - it('should not install prebuilt rules if they are up to date', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Check that all prebuilt rules were installed - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_installed).toBe(0); - - // Call the install prebuilt rules again and check that no rules were installed - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(0); - }); - - it('should install missing prebuilt rules', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Delete one of the installed rules - await deleteRule(supertest, 'rule-1'); - - // Check that one prebuilt rule is missing - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_installed).toBe(1); - - // Call the install prebuilt rules endpoint again and check that the missing rule was installed - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(1); - expect(response.rules_updated).toBe(0); - }); - - it('should update outdated prebuilt rules when previous historical versions available', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Add a new version of one of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_updated).toBe(1); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(1); - - const _statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(_statusResponse.rules_not_installed).toBe(0); - expect(_statusResponse.rules_not_updated).toBe(0); - }); - - it('should update outdated prebuilt rules when previous historical versions unavailable', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRulesAndTimelines(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a new rule version - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that one prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(statusResponse.rules_not_updated).toBe(1); - expect(statusResponse.rules_not_installed).toBe(0); - - // Call the install prebuilt rules again and check that the outdated rule was updated - const response = await installPrebuiltRulesAndTimelines(es, supertest); - expect(response.rules_installed).toBe(0); - expect(response.rules_updated).toBe(1); - - const _statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); - expect(_statusResponse.rules_not_updated).toBe(0); - expect(_statusResponse.rules_not_installed).toBe(0); - }); - }); - - describe('using current endpoint', () => { - it('should install prebuilt rules', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - const body = await installPrebuiltRules(es, supertest); - - expect(body.summary.succeeded).toBe(RULES_COUNT); - }); - - it('should install correct prebuilt rule versions', async () => { - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - const response = await installPrebuiltRules(es, supertest); - - // Check that all prebuilt rules were actually installed and their versions match the latest - expect(response.summary.succeeded).toBe(RULES_COUNT); - expect(response.results.created).toEqual( - expect.arrayContaining([ - expect.objectContaining({ rule_id: 'rule-1', version: 2 }), - expect.objectContaining({ rule_id: 'rule-2', version: 3 }), - ]) - ); - }); - - it('should not install prebuilt rules if they are up to date', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Check that all prebuilt rules were installed - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - - // Call the install prebuilt rules again and check that no rules were installed - const response = await installPrebuiltRules(es, supertest); - expect(response.summary.succeeded).toBe(0); - expect(response.summary.total).toBe(0); - }); - - it('should install missing prebuilt rules', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Delete one of the installed rules - await deleteRule(supertest, 'rule-1'); - - // Check that one prebuilt rule is missing - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(1); - - // Call the install prebuilt rules endpoint again and check that the missing rule was installed - const response = await installPrebuiltRules(es, supertest); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.total).toBe(1); - }); - - it('should update outdated prebuilt rules when previous historical versions available', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Add a new version of one of the installed rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that the prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); - - // Call the upgrade prebuilt rules endpoint and check that the outdated rule was updated - const response = await upgradePrebuiltRules(es, supertest); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.total).toBe(1); - - const status = await getPrebuiltRulesStatus(es, supertest); - expect(status.stats.num_prebuilt_rules_to_install).toBe(0); - expect(status.stats.num_prebuilt_rules_to_upgrade).toBe(0); - }); - - it('should update outdated prebuilt rules when previous historical versions unavailable', async () => { - // Install all prebuilt detection rules - await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); - await installPrebuiltRules(es, supertest); - - // Clear previous rule assets - await deleteAllPrebuiltRuleAssets(es, log); - - // Add a new rule version - await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ - createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), - ]); - - // Check that the prebuilt rule status shows that one rule is outdated - const statusResponse = await getPrebuiltRulesStatus(es, supertest); - expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); - expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); - - // Call the upgrade prebuilt rules endpoint and check that the outdated rule was updated - const response = await upgradePrebuiltRules(es, supertest); - expect(response.summary.succeeded).toBe(1); - expect(response.summary.total).toBe(1); - - const status = await getPrebuiltRulesStatus(es, supertest); - expect(status.stats.num_prebuilt_rules_to_install).toBe(0); - expect(status.stats.num_prebuilt_rules_to_upgrade).toBe(0); - }); - }); - }); - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules.ts new file mode 100644 index 0000000000000..e9b8bbed84d1e --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules.ts @@ -0,0 +1,133 @@ +/* + * 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 expect from 'expect'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllRules, + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + createPrebuiltRuleAssetSavedObjects, + installPrebuiltRulesAndTimelines, + deleteRule, + getPrebuiltRulesAndTimelinesStatus, + getPrebuiltRulesStatus, + installPrebuiltRules, + getInstalledRules, +} from '../../../../utils'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInQA install prebuilt rules from package without historical versions with mock rule assets', () => { + const getRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), + createRuleAssetSavedObject({ rule_id: 'rule-3', version: 3 }), + createRuleAssetSavedObject({ rule_id: 'rule-4', version: 4 }), + ]; + const RULES_COUNT = getRuleAssetSavedObjects().length; + + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe('using current endpoint', () => { + it('should install prebuilt rules', async () => { + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + const body = await installPrebuiltRules(es, supertest); + + expect(body.summary.succeeded).toBe(RULES_COUNT); + expect(body.summary.failed).toBe(0); + expect(body.summary.skipped).toBe(0); + }); + + it('should install correct prebuilt rule versions', async () => { + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + const body = await installPrebuiltRules(es, supertest); + + // Check that all prebuilt rules were actually installed and their versions match the latest + expect(body.results.created).toEqual( + expect.arrayContaining([ + expect.objectContaining({ rule_id: 'rule-1', version: 1 }), + expect.objectContaining({ rule_id: 'rule-2', version: 2 }), + expect.objectContaining({ rule_id: 'rule-3', version: 3 }), + expect.objectContaining({ rule_id: 'rule-4', version: 4 }), + ]) + ); + }); + + it('should install missing prebuilt rules', async () => { + // Install all prebuilt detection rules + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Delete one of the installed rules + await deleteRule(supertest, 'rule-1'); + + // Check that one prebuilt rule is missing + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(1); + + // Call the install prebuilt rules again and check that the missing rule was installed + const response = await installPrebuiltRules(es, supertest); + expect(response.summary.succeeded).toBe(1); + }); + }); + + describe('using legacy endpoint', () => { + it('should install prebuilt rules', async () => { + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + const body = await installPrebuiltRulesAndTimelines(es, supertest); + + expect(body.rules_installed).toBe(RULES_COUNT); + expect(body.rules_updated).toBe(0); + }); + + it('should install correct prebuilt rule versions', async () => { + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Get installed rules + const rulesResponse = await getInstalledRules(supertest); + + // Check that all prebuilt rules were actually installed and their versions match the latest + expect(rulesResponse.total).toBe(RULES_COUNT); + expect(rulesResponse.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ rule_id: 'rule-1', version: 1 }), + expect.objectContaining({ rule_id: 'rule-2', version: 2 }), + expect.objectContaining({ rule_id: 'rule-3', version: 3 }), + expect.objectContaining({ rule_id: 'rule-4', version: 4 }), + ]) + ); + }); + + it('should install missing prebuilt rules', async () => { + // Install all prebuilt detection rules + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Delete one of the installed rules + await deleteRule(supertest, 'rule-1'); + + // Check that one prebuilt rule is missing + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_installed).toBe(1); + + // Call the install prebuilt rules again and check that the missing rule was installed + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(1); + expect(response.rules_updated).toBe(0); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules_with_historical_versions.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules_with_historical_versions.ts new file mode 100644 index 0000000000000..6120caa8eda22 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/install_prebuilt_rules_with_historical_versions.ts @@ -0,0 +1,160 @@ +/* + * 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 expect from 'expect'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllRules, + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + installPrebuiltRulesAndTimelines, + deleteRule, + getPrebuiltRulesAndTimelinesStatus, + createHistoricalPrebuiltRuleAssetSavedObjects, + getPrebuiltRulesStatus, + installPrebuiltRules, + getInstalledRules, +} from '../../../../utils'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInQA install prebuilt rules from package with historical versions with mock rule assets', () => { + const getRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 2 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 1 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 3 }), + ]; + const RULES_COUNT = 2; + + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe('using legacy endpoint', () => { + it('should install prebuilt rules', async () => { + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + const body = await installPrebuiltRulesAndTimelines(es, supertest); + + expect(body.rules_installed).toBe(RULES_COUNT); + expect(body.rules_updated).toBe(0); + }); + + it('should install correct prebuilt rule versions', async () => { + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Get installed rules + const rulesResponse = await getInstalledRules(supertest); + + // Check that all prebuilt rules were actually installed and their versions match the latest + expect(rulesResponse.total).toBe(RULES_COUNT); + expect(rulesResponse.data).toEqual( + expect.arrayContaining([ + expect.objectContaining({ rule_id: 'rule-1', version: 2 }), + expect.objectContaining({ rule_id: 'rule-2', version: 3 }), + ]) + ); + }); + + it('should not install prebuilt rules if they are up to date', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Check that all prebuilt rules were installed + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_installed).toBe(0); + + // Call the install prebuilt rules again and check that no rules were installed + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(0); + expect(response.rules_updated).toBe(0); + }); + + it('should install missing prebuilt rules', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Delete one of the installed rules + await deleteRule(supertest, 'rule-1'); + + // Check that one prebuilt rule is missing + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_installed).toBe(1); + + // Call the install prebuilt rules endpoint again and check that the missing rule was installed + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(1); + expect(response.rules_updated).toBe(0); + }); + }); + + describe('using current endpoint', () => { + it('should install prebuilt rules', async () => { + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + const body = await installPrebuiltRules(es, supertest); + + expect(body.summary.succeeded).toBe(RULES_COUNT); + }); + + it('should install correct prebuilt rule versions', async () => { + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + const response = await installPrebuiltRules(es, supertest); + + // Check that all prebuilt rules were actually installed and their versions match the latest + expect(response.summary.succeeded).toBe(RULES_COUNT); + expect(response.results.created).toEqual( + expect.arrayContaining([ + expect.objectContaining({ rule_id: 'rule-1', version: 2 }), + expect.objectContaining({ rule_id: 'rule-2', version: 3 }), + ]) + ); + }); + + it('should not install prebuilt rules if they are up to date', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Check that all prebuilt rules were installed + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); + + // Call the install prebuilt rules again and check that no rules were installed + const response = await installPrebuiltRules(es, supertest); + expect(response.summary.succeeded).toBe(0); + expect(response.summary.total).toBe(0); + }); + + it('should install missing prebuilt rules', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Delete one of the installed rules + await deleteRule(supertest, 'rule-1'); + + // Check that one prebuilt rule is missing + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(1); + + // Call the install prebuilt rules endpoint again and check that the missing rule was installed + const response = await installPrebuiltRules(es, supertest); + expect(response.summary.succeeded).toBe(1); + expect(response.summary.total).toBe(1); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts new file mode 100644 index 0000000000000..5d1f9662e118a --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules.ts @@ -0,0 +1,268 @@ +/* + * 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 expect from 'expect'; +import { PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID } from '../../../../../../config/shared'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllRules, + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + createPrebuiltRuleAssetSavedObjects, + installPrebuiltRulesAndTimelines, + getPrebuiltRulesAndTimelinesStatus, + getPrebuiltRulesStatus, + installPrebuiltRules, + upgradePrebuiltRules, + fetchRule, + patchRule, +} from '../../../../utils'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInQA upgrade prebuilt rules from package without historical versions with mock rule assets', () => { + const getRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), + createRuleAssetSavedObject({ rule_id: 'rule-3', version: 3 }), + createRuleAssetSavedObject({ rule_id: 'rule-4', version: 4 }), + ]; + + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe('using legacy endpoint', () => { + it('should upgrade outdated prebuilt rules', async () => { + // Install all prebuilt detection rules + const ruleAssetSavedObjects = getRuleAssetSavedObjects(); + await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + // Increment the version of one of the installed rules and create the new rule assets + ruleAssetSavedObjects[0]['security-rule'].version += 1; + await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); + + // Check that one prebuilt rule status shows that one rule is outdated + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_updated).toBe(1); + + // Call the install prebuilt rules again and check that the outdated rule was updated + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(0); + expect(response.rules_updated).toBe(1); + }); + + it('should not upgrade prebuilt rules if they are up to date', async () => { + // Install all prebuilt detection rules + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Check that all prebuilt rules were installed + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_installed).toBe(0); + expect(statusResponse.rules_not_updated).toBe(0); + + // Call the install prebuilt rules again and check that no rules were installed + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(0); + expect(response.rules_updated).toBe(0); + }); + }); + + describe('using current endpoint', () => { + it('should upgrade outdated prebuilt rules', async () => { + // Install all prebuilt detection rules + const ruleAssetSavedObjects = getRuleAssetSavedObjects(); + await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + // Increment the version of one of the installed rules and create the new rule assets + ruleAssetSavedObjects[0]['security-rule'].version += 1; + await createPrebuiltRuleAssetSavedObjects(es, ruleAssetSavedObjects); + + // Check that one prebuilt rule status shows that one rule is outdated + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); + expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); + + // Call the install prebuilt rules again and check that the outdated rule was updated + const response = await upgradePrebuiltRules(es, supertest); + expect(response.summary.succeeded).toBe(1); + expect(response.summary.skipped).toBe(0); + }); + + it('should not upgrade prebuilt rules if they are up to date', async () => { + // Install all prebuilt detection rules + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Check that all prebuilt rules were installed + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); + expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(0); + + // Call the install prebuilt rules again and check that no rules were installed + const installResponse = await installPrebuiltRules(es, supertest); + expect(installResponse.summary.succeeded).toBe(0); + expect(installResponse.summary.skipped).toBe(0); + + // Call the upgrade prebuilt rules endpoint and check that no rules were updated + const upgradeResponse = await upgradePrebuiltRules(es, supertest); + expect(upgradeResponse.summary.succeeded).toBe(0); + expect(upgradeResponse.summary.skipped).toBe(0); + }); + + describe('when upgrading a prebuilt rule to a newer version with the same rule type', () => { + it('preserves rule bound data', async () => { + await createPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + rule_id: 'rule-to-test-1', + enabled: true, + version: 1, + }), + ]); + const firstInstallResponse = await installPrebuiltRules(es, supertest); + const initialRuleSoId = firstInstallResponse.results.created[0].id; + + const actions = [ + // Use a preconfigured action connector to simplify the test and avoid action connector creation + { + id: PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID, + action_type_id: '.email', + group: 'default', + params: {}, + }, + ]; + const exceptionsList = [ + { + id: 'exception_list_1', + list_id: 'exception_list_1', + namespace_type: 'agnostic', + type: 'rule_default', + } as const, + ]; + + // Add some actions, exceptions list, and timeline reference + await patchRule(supertest, log, { + rule_id: 'rule-to-test-1', + enabled: false, + actions, + exceptions_list: exceptionsList, + timeline_id: 'some-timeline-id', + timeline_title: 'Some timeline title', + }); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + // Create a new version with the same rule type asset + await createPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + rule_id: 'rule-to-test-1', + enabled: true, + version: 2, + }), + ]); + + // Upgrade to a newer version with the same type + await upgradePrebuiltRules(es, supertest); + + expect(await fetchRule(supertest, { ruleId: 'rule-to-test-1' })).toMatchObject({ + id: initialRuleSoId, + // If a user disabled the rule it's expected to stay disabled after upgrade + enabled: false, + actions, + exceptions_list: exceptionsList, + timeline_id: 'some-timeline-id', + timeline_title: 'Some timeline title', + }); + }); + }); + + describe('when upgrading a prebuilt rule to a newer version with a different rule type', () => { + it('preserves rule bound data', async () => { + await createPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + rule_id: 'rule-to-test-2', + type: 'query', + language: 'kuery', + query: '*:*', + enabled: true, + version: 1, + }), + ]); + const firstInstallResponse = await installPrebuiltRules(es, supertest); + const initialRuleSoId = firstInstallResponse.results.created[0].id; + + const actions = [ + // Use a preconfigured action connector to simplify the test and avoid action connector creation + { + id: PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID, + action_type_id: '.email', + group: 'default', + params: {}, + }, + ]; + const exceptionsList = [ + { + id: 'exception_list_1', + list_id: 'exception_list_1', + namespace_type: 'agnostic', + type: 'rule_default', + } as const, + ]; + + // Add some actions, exceptions list, and timeline reference + await patchRule(supertest, log, { + rule_id: 'rule-to-test-2', + enabled: false, + actions, + exceptions_list: exceptionsList, + timeline_id: 'some-timeline-id', + timeline_title: 'Some timeline title', + }); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + // Create a new version with a different rule type asset + await createPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + rule_id: 'rule-to-test-2', + type: 'eql', + language: 'eql', + query: 'host where host == "something"', + enabled: true, + version: 2, + }), + ]); + + // Upgrade to a newer version with a different rule type + await upgradePrebuiltRules(es, supertest); + + expect(await fetchRule(supertest, { ruleId: 'rule-to-test-2' })).toMatchObject({ + id: initialRuleSoId, + // If a user disabled the rule it's expected to stay disabled after upgrade + enabled: false, + actions, + exceptions_list: exceptionsList, + timeline_id: 'some-timeline-id', + timeline_title: 'Some timeline title', + }); + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts new file mode 100644 index 0000000000000..cd6ff46ecabb1 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_prebuilt_rules_with_historical_versions.ts @@ -0,0 +1,152 @@ +/* + * 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 expect from 'expect'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllRules, + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + installPrebuiltRulesAndTimelines, + getPrebuiltRulesAndTimelinesStatus, + createHistoricalPrebuiltRuleAssetSavedObjects, + getPrebuiltRulesStatus, + installPrebuiltRules, + upgradePrebuiltRules, +} from '../../../../utils'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInQA upgrade prebuilt rules from package with historical versions with mock rule assets', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe(`rule package with historical versions`, () => { + const getRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 1 }), + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 2 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 1 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 2 }), + createRuleAssetSavedObject({ rule_id: 'rule-2', version: 3 }), + ]; + + describe('using legacy endpoint', () => { + it('should upgrade outdated prebuilt rules when previous historical versions available', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Add a new version of one of the installed rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), + ]); + + // Check that one prebuilt rule status shows that one rule is outdated + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_updated).toBe(1); + + // Call the install prebuilt rules again and check that the outdated rule was updated + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(0); + expect(response.rules_updated).toBe(1); + + const _statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(_statusResponse.rules_not_installed).toBe(0); + expect(_statusResponse.rules_not_updated).toBe(0); + }); + + it('should upgrade outdated prebuilt rules when previous historical versions unavailable', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRulesAndTimelines(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Add a new rule version + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), + ]); + + // Check that one prebuilt rule status shows that one rule is outdated + const statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(statusResponse.rules_not_updated).toBe(1); + expect(statusResponse.rules_not_installed).toBe(0); + + // Call the install prebuilt rules again and check that the outdated rule was updated + const response = await installPrebuiltRulesAndTimelines(es, supertest); + expect(response.rules_installed).toBe(0); + expect(response.rules_updated).toBe(1); + + const _statusResponse = await getPrebuiltRulesAndTimelinesStatus(es, supertest); + expect(_statusResponse.rules_not_updated).toBe(0); + expect(_statusResponse.rules_not_installed).toBe(0); + }); + }); + + describe('using current endpoint', () => { + it('should upgrade outdated prebuilt rules when previous historical versions available', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Add a new version of one of the installed rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), + ]); + + // Check that the prebuilt rule status shows that one rule is outdated + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); + + // Call the upgrade prebuilt rules endpoint and check that the outdated rule was updated + const response = await upgradePrebuiltRules(es, supertest); + expect(response.summary.succeeded).toBe(1); + expect(response.summary.total).toBe(1); + + const status = await getPrebuiltRulesStatus(es, supertest); + expect(status.stats.num_prebuilt_rules_to_install).toBe(0); + expect(status.stats.num_prebuilt_rules_to_upgrade).toBe(0); + }); + + it('should upgrade outdated prebuilt rules when previous historical versions unavailable', async () => { + // Install all prebuilt detection rules + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Add a new rule version + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ rule_id: 'rule-1', version: 3 }), + ]); + + // Check that the prebuilt rule status shows that one rule is outdated + const statusResponse = await getPrebuiltRulesStatus(es, supertest); + expect(statusResponse.stats.num_prebuilt_rules_to_upgrade).toBe(1); + expect(statusResponse.stats.num_prebuilt_rules_to_install).toBe(0); + + // Call the upgrade prebuilt rules endpoint and check that the outdated rule was updated + const response = await upgradePrebuiltRules(es, supertest); + expect(response.summary.succeeded).toBe(1); + expect(response.summary.total).toBe(1); + + const status = await getPrebuiltRulesStatus(es, supertest); + expect(status.stats.num_prebuilt_rules_to_install).toBe(0); + expect(status.stats.num_prebuilt_rules_to_upgrade).toBe(0); + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_import_export/trial_license_complete_tier/export_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_import_export/trial_license_complete_tier/export_rules.ts index b87e1e0fcc4b1..555e845ec7b4f 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_import_export/trial_license_complete_tier/export_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/rule_import_export/trial_license_complete_tier/export_rules.ts @@ -9,6 +9,7 @@ import expect from 'expect'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; import { RuleResponse } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID } from '../../../../../config/shared'; import { binaryToString, createRule, @@ -381,7 +382,7 @@ export default ({ getService }: FtrProviderContext): void => { it('should export rule without the action connector if it is Preconfigured Connector', async () => { const action = { group: 'default', - id: 'my-test-email', + id: PRECONFIGURED_EMAIL_ACTION_CONNECTOR_ID, action_type_id: '.email', params: {}, }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts index 0b4bfd9254b15..20a8e6cf17280 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/create_prebuilt_rule_saved_objects.ts @@ -21,10 +21,7 @@ import { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-se * @returns Created rule asset saved object */ export const createRuleAssetSavedObject = (overrideParams: Partial) => ({ - 'security-rule': { - ...getPrebuiltRuleMock(), - ...overrideParams, - }, + 'security-rule': getPrebuiltRuleMock(overrideParams), type: 'security-rule', references: [], coreMigrationVersion: '8.6.0', diff --git a/x-pack/test/security_solution_api_integration/tsconfig.json b/x-pack/test/security_solution_api_integration/tsconfig.json index 18e019202355c..d60124a7cc19f 100644 --- a/x-pack/test/security_solution_api_integration/tsconfig.json +++ b/x-pack/test/security_solution_api_integration/tsconfig.json @@ -41,5 +41,6 @@ "@kbn/safer-lodash-set", "@kbn/stack-connectors-plugin", "@kbn/ftr-common-functional-services", + "@kbn/actions-plugin", ] }