mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[Security Solution][API testing] Move and restructures Telemetry logic (#171159)
## Summary Following the initial work in this https://github.com/elastic/kibana/pull/166755 - Addresses part of https://github.com/elastic/kibana/issues/151902 for Telemetry - Moved the utility files associated with telemetry to the new directory `security_solution_api_integration`. Files not actively used in the previous folder were moved, while duplicate files remained in their original positions. - Updated the CodeOwner file for the newly moved tests - Old/new group details, decisions, and execution time are mentioned in this [document](https://docs.google.com/document/d/1CRFfDWMzw3ob03euWIvT4-IoiLXjoiPWI8mTBqP4Zks/edit) | Action | File | New Path if moved | |--------|------|----------| | Delete| security_and_spaces/group4| - | | Move|detection_engine_api_integration/security_and_spaces/group4|detections_response/default_license/telemetry/keyword_family|
This commit is contained in:
parent
3791a73dfa
commit
53a37f0415
36 changed files with 867 additions and 316 deletions
|
@ -225,7 +225,6 @@ enabled:
|
|||
- x-pack/test/dataset_quality_api_integration/basic/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/basic/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/group1/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/group4/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/group10/config.ts
|
||||
- x-pack/test/disable_ems/config.ts
|
||||
- x-pack/test/encrypted_saved_objects_api_integration/config.ts
|
||||
|
@ -477,3 +476,5 @@ enabled:
|
|||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_execution_logic/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/user_roles/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/user_roles/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/ess.config.ts
|
||||
|
|
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
@ -1410,7 +1410,7 @@ x-pack/test/security_solution_api_integration/test_suites/detections_response/de
|
|||
/x-pack/plugins/security_solution/server/routes @elastic/security-detections-response @elastic/security-threat-hunting
|
||||
/x-pack/plugins/security_solution/server/utils @elastic/security-detections-response @elastic/security-threat-hunting
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/utils @elastic/security-detections-response
|
||||
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry @elastic/security-detections-response
|
||||
|
||||
## Security Solution sub teams - security-defend-workflows
|
||||
/x-pack/plugins/security_solution/public/management/ @elastic/security-defend-workflows
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ loadTestFile }: FtrProviderContext): void => {
|
||||
describe('detection engine api security and spaces enabled - Group 4', function () {
|
||||
loadTestFile(require.resolve('./telemetry'));
|
||||
});
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ToolingLog } from '@kbn/tooling-log';
|
||||
import type SuperTest from 'supertest';
|
||||
|
||||
import { getWebHookAction } from './get_web_hook_action';
|
||||
|
||||
/**
|
||||
* Helper to cut down on the noise in some of the tests. This
|
||||
* creates a new action and expects a 200 and does not do any retries.
|
||||
* @param supertest The supertest deps
|
||||
*/
|
||||
export const createNewAction = async (
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>,
|
||||
log: ToolingLog
|
||||
) => {
|
||||
const response = await supertest
|
||||
.post('/api/actions/action')
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getWebHookAction());
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
||||
`Did not get an expected 200 "ok" when creating a new action. CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify(
|
||||
response.body
|
||||
)}, status: ${JSON.stringify(response.status)}`
|
||||
);
|
||||
}
|
||||
return response.body;
|
||||
};
|
|
@ -13,7 +13,6 @@ export * from './create_container_with_entries';
|
|||
export * from './create_exception_list';
|
||||
export * from './create_exception_list_item';
|
||||
export * from './create_legacy_rule_action';
|
||||
export * from './create_new_action';
|
||||
export * from './create_rule';
|
||||
export * from './create_rule_with_exception_entries';
|
||||
export * from './create_rule_saved_object';
|
||||
|
@ -25,12 +24,10 @@ export * from './delete_all_alerts';
|
|||
export * from './delete_all_timelines';
|
||||
export * from './delete_exception_list';
|
||||
export * from './delete_rule';
|
||||
export * from './downgrade_immutable_rule';
|
||||
export * from './finalize_signals_migration';
|
||||
export * from './find_immutable_rule_by_id';
|
||||
export * from './get_complex_rule';
|
||||
export * from './get_complex_rule_output';
|
||||
export * from './get_detection_metrics_from_body';
|
||||
export * from './get_eql_rule_for_signal_testing';
|
||||
export * from './get_event_log_execute_complete_by_id';
|
||||
export * from './get_legacy_action_notification_so';
|
||||
|
@ -47,7 +44,6 @@ export * from './get_rule_for_signal_testing_with_timestamp_override';
|
|||
export * from './get_rule_with_web_hook_action';
|
||||
export * from './get_rule_with_legacy_investigation_fields';
|
||||
export * from './get_saved_query_rule_for_signal_testing';
|
||||
export * from './get_security_telemetry_stats';
|
||||
export * from './get_signal_status';
|
||||
export * from './get_signals_by_id';
|
||||
export * from './get_signals_by_ids';
|
||||
|
@ -62,9 +58,6 @@ export * from './get_simple_rule_output_without_rule_id';
|
|||
export * from './get_simple_rule_update';
|
||||
export * from './get_simple_rule_without_rule_id';
|
||||
export * from './get_simple_saved_query_rule';
|
||||
export * from './get_simple_threat_match';
|
||||
export * from './get_stats';
|
||||
export * from './get_stats_url';
|
||||
export * from './get_threat_match_rule_for_signal_testing';
|
||||
export * from './get_threshold_rule_for_signal_testing';
|
||||
export * from './get_slack_action';
|
||||
|
@ -76,7 +69,6 @@ export * from './preview_rule_with_exception_entries';
|
|||
export * from './preview_rule';
|
||||
export * from './refresh_index';
|
||||
export * from './route_with_namespace';
|
||||
export * from './remove_time_fields_from_telemetry_stats';
|
||||
export * from './remove_server_generated_properties';
|
||||
export * from './remove_server_generated_properties_including_rule_id';
|
||||
export * from './resolve_simple_rule_output';
|
||||
|
|
|
@ -93,6 +93,11 @@
|
|||
"user_roles:runner:serverless": "npm run run-tests:dr:default user_roles serverless serverlessEnv",
|
||||
"user_roles:qa:serverless": "npm run run-tests:dr:default user_roles serverless qaEnv",
|
||||
"user_roles:server:ess": "npm run initialize-server:dr:default user_roles ess",
|
||||
"user_roles:runner:ess": "npm run run-tests:dr:default user_roles ess essEnv"
|
||||
"user_roles:runner:ess": "npm run run-tests:dr:default user_roles ess essEnv",
|
||||
"telemetry:server:serverless": "npm run initialize-server:dr:default telemetry serverless",
|
||||
"telemetry:runner:serverless": "npm run run-tests:dr:default telemetry serverless serverlessEnv",
|
||||
"telemetry:qa:serverless": "npm run run-tests:dr:default telemetry serverless qaEnv",
|
||||
"telemetry:server:ess": "npm run initialize-server:dr:default telemetry ess",
|
||||
"telemetry:runner:ess": "npm run run-tests:dr:default telemetry ess essEnv"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
expect(bundledInstallResponse._meta.install_source).toBe('bundled');
|
||||
|
||||
// Refresh ES indices to avoid race conditions between write and reading of indeces
|
||||
// See implementation utility function at x-pack/test/detection_engine_api_integration/utils/prebuilt_rules/install_prebuilt_rules_fleet_package.ts
|
||||
// See implementation utility function at x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/prebuilt_rules/install_prebuilt_rules_fleet_package.ts
|
||||
await es.indices.refresh({ index: ALL_SAVED_OBJECT_INDICES });
|
||||
|
||||
// Verify that status is updated after package installation
|
||||
|
|
|
@ -7,12 +7,16 @@
|
|||
|
||||
import { FtrConfigProviderContext } from '@kbn/test';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const functionalConfig = await readConfigFile(require.resolve('../config.base.ts'));
|
||||
const functionalConfig = await readConfigFile(
|
||||
require.resolve('../../../../../config/ess/config.base.trial')
|
||||
);
|
||||
|
||||
return {
|
||||
...functionalConfig.getAll(),
|
||||
testFiles: [require.resolve('.')],
|
||||
testFiles: [require.resolve('..')],
|
||||
junit: {
|
||||
reportName: 'Detection Engine API Integration Tests - ESS - Telemetry',
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createTestConfig } from '../../../../../config/serverless/config.base';
|
||||
|
||||
export default createTestConfig({
|
||||
testFiles: [require.resolve('..')],
|
||||
junit: {
|
||||
reportName: 'Detection Engine API Integration Tests - Serverless - Telemetry',
|
||||
},
|
||||
kbnTestServerArgs: [
|
||||
`--xpack.securitySolution.enableExperimental=${JSON.stringify(['previewTelemetryUrlEnabled'])}`,
|
||||
],
|
||||
});
|
|
@ -4,15 +4,14 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
import { FtrProviderContext } from '../../../common/ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ loadTestFile }: FtrProviderContext): void => {
|
||||
describe('Detection rule type telemetry', function () {
|
||||
loadTestFile(require.resolve('./usage_collector/all_types'));
|
||||
loadTestFile(require.resolve('./usage_collector/detection_rules'));
|
||||
loadTestFile(require.resolve('./usage_collector/detection_rule_status'));
|
||||
loadTestFile(require.resolve('./usage_collector/detection_rules_legacy_action'));
|
||||
|
||||
loadTestFile(require.resolve('./task_based/all_types'));
|
||||
loadTestFile(require.resolve('./task_based/detection_rules'));
|
|
@ -6,17 +6,18 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
|
||||
import {
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getSecurityTelemetryStats,
|
||||
removeTimeFieldsFromTelemetryStats,
|
||||
} from '../../../../utils';
|
||||
import { deleteAllExceptions } from '../../../../../lists_api_integration/utils';
|
||||
} from '../../../utils';
|
||||
import { deleteAllExceptions } from '../../../../../../lists_api_integration/utils';
|
||||
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -24,7 +25,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const retry = getService('retry');
|
||||
const es = getService('es');
|
||||
|
||||
describe('All task telemetry types generically', async () => {
|
||||
describe('@ess @serverless All task telemetry types generically', async () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry');
|
||||
});
|
||||
|
@ -34,7 +35,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -43,7 +44,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
await deleteAllExceptions(supertest, log);
|
||||
});
|
||||
|
||||
it('should only have task metric values when no rules are running', async () => {
|
||||
it('@skipInQA should only have task metric values when no rules are running', async () => {
|
||||
await retry.try(async () => {
|
||||
const stats = await getSecurityTelemetryStats(supertest, log);
|
||||
removeTimeFieldsFromTelemetryStats(stats);
|
|
@ -10,23 +10,22 @@
|
|||
import expect from '@kbn/expect';
|
||||
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
|
||||
import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
createRule,
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getRule,
|
||||
getRuleForSignalTesting,
|
||||
fetchRule,
|
||||
getRuleForAlertTesting,
|
||||
installMockPrebuiltRules,
|
||||
getSecurityTelemetryStats,
|
||||
createExceptionList,
|
||||
createExceptionListItem,
|
||||
removeTimeFieldsFromTelemetryStats,
|
||||
} from '../../../../utils';
|
||||
import { deleteAllExceptions } from '../../../../../lists_api_integration/utils';
|
||||
} from '../../../utils';
|
||||
import { deleteAllExceptions } from '../../../../../../lists_api_integration/utils';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const es = getService('es');
|
||||
const supertest = getService('supertest');
|
||||
|
@ -34,7 +33,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
|
||||
describe('Detection rule task telemetry', async () => {
|
||||
describe('@ess @serverless Detection rule task telemetry', async () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry');
|
||||
});
|
||||
|
@ -44,7 +43,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -54,8 +53,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
describe('custom rules should never show any detection_rules telemetry data for each list type', () => {
|
||||
it('should NOT give telemetry/stats for an exception list of type "detection"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@skipInQA should NOT give telemetry/stats for an exception list of type "detection"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
|
||||
// create an exception list container of type "detection"
|
||||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, {
|
||||
|
@ -110,8 +109,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should NOT give telemetry/stats for an exception list of type "endpoint"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
|
||||
// create an exception list container of type "detection"
|
||||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, {
|
||||
|
@ -166,8 +165,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should NOT give telemetry/stats for an exception list of type "endpoint_trusted_apps"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint_trusted_apps"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
|
||||
// create an exception list container of type "detection"
|
||||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, {
|
||||
|
@ -222,8 +221,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should NOT give telemetry/stats for an exception list of type "endpoint_events"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint_events"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
|
||||
// create an exception list container of type "detection"
|
||||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, {
|
||||
|
@ -278,8 +277,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should NOT give telemetry/stats for an exception list of type "endpoint_host_isolation_exceptions"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@skipInQA should NOT give telemetry/stats for an exception list of type "endpoint_host_isolation_exceptions"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
|
||||
// create an exception list container of type "detection"
|
||||
const { id, list_id, namespace_type, type } = await createExceptionList(supertest, log, {
|
||||
|
@ -335,7 +334,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('pre-built/immutable/elastic rules should show detection_rules telemetry data for each list type', () => {
|
||||
describe('@skipInQA pre-built/immutable/elastic rules should show detection_rules telemetry data for each list type', () => {
|
||||
beforeEach(async () => {
|
||||
// install prepackaged rules to get immutable rules for testing
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
|
@ -368,7 +367,9 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule using "PATCH" endpoint
|
||||
const { exceptions_list } = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const { exceptions_list } = await fetchRule(supertest, {
|
||||
ruleId: ELASTIC_SECURITY_RULE_ID,
|
||||
});
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -427,7 +428,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -504,7 +505,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -581,7 +582,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -658,7 +659,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -735,7 +736,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -786,7 +787,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('pre-built/immutable/elastic rules should show detection_rules telemetry data for multiple list items and types', () => {
|
||||
describe('@skipInQA pre-built/immutable/elastic rules should show detection_rules telemetry data for multiple list items and types', () => {
|
||||
beforeEach(async () => {
|
||||
// install prepackaged rules to get immutable rules for testing
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
|
@ -836,7 +837,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// add the exception list to the pre-built/immutable/elastic rule
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
await supertest
|
||||
.patch(DETECTION_ENGINE_RULES_URL)
|
||||
.set('kbn-xsrf', 'true')
|
|
@ -11,19 +11,18 @@ import {
|
|||
ENDPOINT_LIST_ID,
|
||||
ENDPOINT_TRUSTED_APPS_LIST_ID,
|
||||
} from '@kbn/securitysolution-list-constants';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getSecurityTelemetryStats,
|
||||
createExceptionListItem,
|
||||
createExceptionList,
|
||||
removeTimeFieldsFromTelemetryStats,
|
||||
} from '../../../../utils';
|
||||
import { deleteAllExceptions } from '../../../../../lists_api_integration/utils';
|
||||
} from '../../../utils';
|
||||
import { deleteAllExceptions } from '../../../../../../lists_api_integration/utils';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -32,7 +31,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const es = getService('es');
|
||||
|
||||
// Failing: See https://github.com/elastic/kibana/issues/164334
|
||||
describe.skip('Security lists task telemetry', async () => {
|
||||
describe.skip('@ess @serverless Security lists task telemetry', async () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry');
|
||||
});
|
||||
|
@ -42,7 +41,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
// Calling stats endpoint once like this guarantees that the trusted applications and exceptions lists are created for us.
|
||||
await getSecurityTelemetryStats(supertest, log);
|
||||
});
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage';
|
||||
import type { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import { createSignalsIndex, deleteAllRules, deleteAllAlerts, getStats } from '../../../../utils';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
import { createAlertsIndex, deleteAllRules, deleteAllAlerts, getStats } from '../../../utils';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -18,7 +18,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const retry = getService('retry');
|
||||
const es = getService('es');
|
||||
|
||||
describe('Detection rule telemetry', async () => {
|
||||
describe('@ess @serverless @skipInQA Detection rule telemetry', async () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry');
|
||||
});
|
||||
|
@ -28,7 +28,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
|
@ -22,21 +22,20 @@ import {
|
|||
} from '@kbn/security-solution-plugin/server/usage/detections/rules/get_initial_usage';
|
||||
import {
|
||||
createRule,
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getEqlRuleForSignalTesting,
|
||||
getRuleForSignalTesting,
|
||||
getEqlRuleForAlertTesting,
|
||||
getRuleForAlertTesting,
|
||||
getSimpleThreatMatch,
|
||||
getStats,
|
||||
getThresholdRuleForSignalTesting,
|
||||
getThresholdRuleForAlertTesting,
|
||||
waitForRuleSuccess,
|
||||
waitForSignalsToBePresent,
|
||||
waitForAlertsToBePresent,
|
||||
deleteAllEventLogExecutionEvents,
|
||||
} from '../../../../utils';
|
||||
import type { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
} from '../../../utils';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -46,7 +45,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
// Note: We don't actually find signals well with ML tests at the moment so there are not tests for ML rule type for telemetry
|
||||
// FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/132856
|
||||
describe('Detection rule status telemetry', async () => {
|
||||
describe('@ess @serverless Detection rule status telemetry', async () => {
|
||||
before(async () => {
|
||||
// Just in case other tests do not clean up the event logs, let us clear them now and here only once.
|
||||
await deleteAllEventLogExecutionEvents(es, log);
|
||||
|
@ -58,7 +57,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -70,10 +69,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('"kql" rule type', () => {
|
||||
let stats: DetectionMetrics | undefined;
|
||||
before(async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry']);
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
// get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed
|
||||
await retry.try(async () => {
|
||||
stats = await getStats(supertest, log);
|
||||
|
@ -120,7 +119,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(stats?.detection_rules.detection_rule_usage).to.eql(expectedRuleUsage);
|
||||
});
|
||||
|
||||
it('should have zero values for "detection_rule_status.all_rules" rules that are not query based', () => {
|
||||
it('@skipInQA should have zero values for "detection_rule_status.all_rules" rules that are not query based', () => {
|
||||
expect(stats?.detection_rules.detection_rule_status.all_rules.eql).to.eql(
|
||||
getInitialSingleEventMetric()
|
||||
);
|
||||
|
@ -172,7 +171,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should have non zero values for "index_duration"', () => {
|
||||
it('@skipInQA should have non zero values for "index_duration"', () => {
|
||||
expect(
|
||||
stats?.detection_rules.detection_rule_status.custom_rules.query.index_duration.max
|
||||
).to.be.above(1);
|
||||
|
@ -205,11 +204,11 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
).to.be.above(1);
|
||||
});
|
||||
|
||||
it('should have non zero values for "succeeded"', () => {
|
||||
it('@skipInQA should have non zero values for "succeeded"', () => {
|
||||
expect(stats?.detection_rules.detection_rule_status.custom_rules.query.succeeded).to.eql(1);
|
||||
});
|
||||
|
||||
it('should have non zero values for "succeeded", "index_duration", "search_duration" and "enrichment_duration"', () => {
|
||||
it('@skipInQA should have non zero values for "succeeded", "index_duration", "search_duration" and "enrichment_duration"', () => {
|
||||
expect(
|
||||
stats?.detection_rules.detection_rule_status.custom_rules.query.index_duration.max
|
||||
).to.be.above(1);
|
||||
|
@ -257,10 +256,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('"eql" rule type', () => {
|
||||
let stats: DetectionMetrics | undefined;
|
||||
before(async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry']);
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
// get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed
|
||||
await retry.try(async () => {
|
||||
stats = await getStats(supertest, log);
|
||||
|
@ -445,7 +444,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
let stats: DetectionMetrics | undefined;
|
||||
before(async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry']),
|
||||
...getThresholdRuleForAlertTesting(['telemetry']),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
|
@ -453,7 +452,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
// get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed
|
||||
await retry.try(async () => {
|
||||
stats = await getStats(supertest, log);
|
||||
|
@ -662,7 +661,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
// get the stats for all the tests where we at least have the expected "query" to reduce chances of flake by checking that at least one custom rule passed
|
||||
await retry.try(async () => {
|
||||
stats = await getStats(supertest, log);
|
|
@ -14,34 +14,34 @@ import type {
|
|||
import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage';
|
||||
import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common';
|
||||
import { RulesTypeUsage } from '@kbn/security-solution-plugin/server/usage/detections/rules/types';
|
||||
import type { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
createLegacyRuleAction,
|
||||
createNewAction,
|
||||
createWebHookRuleAction,
|
||||
createRule,
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getEqlRuleForSignalTesting,
|
||||
getRule,
|
||||
getRuleForSignalTesting,
|
||||
getEqlRuleForAlertTesting,
|
||||
fetchRule,
|
||||
getRuleForAlertTesting,
|
||||
getRuleWithWebHookAction,
|
||||
getSimpleMlRule,
|
||||
getSimpleRule,
|
||||
getSimpleThreatMatch,
|
||||
getStats,
|
||||
getThresholdRuleForSignalTesting,
|
||||
getThresholdRuleForAlertTesting,
|
||||
installMockPrebuiltRules,
|
||||
waitForRuleSuccess,
|
||||
waitForSignalsToBePresent,
|
||||
waitForAlertsToBePresent,
|
||||
updateRule,
|
||||
deleteAllEventLogExecutionEvents,
|
||||
getRuleSavedObjectWithLegacyInvestigationFields,
|
||||
getRuleSavedObjectWithLegacyInvestigationFieldsEmptyArray,
|
||||
createRuleThroughAlertingEndpoint,
|
||||
} from '../../../../utils';
|
||||
} from '../../../utils';
|
||||
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -49,7 +49,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const retry = getService('retry');
|
||||
const es = getService('es');
|
||||
|
||||
describe('Detection rule telemetry', async () => {
|
||||
describe('@ess @serverless Detection rule telemetry', async () => {
|
||||
before(async () => {
|
||||
// Just in case other tests do not clean up the event logs, let us clear them now and here only once.
|
||||
await deleteAllEventLogExecutionEvents(es, log);
|
||||
|
@ -61,7 +61,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -72,7 +72,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
describe('"kql" rule type', () => {
|
||||
it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
await createRule(supertest, log, rule);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -102,10 +102,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry']);
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
|
@ -136,8 +136,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry']);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule);
|
||||
await createRule(supertest, log, ruleToCreate);
|
||||
|
||||
|
@ -160,13 +160,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry']);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
it('@brokenInServerless should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule);
|
||||
const { id } = await createRule(supertest, log, ruleToCreate);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -189,10 +189,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -215,13 +215,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getRuleForSignalTesting(['telemetry']);
|
||||
it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -244,7 +244,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('legacy investigation fields', () => {
|
||||
describe('@brokenInServerless legacy investigation fields', () => {
|
||||
beforeEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
await createRuleThroughAlertingEndpoint(
|
||||
|
@ -294,7 +294,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
describe('"eql" rule type', () => {
|
||||
it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
await createRule(supertest, log, rule);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -322,10 +322,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry']);
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
|
@ -356,8 +356,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry']);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry']);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule);
|
||||
await createRule(supertest, log, ruleToCreate);
|
||||
|
||||
|
@ -381,12 +381,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry']);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry']);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule);
|
||||
const { id } = await createRule(supertest, log, ruleToCreate);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -409,10 +409,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry'], 'rule-1', false);
|
||||
it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -434,13 +434,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getEqlRuleForSignalTesting(['telemetry']);
|
||||
it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -467,7 +467,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('"threshold" rule type', () => {
|
||||
it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "disabled"/"in-active" rule that does not have any actions', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false),
|
||||
...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
|
@ -503,7 +503,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should show "notifications_enabled", "notifications_disabled" "legacy_notifications_enabled", "legacy_notifications_disabled", all to be "0" for "enabled"/"active" rule that does not have any actions', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry']),
|
||||
...getThresholdRuleForAlertTesting(['telemetry']),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
|
@ -511,7 +511,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
|
@ -543,13 +543,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false),
|
||||
...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
},
|
||||
};
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule);
|
||||
await createRule(supertest, log, ruleToCreate);
|
||||
|
||||
|
@ -574,17 +574,17 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry']),
|
||||
...getThresholdRuleForAlertTesting(['telemetry']),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
},
|
||||
};
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule);
|
||||
const { id } = await createRule(supertest, log, ruleToCreate);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -607,16 +607,16 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry'], 'rule-1', false),
|
||||
...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
},
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -638,19 +638,19 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForSignalTesting(['telemetry']),
|
||||
...getThresholdRuleForAlertTesting(['telemetry']),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
},
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -738,7 +738,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getSimpleMlRule();
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule);
|
||||
await createRule(supertest, log, ruleToCreate);
|
||||
|
||||
|
@ -763,7 +763,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getSimpleMlRule('rule-1', true);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule);
|
||||
await createRule(supertest, log, ruleToCreate);
|
||||
|
||||
|
@ -786,10 +786,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getSimpleMlRule();
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -811,10 +811,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getSimpleMlRule('rule-1', true);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -887,7 +887,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
|
@ -919,7 +919,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getSimpleThreatMatch();
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, false, rule);
|
||||
await createRule(supertest, log, ruleToCreate);
|
||||
|
||||
|
@ -959,11 +959,11 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
},
|
||||
],
|
||||
};
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule);
|
||||
const { id } = await createRule(supertest, log, ruleToCreate);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -986,10 +986,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getSimpleThreatMatch();
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -1011,7 +1011,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule: ThreatMatchRuleCreateProps = {
|
||||
...getSimpleThreatMatch('rule-1', true),
|
||||
index: ['telemetry'],
|
||||
|
@ -1029,10 +1029,10 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
],
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -1057,7 +1057,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
describe('"pre-packaged"/"immutable" rules', async () => {
|
||||
it('should show stats for totals for in-active pre-packaged rules', async () => {
|
||||
it('@skipInQA should show stats for totals for in-active pre-packaged rules', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -1090,7 +1090,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show stats for the detection_rule_details for a specific pre-packaged rule', async () => {
|
||||
it('@skipInQA should show stats for the detection_rule_details for a specific pre-packaged rule', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -1121,13 +1121,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "notifications_disabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
it('@skipInQA should show "notifications_disabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const newRuleToUpdate = getSimpleRule(immutableRule.rule_id);
|
||||
const ruleToUpdate = getRuleWithWebHookAction(hookAction.id, false, newRuleToUpdate);
|
||||
await updateRule(supertest, log, ruleToUpdate);
|
||||
await updateRule(supertest, ruleToUpdate);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -1174,13 +1174,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "notifications_enabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
it('@skipInQA should show "notifications_enabled" to be "1", "has_notification" to be "true, "has_legacy_notification" to be "false" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const newRuleToUpdate = getSimpleRule(immutableRule.rule_id);
|
||||
const ruleToUpdate = getRuleWithWebHookAction(hookAction.id, true, newRuleToUpdate);
|
||||
await updateRule(supertest, log, ruleToUpdate);
|
||||
await updateRule(supertest, ruleToUpdate);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
@ -1227,12 +1227,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, false);
|
||||
await updateRule(supertest, log, newRuleToUpdate);
|
||||
await updateRule(supertest, newRuleToUpdate);
|
||||
await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
|
@ -1280,12 +1280,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
it('@brokenInServerless should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
const immutableRule = await getRule(supertest, log, ELASTIC_SECURITY_RULE_ID);
|
||||
const hookAction = await createNewAction(supertest, log);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, true);
|
||||
await updateRule(supertest, log, newRuleToUpdate);
|
||||
await updateRule(supertest, newRuleToUpdate);
|
||||
await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
* Copyright 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 '@kbn/expect';
|
||||
|
||||
import type {
|
||||
ThreatMatchRuleCreateProps,
|
||||
ThresholdRuleCreateProps,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { getInitialDetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/get_initial_usage';
|
||||
import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common';
|
||||
import { RulesTypeUsage } from '@kbn/security-solution-plugin/server/usage/detections/rules/types';
|
||||
import {
|
||||
createLegacyRuleAction,
|
||||
createWebHookRuleAction,
|
||||
createRule,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getEqlRuleForAlertTesting,
|
||||
fetchRule,
|
||||
getRuleForAlertTesting,
|
||||
getRuleWithWebHookAction,
|
||||
getSimpleMlRule,
|
||||
getSimpleRule,
|
||||
getSimpleThreatMatch,
|
||||
getStats,
|
||||
getThresholdRuleForAlertTesting,
|
||||
installMockPrebuiltRules,
|
||||
waitForRuleSuccess,
|
||||
waitForAlertsToBePresent,
|
||||
updateRule,
|
||||
deleteAllEventLogExecutionEvents,
|
||||
} from '../../../utils';
|
||||
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const es = getService('es');
|
||||
|
||||
describe('@ess Detection rule legacy actions telemetry', async () => {
|
||||
before(async () => {
|
||||
// Just in case other tests do not clean up the event logs, let us clear them now and here only once.
|
||||
await deleteAllEventLogExecutionEvents(es, log);
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/telemetry');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/security_solution/telemetry');
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
await deleteAllEventLogExecutionEvents(es, log);
|
||||
});
|
||||
|
||||
describe('"kql" rule type', () => {
|
||||
it('should show "notifications_enabled" to be "1" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const ruleToCreate = getRuleWithWebHookAction(hookAction.id, true, rule);
|
||||
const { id } = await createRule(supertest, log, ruleToCreate);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
query: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.query,
|
||||
enabled: 1,
|
||||
alerts: 4,
|
||||
notifications_enabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
enabled: 1,
|
||||
alerts: 4,
|
||||
notifications_enabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
query: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.query,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
query: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.query,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('"eql" rule type', () => {
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry'], 'rule-1', false);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
eql: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.eql,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getEqlRuleForAlertTesting(['telemetry']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
eql: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.eql,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('"threshold" rule type', () => {
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForAlertTesting(['telemetry'], 'rule-1', false),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
},
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
threshold: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threshold,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
...getThresholdRuleForAlertTesting(['telemetry']),
|
||||
threshold: {
|
||||
field: 'keyword',
|
||||
value: 1,
|
||||
},
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
threshold: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threshold,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Note: We don't actually find signals with these tests as we don't have a good way of signal finding with ML rules.
|
||||
describe('"ml" rule type', () => {
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getSimpleMlRule();
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
machine_learning: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.machine_learning,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule = getSimpleMlRule('rule-1', true);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
machine_learning: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.machine_learning,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('"indicator_match/threat_match" rule type', () => {
|
||||
it('should show "legacy_notifications_disabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
const rule = getSimpleThreatMatch();
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
threat_match: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threat_match,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
disabled: 1,
|
||||
legacy_notifications_disabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1" for rule that has at least "1" legacy action(s) and the alert is "enabled"/"active"', async () => {
|
||||
const rule: ThreatMatchRuleCreateProps = {
|
||||
...getSimpleThreatMatch('rule-1', true),
|
||||
index: ['telemetry'],
|
||||
threat_index: ['telemetry'],
|
||||
threat_mapping: [
|
||||
{
|
||||
entries: [
|
||||
{
|
||||
field: 'keyword',
|
||||
value: 'keyword',
|
||||
type: 'mapping',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
await createLegacyRuleAction(supertest, id, hookAction.id);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
const expected: RulesTypeUsage = {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage,
|
||||
threat_match: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.threat_match,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
custom_total: {
|
||||
...getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total,
|
||||
alerts: 4,
|
||||
enabled: 1,
|
||||
legacy_notifications_enabled: 1,
|
||||
},
|
||||
};
|
||||
expect(stats.detection_rules.detection_rule_usage).to.eql(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('"pre-packaged"/"immutable" rules', async () => {
|
||||
it('should show "legacy_notifications_disabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, false);
|
||||
await updateRule(supertest, newRuleToUpdate);
|
||||
await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
// We have to search by "rule_name" since the "rule_id" it is storing is the Saved Object ID and not the rule_id
|
||||
const foundRule = stats.detection_rules.detection_rule_detail.find(
|
||||
(rule) => rule.rule_id === ELASTIC_SECURITY_RULE_ID
|
||||
);
|
||||
if (foundRule == null) {
|
||||
throw new Error('Found rule should not be null. Please change this end to end test.');
|
||||
}
|
||||
const {
|
||||
created_on: createdOn,
|
||||
updated_on: updatedOn,
|
||||
rule_id: ruleId,
|
||||
rule_version: ruleVersion,
|
||||
...omittedFields
|
||||
} = foundRule;
|
||||
expect(omittedFields).to.eql({
|
||||
rule_name: 'Simple Rule Query',
|
||||
rule_type: 'query',
|
||||
enabled: false,
|
||||
elastic_rule: true,
|
||||
alert_count_daily: 0,
|
||||
cases_count_total: 0,
|
||||
has_notification: false,
|
||||
has_legacy_notification: true,
|
||||
has_legacy_investigation_field: false,
|
||||
});
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.notifications_disabled
|
||||
).to.eql(0);
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_enabled
|
||||
).to.eql(0);
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_disabled
|
||||
).to.eql(1);
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.notifications_enabled
|
||||
).to.eql(0);
|
||||
expect(stats.detection_rules.detection_rule_usage.custom_total).to.eql(
|
||||
getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show "legacy_notifications_enabled" to be "1", "has_notification" to be "false, "has_legacy_notification" to be "true" for rule that has at least "1" action(s) and the alert is "enabled"/"active"', async () => {
|
||||
await installMockPrebuiltRules(supertest, es);
|
||||
const immutableRule = await fetchRule(supertest, { ruleId: ELASTIC_SECURITY_RULE_ID });
|
||||
const hookAction = await createWebHookRuleAction(supertest);
|
||||
const newRuleToUpdate = getSimpleRule(immutableRule.rule_id, true);
|
||||
await updateRule(supertest, newRuleToUpdate);
|
||||
await createLegacyRuleAction(supertest, immutableRule.id, hookAction.id);
|
||||
|
||||
await retry.try(async () => {
|
||||
const stats = await getStats(supertest, log);
|
||||
// We have to search by "rule_name" since the "rule_id" it is storing is the Saved Object ID and not the rule_id
|
||||
const foundRule = stats.detection_rules.detection_rule_detail.find(
|
||||
(rule) => rule.rule_id === ELASTIC_SECURITY_RULE_ID
|
||||
);
|
||||
if (foundRule == null) {
|
||||
throw new Error('Found rule should not be null. Please change this end to end test.');
|
||||
}
|
||||
const {
|
||||
created_on: createdOn,
|
||||
updated_on: updatedOn,
|
||||
rule_id: ruleId,
|
||||
rule_version: ruleVersion,
|
||||
...omittedFields
|
||||
} = foundRule;
|
||||
expect(omittedFields).to.eql({
|
||||
rule_name: 'Simple Rule Query',
|
||||
rule_type: 'query',
|
||||
enabled: true,
|
||||
elastic_rule: true,
|
||||
alert_count_daily: 0,
|
||||
cases_count_total: 0,
|
||||
has_notification: false,
|
||||
has_legacy_notification: true,
|
||||
has_legacy_investigation_field: false,
|
||||
});
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.notifications_disabled
|
||||
).to.eql(0);
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_enabled
|
||||
).to.eql(1);
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.legacy_notifications_disabled
|
||||
).to.eql(0);
|
||||
expect(
|
||||
stats.detection_rules.detection_rule_usage.elastic_total.notifications_enabled
|
||||
).to.eql(0);
|
||||
expect(stats.detection_rules.detection_rule_usage.custom_total).to.eql(
|
||||
getInitialDetectionMetrics().detection_rules.detection_rule_usage.custom_total
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -6,5 +6,5 @@
|
|||
*/
|
||||
export * from './get_slack_action';
|
||||
export * from './get_web_hook_action';
|
||||
export * from './create_new_action';
|
||||
export * from './create_new_webhook_action';
|
||||
export * from './legacy_actions';
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { ToolingLog } from '@kbn/tooling-log';
|
||||
import type { Client } from '@elastic/elasticsearch';
|
||||
|
||||
import { countDownES } from '../count_down_es';
|
||||
|
||||
/**
|
||||
* Remove all .kibana-event-log-* documents with an execution.uuid
|
||||
* This will retry 50 times before giving up and hopefully still not interfere with other tests
|
||||
* @param es The ElasticSearch handle
|
||||
* @param log The tooling logger
|
||||
*/
|
||||
export const deleteAllEventLogExecutionEvents = async (
|
||||
es: Client,
|
||||
log: ToolingLog
|
||||
): Promise<void> => {
|
||||
return countDownES(
|
||||
async () => {
|
||||
return es.deleteByQuery(
|
||||
{
|
||||
index: '.kibana-event-log-*',
|
||||
q: '_exists_:kibana.alert.rule.execution.uuid',
|
||||
wait_for_completion: true,
|
||||
refresh: true,
|
||||
body: {},
|
||||
},
|
||||
{ meta: true }
|
||||
);
|
||||
},
|
||||
'deleteAllEventLogExecutionEvents',
|
||||
log
|
||||
);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
export * from './delete_all_event_log_execution_events';
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types';
|
||||
import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types';
|
||||
|
||||
/**
|
||||
* Given a body this will return the detection metrics from it.
|
||||
|
@ -24,20 +23,3 @@ export const getDetectionMetricsFromBody = (
|
|||
): DetectionMetrics => {
|
||||
return body[0].stats.stack_stats.kibana.plugins.security_solution.detectionMetrics;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a body this will return the risk engine metrics from it.
|
||||
* @param body The Stats body
|
||||
* @returns Detection metrics
|
||||
*/
|
||||
export const getRiskEngineMetricsFromBody = (
|
||||
body: Array<{
|
||||
stats: {
|
||||
stack_stats: {
|
||||
kibana: { plugins: { security_solution: { riskEngineMetrics: {} } } };
|
||||
};
|
||||
};
|
||||
}>
|
||||
): RiskEngineMetrics => {
|
||||
return body[0].stats.stack_stats.kibana.plugins.security_solution.riskEngineMetrics;
|
||||
};
|
|
@ -8,17 +8,13 @@
|
|||
import type { ToolingLog } from '@kbn/tooling-log';
|
||||
import type SuperTest from 'supertest';
|
||||
import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types';
|
||||
import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types';
|
||||
import {
|
||||
ELASTIC_HTTP_VERSION_HEADER,
|
||||
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
|
||||
} from '@kbn/core-http-common';
|
||||
|
||||
import { getStatsUrl } from './get_stats_url';
|
||||
import {
|
||||
getDetectionMetricsFromBody,
|
||||
getRiskEngineMetricsFromBody,
|
||||
} from './get_detection_metrics_from_body';
|
||||
import { getDetectionMetricsFromBody } from './get_detection_metrics_from_body';
|
||||
|
||||
/**
|
||||
* Gets the stats from the stats endpoint.
|
||||
|
@ -45,29 +41,3 @@ export const getStats = async (
|
|||
|
||||
return getDetectionMetricsFromBody(response.body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the stats from the stats endpoint.
|
||||
* @param supertest The supertest agent.
|
||||
* @returns The detection metrics
|
||||
*/
|
||||
export const getRiskEngineStats = async (
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>,
|
||||
log: ToolingLog
|
||||
): Promise<RiskEngineMetrics> => {
|
||||
const response = await supertest
|
||||
.post(getStatsUrl())
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send({ unencrypted: true, refreshCache: true });
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
||||
`Did not get an expected 200 "ok" when getting the stats for risk engine. CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify(
|
||||
response.body
|
||||
)}, status: ${JSON.stringify(response.status)}`
|
||||
);
|
||||
}
|
||||
|
||||
return getRiskEngineMetricsFromBody(response.body);
|
||||
};
|
|
@ -9,13 +9,11 @@ export * from './exception_list_and_item';
|
|||
export * from './alerts';
|
||||
export * from './actions';
|
||||
export * from './data_generator';
|
||||
export * from './telemetry';
|
||||
export * from './event_log';
|
||||
export * from './machine_learning';
|
||||
|
||||
export * from './rules/get_rule_so_by_id';
|
||||
export * from './rules/create_rule_saved_object';
|
||||
export * from './rules/get_rule_with_legacy_investigation_fields';
|
||||
export * from './get_index_name_from_load';
|
||||
|
||||
export * from './count_down_test';
|
||||
export * from './count_down_es';
|
||||
export * from './update_username';
|
||||
|
@ -23,3 +21,6 @@ export * from './refresh_index';
|
|||
export * from './wait_for';
|
||||
export * from './route_with_namespace';
|
||||
export * from './wait_for_index_to_populate';
|
||||
export * from './get_stats';
|
||||
export * from './get_detection_metrics_from_body';
|
||||
export * from './get_stats_url';
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type SuperTest from 'supertest';
|
||||
|
||||
import { UPDATE_OR_CREATE_LEGACY_ACTIONS } from '@kbn/security-solution-plugin/common/constants';
|
||||
|
||||
export const createLegacyRuleAction = async (
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>,
|
||||
alertId: string,
|
||||
connectorId: string
|
||||
): Promise<unknown> =>
|
||||
supertest
|
||||
.post(UPDATE_OR_CREATE_LEGACY_ACTIONS)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.query({ alert_id: alertId })
|
||||
.send({
|
||||
name: 'Legacy notification with one action',
|
||||
interval: '1h',
|
||||
actions: [
|
||||
{
|
||||
id: connectorId,
|
||||
group: 'default',
|
||||
params: {
|
||||
message: 'Hourly\nRule {{context.rule.name}} generated {{state.signals_count}} alerts',
|
||||
},
|
||||
actionTypeId: '.slack',
|
||||
},
|
||||
],
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { RuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
|
||||
/**
|
||||
* This is a representative ML rule payload as expected by the server
|
||||
* @param ruleId The rule id
|
||||
* @param enabled Set to tru to enable it, by default it is off
|
||||
*/
|
||||
export const getSimpleMlRule = (ruleId = 'rule-1', enabled = false): RuleCreateProps => ({
|
||||
name: 'Simple ML Rule',
|
||||
description: 'Simple Machine Learning Rule',
|
||||
enabled,
|
||||
anomaly_threshold: 44,
|
||||
risk_score: 1,
|
||||
rule_id: ruleId,
|
||||
severity: 'high',
|
||||
machine_learning_job_id: ['some_job_id'],
|
||||
type: 'machine_learning',
|
||||
});
|
|
@ -36,5 +36,8 @@ export * from './preview_rule';
|
|||
export * from './preview_rule_with_exception_entries';
|
||||
export * from './patch_rule';
|
||||
export * from './generate_event';
|
||||
export * from './create_legacy_rule_action';
|
||||
export * from './get_simple_threat_match';
|
||||
export * from './get_simple_ml_rule';
|
||||
|
||||
export * from './prebuilt_rules';
|
||||
|
|
|
@ -9,6 +9,10 @@ import type { ToolingLog } from '@kbn/tooling-log';
|
|||
import type SuperTest from 'supertest';
|
||||
|
||||
import { SECURITY_TELEMETRY_URL } from '@kbn/security-solution-plugin/common/constants';
|
||||
import {
|
||||
ELASTIC_HTTP_VERSION_HEADER,
|
||||
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
|
||||
} from '@kbn/core-http-common';
|
||||
|
||||
/**
|
||||
* Gets the stats from the stats endpoint within specifically the security_solutions application.
|
||||
|
@ -23,7 +27,8 @@ export const getSecurityTelemetryStats = async (
|
|||
const response = await supertest
|
||||
.get(SECURITY_TELEMETRY_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send({ unencrypted: true, refreshCache: true });
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
export * from './get_security_telemetry_stats';
|
||||
export * from './remove_time_fields_from_telemetry_stats';
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import type { ToolingLog } from '@kbn/tooling-log';
|
||||
import type { Client } from '@elastic/elasticsearch';
|
||||
import { waitFor } from '../../../../detection_engine_api_integration/utils/wait_for';
|
||||
import { waitFor } from './wait_for';
|
||||
|
||||
/**
|
||||
* Waits for the given index to contain documents
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types';
|
||||
|
||||
/**
|
||||
* Given a body this will return the risk engine metrics from it.
|
||||
* @param body The Stats body
|
||||
* @returns Detection metrics
|
||||
*/
|
||||
export const getRiskEngineMetricsFromBody = (
|
||||
body: Array<{
|
||||
stats: {
|
||||
stack_stats: {
|
||||
kibana: { plugins: { security_solution: { riskEngineMetrics: {} } } };
|
||||
};
|
||||
};
|
||||
}>
|
||||
): RiskEngineMetrics => {
|
||||
return body[0].stats.stack_stats.kibana.plugins.security_solution.riskEngineMetrics;
|
||||
};
|
|
@ -7,44 +7,14 @@
|
|||
|
||||
import type { ToolingLog } from '@kbn/tooling-log';
|
||||
import type SuperTest from 'supertest';
|
||||
import type { DetectionMetrics } from '@kbn/security-solution-plugin/server/usage/detections/types';
|
||||
import type { RiskEngineMetrics } from '@kbn/security-solution-plugin/server/usage/risk_engine/types';
|
||||
import {
|
||||
ELASTIC_HTTP_VERSION_HEADER,
|
||||
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
|
||||
} from '@kbn/core-http-common';
|
||||
|
||||
import { getStatsUrl } from '../../../../detection_engine_api_integration/utils/get_stats_url';
|
||||
import {
|
||||
getDetectionMetricsFromBody,
|
||||
getRiskEngineMetricsFromBody,
|
||||
} from '../../../../detection_engine_api_integration/utils/get_detection_metrics_from_body';
|
||||
|
||||
/**
|
||||
* Gets the stats from the stats endpoint.
|
||||
* @param supertest The supertest agent.
|
||||
* @returns The detection metrics
|
||||
*/
|
||||
export const getStats = async (
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>,
|
||||
log: ToolingLog
|
||||
): Promise<DetectionMetrics> => {
|
||||
const response = await supertest
|
||||
.post(getStatsUrl())
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set(ELASTIC_HTTP_VERSION_HEADER, '2')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send({ unencrypted: true, refreshCache: true });
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
||||
`Did not get an expected 200 "ok" when getting the stats for detections. CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify(
|
||||
response.body
|
||||
)}, status: ${JSON.stringify(response.status)}`
|
||||
);
|
||||
}
|
||||
|
||||
return getDetectionMetricsFromBody(response.body);
|
||||
};
|
||||
import { getStatsUrl } from '../../detections_response/utils/get_stats_url';
|
||||
import { getRiskEngineMetricsFromBody } from './get_risk_engine_metrics_from_body';
|
||||
|
||||
/**
|
||||
* Gets the stats from the stats endpoint.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue