mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[Security Solution][API testing] Move and restructures Alerts' tests (#170350)
## 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 Alerts - Introduced a new folder called `alerts` under `security_solution_api_integration` - Moved the utility files associated with alerts to the new directory `security_solution_api_integration`. Files that were not actively used in the previous folder were moved, while any duplicate files remained in their original positions. - Updated the CodeOwner file for the newly moved tests - Old / new groups details and execution time [document](https://docs.google.com/document/d/1CRFfDWMzw3ob03euWIvT4-IoiLXjoiPWI8mTBqP4Zks/edit) | Action | File | New Path if moved | |--------|------|----------| | Delete| group1/find_rule_exception_references.ts| Already moved in previous PR | | Delete|security_and_spaces/group6 | - | | Move|detection_engine_api_integration/security_and_spaces/group6 |detections_response/default_license/alerts/alerts_compatibility.ts| | Move|detection_engine_api_integration/security_and_spaces/group1| detections_response/default_license/alerts/aliases.ts | | Move |detection_engine_api_integration/security_and_spaces/group1| detections_response/default_license/alerts/create_index.ts| | Move|detection_engine_api_integration/security_and_spaces/group10/create_signals_migrations| detections_response/default_license/alerts/migrations/create_alerts_migrations.ts | | Move|detection_engine_api_integration/security_and_spaces/group10/delete_signals_migrations| detections_response/default_license/alerts/migrations/delete_alerts_migrations.ts| | Move|detection_engine_api_integration/security_and_spaces/group10/finalize_signals_migrations| detections_response/default_license/alerts/migrations/finalize_alerts_migrations.ts | | Move|detection_engine_api_integration/security_and_spaces/group10/get_signals_migration_status| detections_response/default_license/alerts/migrations/get_alerts_migration_status.ts| | Move|detection_engine_api_integration/security_and_spaces/group10/open_close_signals| detections_response/default_license/alerts/open_close_alerts.ts| | Move|detection_engine_api_integration/security_and_spaces/group10/alert_tags| detections_response/default_license/alerts/alert_tags.ts| Note: these tests are skipped on the main branch https://github.com/elastic/kibana/blob/main/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts#L215 https://github.com/elastic/kibana/blob/main/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/open_close_signals.ts#L252 https://github.com/elastic/kibana/blob/main/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/finalize_signals_migrations.ts#L192 https://github.com/elastic/kibana/blob/main/x-pack/test/detection_engine_api_integration/security_and_spaces/group1/create_index.ts#L42 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
550b3cf08d
commit
2b5f4f7a0a
43 changed files with 576 additions and 528 deletions
|
@ -225,7 +225,6 @@ enabled:
|
|||
- 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/group5/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/group6/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/group10/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/config.ts
|
||||
- x-pack/test/detection_engine_api_integration/security_and_spaces/prebuilt_rules/config.ts
|
||||
|
@ -461,6 +460,8 @@ enabled:
|
|||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_creation/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/actions/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/actions/configs/ess.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/alerts/configs/serverless.config.ts
|
||||
- x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/alerts/configs/ess.config.ts
|
||||
|
||||
|
||||
|
||||
|
|
6
.github/CODEOWNERS
vendored
6
.github/CODEOWNERS
vendored
|
@ -1312,8 +1312,10 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib
|
|||
/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics @elastic/security-detection-engine
|
||||
/x-pack/test/security_solution_cypress/cypress/e2e/exceptions @elastic/security-detection-engine
|
||||
/x-pack/test/security_solution_cypress/cypress/e2e/overview @elastic/security-detection-engine
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/exceptions @elastic/security-detection-engine
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/rule_creation @elastic/security-detection-engine
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/exceptions @elastic/security-detection-engine
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/rule_creation @elastic/security-detection-engine
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/actions @elastic/security-detection-engine
|
||||
x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/alerts @elastic/security-detection-engine
|
||||
|
||||
## Security Threat Intelligence - Under Security Platform
|
||||
/x-pack/plugins/security_solution/public/common/components/threat_match @elastic/security-detection-engine
|
||||
|
|
|
@ -1,230 +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.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import {
|
||||
CreateExceptionListSchema,
|
||||
ExceptionListTypeEnum,
|
||||
} from '@kbn/securitysolution-io-ts-list-types';
|
||||
|
||||
import { getCreateExceptionListMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_schema.mock';
|
||||
import {
|
||||
DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL,
|
||||
RuleReferencesSchema,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine/rule_exceptions';
|
||||
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import {
|
||||
createRule,
|
||||
getSimpleRule,
|
||||
createSignalsIndex,
|
||||
deleteAllAlerts,
|
||||
deleteAllRules,
|
||||
createExceptionList,
|
||||
} from '../../utils';
|
||||
import { deleteAllExceptions } from '../../../lists_api_integration/utils';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const log = getService('log');
|
||||
const es = getService('es');
|
||||
|
||||
describe('find_rule_exception_references', () => {
|
||||
before(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteAllExceptions(supertest, log);
|
||||
});
|
||||
|
||||
it('returns empty array per list_id if no references are found', async () => {
|
||||
// create exception list
|
||||
const newExceptionList: CreateExceptionListSchema = {
|
||||
...getCreateExceptionListMinimalSchemaMock(),
|
||||
list_id: 'i_exist',
|
||||
namespace_type: 'single',
|
||||
type: ExceptionListTypeEnum.DETECTION,
|
||||
};
|
||||
const exceptionList = await createExceptionList(supertest, log, newExceptionList);
|
||||
|
||||
// create rule
|
||||
await createRule(supertest, log, getSimpleRule('rule-1'));
|
||||
|
||||
const { body: references } = await supertest
|
||||
.get(DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.query({
|
||||
ids: `${exceptionList.id}`,
|
||||
list_ids: `${exceptionList.list_id}`,
|
||||
namespace_types: `${exceptionList.namespace_type}`,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const {
|
||||
_version,
|
||||
id,
|
||||
created_at,
|
||||
created_by,
|
||||
tie_breaker_id,
|
||||
updated_at,
|
||||
updated_by,
|
||||
...referencesWithoutServerValues
|
||||
} = references.references[0].i_exist;
|
||||
|
||||
expect({
|
||||
references: [
|
||||
{
|
||||
i_exist: {
|
||||
...referencesWithoutServerValues,
|
||||
},
|
||||
},
|
||||
],
|
||||
}).to.eql({
|
||||
references: [
|
||||
{
|
||||
i_exist: {
|
||||
description: 'some description',
|
||||
immutable: false,
|
||||
list_id: 'i_exist',
|
||||
name: 'some name',
|
||||
namespace_type: 'single',
|
||||
os_types: [],
|
||||
tags: [],
|
||||
type: 'detection',
|
||||
version: 1,
|
||||
referenced_rules: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('returns empty array per list_id if list does not exist', async () => {
|
||||
// create rule
|
||||
await createRule(supertest, log, getSimpleRule('rule-1'));
|
||||
|
||||
const { body: references } = await supertest
|
||||
.get(DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.query({
|
||||
ids: `1234`,
|
||||
list_ids: `i_dont_exist`,
|
||||
namespace_types: `single`,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(references).to.eql({ references: [] });
|
||||
});
|
||||
|
||||
it('returns found references', async () => {
|
||||
// create exception list
|
||||
const newExceptionList: CreateExceptionListSchema = {
|
||||
...getCreateExceptionListMinimalSchemaMock(),
|
||||
list_id: 'i_exist',
|
||||
namespace_type: 'single',
|
||||
type: ExceptionListTypeEnum.DETECTION,
|
||||
};
|
||||
const exceptionList = await createExceptionList(supertest, log, newExceptionList);
|
||||
const exceptionList2 = await createExceptionList(supertest, log, {
|
||||
...newExceptionList,
|
||||
list_id: 'i_exist_2',
|
||||
});
|
||||
|
||||
// create rule
|
||||
await createRule(supertest, log, {
|
||||
...getSimpleRule('rule-2'),
|
||||
exceptions_list: [
|
||||
{
|
||||
id: `${exceptionList.id}`,
|
||||
list_id: `${exceptionList.list_id}`,
|
||||
namespace_type: `${exceptionList.namespace_type}`,
|
||||
type: `${exceptionList.type}`,
|
||||
},
|
||||
{
|
||||
id: `${exceptionList2.id}`,
|
||||
list_id: `${exceptionList2.list_id}`,
|
||||
namespace_type: `${exceptionList2.namespace_type}`,
|
||||
type: `${exceptionList2.type}`,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { body: references } = await supertest
|
||||
.get(DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.query({
|
||||
ids: `${exceptionList.id},${exceptionList2.id}`,
|
||||
list_ids: `${exceptionList.list_id},${exceptionList2.list_id}`,
|
||||
namespace_types: `${exceptionList.namespace_type},${exceptionList2.namespace_type}`,
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const refs = references.references.flatMap((ref: RuleReferencesSchema) => Object.keys(ref));
|
||||
|
||||
expect(refs.sort()).to.eql(['i_exist', 'i_exist_2'].sort());
|
||||
});
|
||||
|
||||
it('returns found references for all existing exception lists if no list id/list_id passed in', async () => {
|
||||
// create exception list
|
||||
const newExceptionList: CreateExceptionListSchema = {
|
||||
...getCreateExceptionListMinimalSchemaMock(),
|
||||
list_id: 'i_exist',
|
||||
namespace_type: 'single',
|
||||
type: ExceptionListTypeEnum.DETECTION,
|
||||
};
|
||||
const exceptionList = await createExceptionList(supertest, log, newExceptionList);
|
||||
const exceptionList2 = await createExceptionList(supertest, log, {
|
||||
...newExceptionList,
|
||||
list_id: 'i_exist_2',
|
||||
});
|
||||
|
||||
// create rule
|
||||
await createRule(supertest, log, {
|
||||
...getSimpleRule('rule-2'),
|
||||
exceptions_list: [
|
||||
{
|
||||
id: `${exceptionList.id}`,
|
||||
list_id: `${exceptionList.list_id}`,
|
||||
namespace_type: `${exceptionList.namespace_type}`,
|
||||
type: `${exceptionList.type}`,
|
||||
},
|
||||
{
|
||||
id: `${exceptionList2.id}`,
|
||||
list_id: `${exceptionList2.list_id}`,
|
||||
namespace_type: `${exceptionList2.namespace_type}`,
|
||||
type: `${exceptionList2.type}`,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { body: references } = await supertest
|
||||
.get(DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.query({
|
||||
namespace_types: 'single,agnostic',
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
const refs = references.references.flatMap((ref: RuleReferencesSchema) => Object.keys(ref));
|
||||
expect(refs.sort()).to.eql(['i_exist', 'i_exist_2', 'endpoint_list'].sort());
|
||||
});
|
||||
});
|
||||
};
|
|
@ -14,15 +14,12 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
|
|||
// action migration code. We are monitoring legacy action telemetry to clean up once we see their
|
||||
// existence being near 0.
|
||||
|
||||
loadTestFile(require.resolve('./aliases'));
|
||||
loadTestFile(require.resolve('./check_privileges'));
|
||||
loadTestFile(require.resolve('./create_index'));
|
||||
loadTestFile(require.resolve('./create_rules_bulk'));
|
||||
loadTestFile(require.resolve('./delete_rules'));
|
||||
loadTestFile(require.resolve('./delete_rules_bulk'));
|
||||
loadTestFile(require.resolve('./export_rules'));
|
||||
loadTestFile(require.resolve('./find_rules'));
|
||||
loadTestFile(require.resolve('./find_rule_exception_references'));
|
||||
loadTestFile(require.resolve('./get_rule_management_filters'));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -26,11 +26,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
|
|||
loadTestFile(require.resolve('./perform_bulk_action_dry_run'));
|
||||
loadTestFile(require.resolve('./patch_rules'));
|
||||
loadTestFile(require.resolve('./read_privileges'));
|
||||
loadTestFile(require.resolve('./open_close_signals'));
|
||||
loadTestFile(require.resolve('./get_signals_migration_status'));
|
||||
loadTestFile(require.resolve('./create_signals_migrations'));
|
||||
loadTestFile(require.resolve('./finalize_signals_migrations'));
|
||||
loadTestFile(require.resolve('./delete_signals_migrations'));
|
||||
loadTestFile(require.resolve('./timestamps'));
|
||||
loadTestFile(require.resolve('./runtime'));
|
||||
loadTestFile(require.resolve('./throttle'));
|
||||
|
@ -40,6 +35,5 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
|
|||
loadTestFile(require.resolve('./risk_engine/risk_score_calculation'));
|
||||
loadTestFile(require.resolve('./risk_engine/risk_scoring_task_execution'));
|
||||
loadTestFile(require.resolve('./risk_engine/telemetry_usage'));
|
||||
loadTestFile(require.resolve('./set_alert_tags'));
|
||||
});
|
||||
};
|
||||
|
|
|
@ -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 signals/alerts compatibility', function () {
|
||||
loadTestFile(require.resolve('./alerts_compatibility'));
|
||||
});
|
||||
};
|
|
@ -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 6', function () {
|
||||
loadTestFile(require.resolve('./alerts'));
|
||||
});
|
||||
};
|
|
@ -25,7 +25,6 @@ export * from './delete_all_rule_execution_info';
|
|||
export * from './delete_all_alerts';
|
||||
export * from './delete_all_timelines';
|
||||
export * from './delete_exception_list';
|
||||
export * from './delete_migrations';
|
||||
export * from './delete_rule';
|
||||
export * from './downgrade_immutable_rule';
|
||||
export * from './finalize_signals_migration';
|
||||
|
@ -35,14 +34,12 @@ 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_index_name_from_load';
|
||||
export * from './get_legacy_action_notification_so';
|
||||
export * from './get_open_signals';
|
||||
export * from './get_preview_alerts';
|
||||
export * from './get_query_all_signals';
|
||||
export * from './get_query_signal_ids';
|
||||
export * from './get_query_signals_ids';
|
||||
export * from './get_query_signals_rule_id';
|
||||
export * from './get_query_signal_ids';
|
||||
export * from './get_rule';
|
||||
export * from './get_rules_as_ndjson';
|
||||
export * from './get_rule_for_signal_testing';
|
||||
|
@ -53,7 +50,6 @@ 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_signal_status_empty_response';
|
||||
export * from './get_signals_by_id';
|
||||
export * from './get_signals_by_ids';
|
||||
export * from './get_signals_by_rule_ids';
|
||||
|
@ -93,7 +89,6 @@ export * from './update_rule';
|
|||
export * from './wait_for';
|
||||
export * from './wait_for_alert_to_complete';
|
||||
export * from './wait_for_event_log_execute_complete';
|
||||
export * from './wait_for_index_to_populate';
|
||||
export * from './wait_for_rule_status';
|
||||
export * from './wait_for_signals_to_be_present';
|
||||
export * from './prebuilt_rules/create_prebuilt_rule_saved_objects';
|
||||
|
|
|
@ -36,6 +36,11 @@
|
|||
"actions:runner:serverless": "npm run run-tests:dr:default actions serverless serverlessEnv",
|
||||
"actions:qa:serverless": "npm run run-tests:dr:default actions serverless qaEnv",
|
||||
"actions:server:ess": "npm run initialize-server:dr:default actions ess",
|
||||
"actions:runner:ess": "npm run run-tests:dr:default actions ess essEnv"
|
||||
"actions:runner:ess": "npm run run-tests:dr:default actions ess essEnv",
|
||||
"alerts:server:serverless": "npm run initialize-server:dr:default alerts serverless",
|
||||
"alerts:runner:serverless": "npm run run-tests:dr:default alerts serverless serverlessEnv",
|
||||
"alerts:qa:serverless": "npm run run-tests:dr:default alerts serverless qaEnv",
|
||||
"alerts:server:ess": "npm run initialize-server:dr:default alerts ess",
|
||||
"alerts:runner:ess": "npm run run-tests:dr:default alerts ess essEnv"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,32 +22,31 @@ import {
|
|||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import {
|
||||
createRule,
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
finalizeSignalsMigration,
|
||||
getEqlRuleForSignalTesting,
|
||||
getRuleForSignalTesting,
|
||||
getSavedQueryRuleForSignalTesting,
|
||||
getSignalsByIds,
|
||||
getThreatMatchRuleForSignalTesting,
|
||||
getThresholdRuleForSignalTesting,
|
||||
startSignalsMigration,
|
||||
finalizeAlertsMigration,
|
||||
getEqlRuleForAlertTesting,
|
||||
getRuleForAlertTesting,
|
||||
getSavedQueryRuleForAlertTesting,
|
||||
getAlertsByIds,
|
||||
getThreatMatchRuleForAlertTesting,
|
||||
getThresholdRuleForAlertTesting,
|
||||
startAlertsMigration,
|
||||
waitFor,
|
||||
waitForRuleSuccess,
|
||||
waitForSignalsToBePresent,
|
||||
} from '../../../utils';
|
||||
import { FtrProviderContext } from '../../../common/ftr_provider_context';
|
||||
import { removeRandomValuedProperties } from '../../rule_execution_logic/utils';
|
||||
waitForAlertsToBePresent,
|
||||
removeRandomValuedProperties,
|
||||
} from '../../utils';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const log = getService('log');
|
||||
const supertest = getService('supertest');
|
||||
const es = getService('es');
|
||||
|
||||
describe('Alerts Compatibility', function () {
|
||||
describe('@ess Alerts Compatibility', function () {
|
||||
describe('CTI', () => {
|
||||
const expectedDomain = 'elastic.local';
|
||||
const expectedProvider = 'provider1';
|
||||
|
@ -63,7 +62,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
await esArchiver.load(
|
||||
'x-pack/test/functional/es_archives/security_solution/legacy_cti_signals'
|
||||
);
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -124,14 +123,14 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(indices.length).to.eql(1);
|
||||
expect(indices[0].is_outdated).to.eql(true);
|
||||
|
||||
const [migration] = await startSignalsMigration({
|
||||
const [migration] = await startAlertsMigration({
|
||||
indices: [indices[0].index],
|
||||
supertest,
|
||||
log,
|
||||
});
|
||||
await waitFor(
|
||||
async () => {
|
||||
const [{ completed }] = await finalizeSignalsMigration({
|
||||
const [{ completed }] = await finalizeAlertsMigration({
|
||||
migrationIds: [migration.migration_id],
|
||||
supertest,
|
||||
log,
|
||||
|
@ -183,26 +182,26 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should generate a signal-on-legacy-signal with legacy index pattern', async () => {
|
||||
const rule: ThreatMatchRuleCreateProps = getThreatMatchRuleForSignalTesting([
|
||||
const rule: ThreatMatchRuleCreateProps = getThreatMatchRuleForAlertTesting([
|
||||
'.siem-signals-*',
|
||||
]);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('should generate a signal-on-legacy-signal with AAD index pattern', async () => {
|
||||
const rule: ThreatMatchRuleCreateProps = getThreatMatchRuleForSignalTesting([
|
||||
const rule: ThreatMatchRuleCreateProps = getThreatMatchRuleForAlertTesting([
|
||||
`.alerts-security.alerts-default`,
|
||||
]);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -212,7 +211,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('Query', () => {
|
||||
beforeEach(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alerts/7.16.0');
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -224,11 +223,11 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should generate a signal-on-legacy-signal with legacy index pattern', async () => {
|
||||
const rule: QueryRuleCreateProps = getRuleForSignalTesting([`.siem-signals-*`]);
|
||||
const rule: QueryRuleCreateProps = getRuleForAlertTesting([`.siem-signals-*`]);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -384,13 +383,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should generate a signal-on-legacy-signal with AAD index pattern', async () => {
|
||||
const rule: QueryRuleCreateProps = getRuleForSignalTesting([
|
||||
const rule: QueryRuleCreateProps = getRuleForAlertTesting([
|
||||
`.alerts-security.alerts-default`,
|
||||
]);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -549,7 +548,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('Saved Query', () => {
|
||||
beforeEach(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alerts/7.16.0');
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -562,13 +561,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should generate a signal-on-legacy-signal with legacy index pattern', async () => {
|
||||
const rule: SavedQueryRuleCreateProps = {
|
||||
...getSavedQueryRuleForSignalTesting([`.siem-signals-*`]),
|
||||
...getSavedQueryRuleForAlertTesting([`.siem-signals-*`]),
|
||||
query: 'agent.name: "security-linux-1.example.dev"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -576,13 +575,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should generate a signal-on-legacy-signal with AAD index pattern', async () => {
|
||||
const rule: SavedQueryRuleCreateProps = {
|
||||
...getSavedQueryRuleForSignalTesting([`.alerts-security.alerts-default`]),
|
||||
...getSavedQueryRuleForAlertTesting([`.alerts-security.alerts-default`]),
|
||||
query: 'agent.name: "security-linux-1.example.dev"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -592,7 +591,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('EQL', () => {
|
||||
beforeEach(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alerts/7.16.0');
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -605,13 +604,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should generate a signal-on-legacy-signal with legacy index pattern', async () => {
|
||||
const rule: EqlRuleCreateProps = {
|
||||
...getEqlRuleForSignalTesting(['.siem-signals-*']),
|
||||
...getEqlRuleForAlertTesting(['.siem-signals-*']),
|
||||
query: 'any where agent.name == "security-linux-1.example.dev"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -619,13 +618,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should generate a signal-on-legacy-signal with AAD index pattern', async () => {
|
||||
const rule: EqlRuleCreateProps = {
|
||||
...getEqlRuleForSignalTesting([`.alerts-security.alerts-default`]),
|
||||
...getEqlRuleForAlertTesting([`.alerts-security.alerts-default`]),
|
||||
query: 'any where agent.name == "security-linux-1.example.dev"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
|
@ -635,7 +634,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
describe('Threshold', () => {
|
||||
beforeEach(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alerts/7.16.0');
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -647,7 +646,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should generate a signal-on-legacy-signal with legacy index pattern', async () => {
|
||||
const baseRule: ThresholdRuleCreateProps = getThresholdRuleForSignalTesting([
|
||||
const baseRule: ThresholdRuleCreateProps = getThresholdRuleForAlertTesting([
|
||||
'.siem-signals-*',
|
||||
]);
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
|
@ -660,15 +659,15 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
||||
});
|
||||
|
||||
it('should generate a signal-on-legacy-signal with AAD index pattern', async () => {
|
||||
const baseRule: ThresholdRuleCreateProps = getThresholdRuleForSignalTesting([
|
||||
const baseRule: ThresholdRuleCreateProps = getThresholdRuleForAlertTesting([
|
||||
`.alerts-security.alerts-default`,
|
||||
]);
|
||||
const rule: ThresholdRuleCreateProps = {
|
||||
|
@ -681,8 +680,8 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).greaterThan(0);
|
||||
const hit = signalsOpen.hits.hits[0];
|
||||
expect(hit._source?.kibana).to.eql(undefined);
|
|
@ -7,19 +7,18 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import {
|
||||
createRule,
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllRules,
|
||||
deleteAllAlerts,
|
||||
getRuleForSignalTesting,
|
||||
getSignalsById,
|
||||
getRuleForAlertTesting,
|
||||
getAlertsById,
|
||||
waitForRuleSuccess,
|
||||
waitForSignalsToBePresent,
|
||||
waitForAlertsToBePresent,
|
||||
} 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');
|
||||
|
@ -30,7 +29,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
name: string;
|
||||
}
|
||||
|
||||
describe('Tests involving aliases of source indexes and the signals index', () => {
|
||||
describe('@ess Tests involving aliases of source indexes and the alerts index', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alias');
|
||||
});
|
||||
|
@ -40,7 +39,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -49,25 +48,25 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
it('should keep the original alias value such as "host_alias" from a source index when the value is indexed', async () => {
|
||||
const rule = getRuleForSignalTesting(['host_alias']);
|
||||
const rule = getRuleForAlertTesting(['host_alias']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
const signalsOpen = await getSignalsById(supertest, log, id);
|
||||
const hits = signalsOpen.hits.hits
|
||||
.map((signal) => (signal._source?.host_alias as HostAlias).name)
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
const alertsOpen = await getAlertsById(supertest, log, id);
|
||||
const hits = alertsOpen.hits.hits
|
||||
.map((alert) => (alert._source?.host_alias as HostAlias).name)
|
||||
.sort();
|
||||
expect(hits).to.eql(['host name 1', 'host name 2', 'host name 3', 'host name 4']);
|
||||
});
|
||||
|
||||
it('should copy alias data from a source index into the signals index in the same position when the target is ECS compatible', async () => {
|
||||
const rule = getRuleForSignalTesting(['host_alias']);
|
||||
it('should copy alias data from a source index into the alerts index in the same position when the target is ECS compatible', async () => {
|
||||
const rule = getRuleForAlertTesting(['host_alias']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 4, [id]);
|
||||
const signalsOpen = await getSignalsById(supertest, log, id);
|
||||
const hits = signalsOpen.hits.hits
|
||||
.map((signal) => (signal._source?.host as HostAlias).name)
|
||||
await waitForAlertsToBePresent(supertest, log, 4, [id]);
|
||||
const alertsOpen = await getAlertsById(supertest, log, id);
|
||||
const hits = alertsOpen.hits.hits
|
||||
.map((alert) => (alert._source?.host as HostAlias).name)
|
||||
.sort();
|
||||
expect(hits).to.eql(['host name 1', 'host name 2', 'host name 3', 'host name 4']);
|
||||
});
|
|
@ -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 - Alerts',
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 - Alerts',
|
||||
},
|
||||
});
|
|
@ -13,17 +13,17 @@ import {
|
|||
|
||||
import { SIGNALS_FIELD_ALIASES_VERSION } from '@kbn/security-solution-plugin/server/lib/detection_engine/routes/index/get_signals_template';
|
||||
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import { deleteAllAlerts } from '../../utils';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
|
||||
describe('create_index', () => {
|
||||
describe('@ess create_index', () => {
|
||||
afterEach(async () => {
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
});
|
||||
|
@ -39,7 +39,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
// This fails and should be investigated or removed if it no longer applies
|
||||
it.skip('should report that signals index does not exist', async () => {
|
||||
it.skip('should report that alerts index does not exist', async () => {
|
||||
const { body } = await supertest.get(DETECTION_ENGINE_INDEX_URL).send().expect(404);
|
||||
expect(body).to.eql({ message: 'index for this space does not exist', status_code: 404 });
|
||||
});
|
||||
|
@ -54,7 +54,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with an outdated signals index', () => {
|
||||
describe('with an outdated alerts index', () => {
|
||||
beforeEach(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/endpoint/resolver/signals');
|
||||
});
|
||||
|
@ -63,7 +63,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
await esArchiver.unload('x-pack/test/functional/es_archives/endpoint/resolver/signals');
|
||||
});
|
||||
|
||||
it('should report that signals index is outdated', async () => {
|
||||
it('should report that alerts index is outdated', async () => {
|
||||
const { body } = await supertest.get(DETECTION_ENGINE_INDEX_URL).send().expect(200);
|
||||
expect(body).to.eql({
|
||||
index_mapping_outdated: true,
|
|
@ -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 { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Alerts API', function () {
|
||||
loadTestFile(require.resolve('./aliases'));
|
||||
loadTestFile(require.resolve('./create_index'));
|
||||
loadTestFile(require.resolve('./alerts_compatibility'));
|
||||
loadTestFile(require.resolve('./migrations'));
|
||||
loadTestFile(require.resolve('./open_close_alerts'));
|
||||
loadTestFile(require.resolve('./set_alert_tags'));
|
||||
});
|
||||
}
|
|
@ -15,15 +15,19 @@ import {
|
|||
import { ROLES } from '@kbn/security-solution-plugin/common/test';
|
||||
import { SIGNALS_TEMPLATE_VERSION } from '@kbn/security-solution-plugin/server/lib/detection_engine/routes/index/get_signals_template';
|
||||
import { Signal } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_types/types';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
import {
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteMigrations,
|
||||
deleteAllAlerts,
|
||||
getIndexNameFromLoad,
|
||||
waitForIndexToPopulate,
|
||||
} from '../../utils';
|
||||
import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution';
|
||||
} from '../../../utils';
|
||||
import {
|
||||
createUserAndRole,
|
||||
deleteUserAndRole,
|
||||
} from '../../../../../../common/services/security_solution';
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
interface CreateResponse {
|
||||
index: string;
|
||||
|
@ -35,7 +39,6 @@ function sleep(ms: number) {
|
|||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext): void => {
|
||||
const es = getService('es');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -58,7 +61,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
outdatedSignalsIndexName = getIndexNameFromLoad(
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/signals/outdated_signals_index')
|
||||
);
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
|
@ -13,9 +13,8 @@ import {
|
|||
DETECTION_ENGINE_SIGNALS_MIGRATION_URL,
|
||||
} from '@kbn/security-solution-plugin/common/constants';
|
||||
import { ROLES } from '@kbn/security-solution-plugin/common/test';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import { createSignalsIndex, deleteAllAlerts, getIndexNameFromLoad, waitFor } from '../../utils';
|
||||
import { createUserAndRole } from '../../../common/services/security_solution';
|
||||
import { createAlertsIndex, deleteAllAlerts, getIndexNameFromLoad, waitFor } from '../../../utils';
|
||||
import { createUserAndRole } from '../../../../../../common/services/security_solution';
|
||||
|
||||
interface CreateResponse {
|
||||
index: string;
|
||||
|
@ -27,8 +26,8 @@ interface FinalizeResponse extends CreateResponse {
|
|||
completed?: boolean;
|
||||
error?: unknown;
|
||||
}
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext): void => {
|
||||
const es = getService('es');
|
||||
const esArchiver = getService('esArchiver');
|
||||
|
@ -36,17 +35,17 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
const supertestWithoutAuth = getService('supertestWithoutAuth');
|
||||
const log = getService('log');
|
||||
|
||||
describe('deleting signals migrations', () => {
|
||||
let outdatedSignalsIndexName: string;
|
||||
describe('@ess Deleting alerts migrations', () => {
|
||||
let outdatedAlertsIndexName: string;
|
||||
let createdMigration: CreateResponse;
|
||||
let finalizedMigration: FinalizeResponse;
|
||||
|
||||
beforeEach(async () => {
|
||||
outdatedSignalsIndexName = getIndexNameFromLoad(
|
||||
outdatedAlertsIndexName = getIndexNameFromLoad(
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/signals/outdated_signals_index')
|
||||
);
|
||||
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
|
||||
({
|
||||
body: {
|
||||
|
@ -55,7 +54,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
} = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_MIGRATION_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ index: [outdatedSignalsIndexName] })
|
||||
.send({ index: [outdatedAlertsIndexName] })
|
||||
.expect(200));
|
||||
|
||||
await waitFor(
|
||||
|
@ -91,7 +90,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
|
||||
const deletedMigration = body.migrations[0];
|
||||
expect(deletedMigration.id).to.eql(createdMigration.migration_id);
|
||||
expect(deletedMigration.sourceIndex).to.eql(outdatedSignalsIndexName);
|
||||
expect(deletedMigration.sourceIndex).to.eql(outdatedAlertsIndexName);
|
||||
});
|
||||
|
||||
it('marks the original index for deletion by applying our cleanup policy', async () => {
|
|
@ -13,15 +13,17 @@ import {
|
|||
DETECTION_ENGINE_SIGNALS_MIGRATION_URL,
|
||||
} from '@kbn/security-solution-plugin/common/constants';
|
||||
import { ROLES } from '@kbn/security-solution-plugin/common/test';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import {
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteMigrations,
|
||||
deleteAllAlerts,
|
||||
getIndexNameFromLoad,
|
||||
waitFor,
|
||||
} from '../../utils';
|
||||
import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution';
|
||||
} from '../../../utils';
|
||||
import {
|
||||
createUserAndRole,
|
||||
deleteUserAndRole,
|
||||
} from '../../../../../../common/services/security_solution';
|
||||
|
||||
interface StatusResponse {
|
||||
index: string;
|
||||
|
@ -39,8 +41,8 @@ interface FinalizeResponse {
|
|||
completed?: boolean;
|
||||
error?: unknown;
|
||||
}
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext): void => {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kbnClient = getService('kibanaServer');
|
||||
|
@ -49,7 +51,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
const log = getService('log');
|
||||
const es = getService('es');
|
||||
|
||||
const getSignalsMigrationStatus = async (query: any) => {
|
||||
const getAlertsMigrationStatus = async (query: any) => {
|
||||
const { body } = await supertest
|
||||
.get(DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL)
|
||||
.query(query)
|
||||
|
@ -62,28 +64,28 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
return filteredIndices;
|
||||
};
|
||||
|
||||
describe('Finalizing signals migrations', () => {
|
||||
let legacySignalsIndexName: string;
|
||||
let outdatedSignalsIndexName: string;
|
||||
describe('@ess Finalizing Alerts migrations', () => {
|
||||
let legacyAlertsIndexName: string;
|
||||
let outdatedAlertsIndexName: string;
|
||||
let createdMigrations: CreateResponse[];
|
||||
let createdMigration: CreateResponse;
|
||||
|
||||
beforeEach(async () => {
|
||||
createdMigrations = [];
|
||||
legacySignalsIndexName = getIndexNameFromLoad(
|
||||
legacyAlertsIndexName = getIndexNameFromLoad(
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/signals/legacy_signals_index')
|
||||
);
|
||||
outdatedSignalsIndexName = getIndexNameFromLoad(
|
||||
outdatedAlertsIndexName = getIndexNameFromLoad(
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/signals/outdated_signals_index')
|
||||
);
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
|
||||
({
|
||||
body: { indices: createdMigrations },
|
||||
} = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_MIGRATION_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ index: [legacySignalsIndexName] })
|
||||
.send({ index: [legacyAlertsIndexName] })
|
||||
.expect(200));
|
||||
|
||||
[createdMigration] = createdMigrations;
|
||||
|
@ -91,7 +93,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
|
||||
afterEach(async () => {
|
||||
// Finalize the migration after each test so that the .siem-signals alias gets added to the migrated index -
|
||||
// this allows deleteSignalsIndex to find and delete the migrated index
|
||||
// this allows deleteAlertsIndex to find and delete the migrated index
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
|
@ -107,7 +109,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
|
||||
it('replaces the original index alias with the migrated one', async () => {
|
||||
const statusResponses: StatusResponse[] = await getSignalsMigrationStatus({
|
||||
const statusResponses: StatusResponse[] = await getAlertsMigrationStatus({
|
||||
from: '2020-10-10',
|
||||
});
|
||||
const indicesBefore = statusResponses.map((index) => index.index);
|
||||
|
@ -160,7 +162,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
const { body } = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_MIGRATION_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ index: [outdatedSignalsIndexName] })
|
||||
.send({ index: [outdatedAlertsIndexName] })
|
||||
.expect(200);
|
||||
createdMigrations = [...createdMigrations, ...body.indices];
|
||||
|
||||
|
@ -181,7 +183,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
log
|
||||
);
|
||||
|
||||
const indices = await getSignalsMigrationStatus({ from: '2020-10-10' });
|
||||
const indices = await getAlertsMigrationStatus({ from: '2020-10-10' });
|
||||
expect(indices.map((s: any) => s.index)).to.eql([
|
||||
...createdMigrations.map((c) => c.migration_index),
|
||||
]);
|
|
@ -9,11 +9,14 @@ import expect from '@kbn/expect';
|
|||
|
||||
import { DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL } from '@kbn/security-solution-plugin/common/constants';
|
||||
import { ROLES } from '@kbn/security-solution-plugin/common/test';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import { createSignalsIndex, deleteAllAlerts, getIndexNameFromLoad } from '../../utils';
|
||||
import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution';
|
||||
import { createAlertsIndex, deleteAllAlerts, getIndexNameFromLoad } from '../../../utils';
|
||||
import {
|
||||
createUserAndRole,
|
||||
deleteUserAndRole,
|
||||
} from '../../../../../../common/services/security_solution';
|
||||
|
||||
import { FtrProviderContext } from '../../../../../ftr_provider_context';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext): void => {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertest = getService('supertest');
|
||||
|
@ -21,7 +24,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
const log = getService('log');
|
||||
const es = getService('es');
|
||||
|
||||
const getSignalsMigrationStatus = async (query: any) => {
|
||||
const getAlertsMigrationStatus = async (query: any) => {
|
||||
const { body } = await supertest
|
||||
.get(DETECTION_ENGINE_SIGNALS_MIGRATION_STATUS_URL)
|
||||
.query(query)
|
||||
|
@ -34,13 +37,13 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
return filteredIndices;
|
||||
};
|
||||
|
||||
describe('Signals migration status', () => {
|
||||
let legacySignalsIndexName: string;
|
||||
describe('Alerts migration status', () => {
|
||||
let legacyAlertsIndexName: string;
|
||||
beforeEach(async () => {
|
||||
legacySignalsIndexName = getIndexNameFromLoad(
|
||||
legacyAlertsIndexName = getIndexNameFromLoad(
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/signals/legacy_signals_index')
|
||||
);
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -48,26 +51,26 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
await deleteAllAlerts(supertest, log, es);
|
||||
});
|
||||
|
||||
it('returns no indexes if no signals exist in the specified range', async () => {
|
||||
const indices = await getSignalsMigrationStatus({ from: '2020-10-20' });
|
||||
it('returns no indexes if no alerts exist in the specified range', async () => {
|
||||
const indices = await getAlertsMigrationStatus({ from: '2020-10-20' });
|
||||
expect(indices).to.eql([]);
|
||||
});
|
||||
|
||||
it('includes an index if its signals are within the specified range', async () => {
|
||||
const indices = await getSignalsMigrationStatus({ from: '2020-10-10' });
|
||||
it('includes an index if its alerts are within the specified range', async () => {
|
||||
const indices = await getAlertsMigrationStatus({ from: '2020-10-10' });
|
||||
expect(indices).length(1);
|
||||
expect(indices[0].index).to.eql(legacySignalsIndexName);
|
||||
expect(indices[0].index).to.eql(legacyAlertsIndexName);
|
||||
});
|
||||
|
||||
it("returns the mappings version and a breakdown of signals' version", async () => {
|
||||
it("returns the mappings version and a breakdown of alerts' version", async () => {
|
||||
const outdatedIndexName = getIndexNameFromLoad(
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/signals/outdated_signals_index')
|
||||
);
|
||||
|
||||
const indices = await getSignalsMigrationStatus({ from: '2020-10-10' });
|
||||
const indices = await getAlertsMigrationStatus({ from: '2020-10-10' });
|
||||
expect(indices).to.eql([
|
||||
{
|
||||
index: legacySignalsIndexName,
|
||||
index: legacyAlertsIndexName,
|
||||
is_outdated: true,
|
||||
migrations: [],
|
||||
signal_versions: [
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 '../../../../../ftr_provider_context';
|
||||
|
||||
export default function ({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Actions API', function () {
|
||||
loadTestFile(require.resolve('./create_alerts_migrations'));
|
||||
loadTestFile(require.resolve('./delete_alerts_migrations'));
|
||||
loadTestFile(require.resolve('./finalize_alerts_migrations'));
|
||||
loadTestFile(require.resolve('./finalize_alerts_migrations'));
|
||||
});
|
||||
}
|
|
@ -15,38 +15,46 @@ import {
|
|||
} from '@kbn/security-solution-plugin/common/constants';
|
||||
import { ROLES } from '@kbn/security-solution-plugin/common/test';
|
||||
import { DetectionAlert } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
import {
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllAlerts,
|
||||
setSignalStatus,
|
||||
setAlertStatus,
|
||||
getAlertUpdateByQueryEmptyResponse,
|
||||
getQuerySignalIds,
|
||||
getQueryAlertIds,
|
||||
deleteAllRules,
|
||||
createRule,
|
||||
waitForSignalsToBePresent,
|
||||
getSignalsByIds,
|
||||
waitForAlertsToBePresent,
|
||||
getAlertsByIds,
|
||||
waitForRuleSuccess,
|
||||
getRuleForSignalTesting,
|
||||
getRuleForAlertTesting,
|
||||
} from '../../utils';
|
||||
import { createUserAndRole, deleteUserAndRole } from '../../../common/services/security_solution';
|
||||
import {
|
||||
createUserAndRole,
|
||||
deleteUserAndRole,
|
||||
} from '../../../../../common/services/security_solution';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
import { EsArchivePathBuilder } from '../../../../es_archive_path_builder';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const supertestWithoutAuth = getService('supertestWithoutAuth');
|
||||
const log = getService('log');
|
||||
const es = getService('es');
|
||||
// TODO: add a new service
|
||||
const config = getService('config');
|
||||
const isServerless = config.get('serverless');
|
||||
const dataPathBuilder = new EsArchivePathBuilder(isServerless);
|
||||
const path = dataPathBuilder.getPath('auditbeat/hosts');
|
||||
|
||||
describe('open_close_signals', () => {
|
||||
describe('@ess @serverless open_close_alerts', () => {
|
||||
describe('validation checks', () => {
|
||||
describe('update by ids', () => {
|
||||
it('should not give errors when querying and the signals index does not exist yet', async () => {
|
||||
it('should not give errors when querying and the alerts index does not exist yet', async () => {
|
||||
const { body } = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(setSignalStatus({ signalIds: ['123'], status: 'open' }))
|
||||
.send(setAlertStatus({ alertIds: ['123'], status: 'open' }))
|
||||
.expect(200);
|
||||
|
||||
// remove any server generated items that are nondeterministic
|
||||
|
@ -55,12 +63,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(body).to.eql(getAlertUpdateByQueryEmptyResponse());
|
||||
});
|
||||
|
||||
it('should not give errors when querying and the signals index does exist and is empty', async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
it('should not give errors when querying and the alerts index does exist and is empty', async () => {
|
||||
await createAlertsIndex(supertest, log);
|
||||
const { body } = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(setSignalStatus({ signalIds: ['123'], status: 'open' }))
|
||||
.send(setAlertStatus({ alertIds: ['123'], status: 'open' }))
|
||||
.expect(200);
|
||||
|
||||
// remove any server generated items that are nondeterministic
|
||||
|
@ -73,11 +81,11 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
describe('update by query', () => {
|
||||
it('should not give errors when querying and the signals index does not exist yet', async () => {
|
||||
it('should not give errors when querying and the alerts index does not exist yet', async () => {
|
||||
const { body } = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(setSignalStatus({ query: { match_all: {} }, status: 'open' }))
|
||||
.send(setAlertStatus({ query: { match_all: {} }, status: 'open' }))
|
||||
.expect(200);
|
||||
|
||||
// remove any server generated items that are indeterministic
|
||||
|
@ -86,12 +94,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(body).to.eql(getAlertUpdateByQueryEmptyResponse());
|
||||
});
|
||||
|
||||
it('should not give errors when querying and the signals index does exist and is empty', async () => {
|
||||
await createSignalsIndex(supertest, log);
|
||||
it('should not give errors when querying and the alerts index does exist and is empty', async () => {
|
||||
await createAlertsIndex(supertest, log);
|
||||
const { body } = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(setSignalStatus({ query: { match_all: {} }, status: 'open' }))
|
||||
.send(setAlertStatus({ query: { match_all: {} }, status: 'open' }))
|
||||
.expect(200);
|
||||
|
||||
// remove any server generated items that are indeterministic
|
||||
|
@ -105,16 +113,16 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
describe('tests with auditbeat data', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts');
|
||||
await esArchiver.load(path);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts');
|
||||
await esArchiver.unload(path);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -122,163 +130,160 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
||||
it('should be able to execute and get 10 signals', async () => {
|
||||
it('should be able to execute and get 10 alerts', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
expect(signalsOpen.hits.hits.length).equal(10);
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alertsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
expect(alertsOpen.hits.hits.length).equal(10);
|
||||
});
|
||||
|
||||
it('should be have set the signals in an open state initially', async () => {
|
||||
it('should be have set the alerts in an open state initially', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
const everySignalOpen = signalsOpen.hits.hits.every(
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alertsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
const everyAlertOpen = alertsOpen.hits.hits.every(
|
||||
(hit) => hit._source?.[ALERT_WORKFLOW_STATUS] === 'open'
|
||||
);
|
||||
expect(everySignalOpen).to.eql(true);
|
||||
expect(everyAlertOpen).to.eql(true);
|
||||
});
|
||||
|
||||
it('should be able to get a count of 10 closed signals when closing 10', async () => {
|
||||
it('should be able to get a count of 10 closed alerts when closing 10', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
const signalIds = signalsOpen.hits.hits.map((signal) => signal._id);
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alertsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alertsOpen.hits.hits.map((alert) => alert._id);
|
||||
|
||||
// set all of the signals to the state of closed. There is no reason to use a waitUntil here
|
||||
// set all of the alerts to the state of closed. There is no reason to use a waitUntil here
|
||||
// as this route intentionally has a waitFor within it and should only return when the query has
|
||||
// the data.
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(setSignalStatus({ signalIds, status: 'closed' }))
|
||||
.send(setAlertStatus({ alertIds, status: 'closed' }))
|
||||
.expect(200);
|
||||
|
||||
const { body: signalsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
const { body: alertsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(signalIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
expect(signalsClosed.hits.hits.length).to.equal(10);
|
||||
expect(alertsClosed.hits.hits.length).to.equal(10);
|
||||
});
|
||||
|
||||
// Test is failing after changing refresh to false
|
||||
it.skip('should be able close signals immediately and they all should be closed', async () => {
|
||||
it('should be able close alerts immediately and they all should be closed', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
const signalIds = signalsOpen.hits.hits.map((signal) => signal._id);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const alertsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alertsOpen.hits.hits.map((alert) => alert._id);
|
||||
|
||||
// set all of the signals to the state of closed. There is no reason to use a waitUntil here
|
||||
// set all of the alerts to the state of closed. There is no reason to use a waitUntil here
|
||||
// as this route intentionally has a waitFor within it and should only return when the query has
|
||||
// the data.
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(setSignalStatus({ signalIds, status: 'closed' }))
|
||||
.send(setAlertStatus({ alertIds, status: 'closed' }))
|
||||
.expect(200);
|
||||
|
||||
const { body: signalsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
const { body: alertsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(signalIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
const everySignalClosed = signalsClosed.hits.hits.every(
|
||||
const everyAlertClosed = alertsClosed.hits.hits.every(
|
||||
(hit) => hit._source?.['kibana.alert.workflow_status'] === 'closed'
|
||||
);
|
||||
expect(everySignalClosed).to.eql(true);
|
||||
expect(everyAlertClosed).to.eql(true);
|
||||
});
|
||||
|
||||
// This fails and should be investigated or removed if it no longer applies
|
||||
it.skip('should be able to close signals with t1 analyst user', async () => {
|
||||
const rule = getRuleForSignalTesting(['auditbeat-*']);
|
||||
it.skip('should be able to close alerts with t1 analyst user', async () => {
|
||||
const rule = getRuleForAlertTesting(['auditbeat-*']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
await createUserAndRole(getService, ROLES.t1_analyst);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
const signalIds = signalsOpen.hits.hits.map((signal) => signal._id);
|
||||
const alertsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alertsOpen.hits.hits.map((alert) => alert._id);
|
||||
|
||||
// Try to set all of the signals to the state of closed.
|
||||
// Try to set all of the alerts to the state of closed.
|
||||
// This should not be possible with the given user.
|
||||
await supertestWithoutAuth
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.auth(ROLES.t1_analyst, 'changeme')
|
||||
.send(setSignalStatus({ signalIds, status: 'closed' }))
|
||||
.send(setAlertStatus({ alertIds, status: 'closed' }))
|
||||
.expect(200);
|
||||
|
||||
// query for the signals with the superuser
|
||||
// to allow a check that the signals were NOT closed with t1 analyst
|
||||
const { body: signalsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
// query for the alerts with the superuser
|
||||
// to allow a check that the alerts were NOT closed with t1 analyst
|
||||
const { body: alertsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(signalIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
const everySignalClosed = signalsClosed.hits.hits.every(
|
||||
const everyAlertClosed = alertsClosed.hits.hits.every(
|
||||
(hit) => hit._source?.['kibana.alert.workflow_status'] === 'closed'
|
||||
);
|
||||
expect(everySignalClosed).to.eql(true);
|
||||
expect(everyAlertClosed).to.eql(true);
|
||||
|
||||
await deleteUserAndRole(getService, ROLES.t1_analyst);
|
||||
});
|
||||
|
||||
// This fails and should be investigated or removed if it no longer applies
|
||||
it.skip('should be able to close signals with soc_manager user', async () => {
|
||||
const rule = getRuleForSignalTesting(['auditbeat-*']);
|
||||
it.skip('should be able to close alerts with soc_manager user', async () => {
|
||||
const rule = getRuleForAlertTesting(['auditbeat-*']);
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 1, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 1, [id]);
|
||||
const userAndRole = ROLES.soc_manager;
|
||||
await createUserAndRole(getService, userAndRole);
|
||||
const signalsOpen = await getSignalsByIds(supertest, log, [id]);
|
||||
const signalIds = signalsOpen.hits.hits.map((signal) => signal._id);
|
||||
const alertsOpen = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alertsOpen.hits.hits.map((alert) => alert._id);
|
||||
|
||||
// Try to set all of the signals to the state of closed.
|
||||
// Try to set all of the alerts to the state of closed.
|
||||
// This should not be possible with the given user.
|
||||
await supertestWithoutAuth
|
||||
.post(DETECTION_ENGINE_SIGNALS_STATUS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.auth(userAndRole, 'changeme') // each user has the same password
|
||||
.send(setSignalStatus({ signalIds, status: 'closed' }))
|
||||
.send(setAlertStatus({ alertIds, status: 'closed' }))
|
||||
.expect(200);
|
||||
|
||||
const { body: signalsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
const { body: alertsClosed }: { body: estypes.SearchResponse<DetectionAlert> } =
|
||||
await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(signalIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
const everySignalClosed = signalsClosed.hits.hits.every(
|
||||
const everyAlertClosed = alertsClosed.hits.hits.every(
|
||||
(hit) => hit._source?.['kibana.alert.workflow_status'] === 'closed'
|
||||
);
|
||||
expect(everySignalClosed).to.eql(true);
|
||||
expect(everyAlertClosed).to.eql(true);
|
||||
|
||||
await deleteUserAndRole(getService, userAndRole);
|
||||
});
|
|
@ -13,28 +13,34 @@ import {
|
|||
DETECTION_ENGINE_ALERT_TAGS_URL,
|
||||
} from '@kbn/security-solution-plugin/common/constants';
|
||||
import { DetectionAlert } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { FtrProviderContext } from '../../common/ftr_provider_context';
|
||||
|
||||
import {
|
||||
createSignalsIndex,
|
||||
createAlertsIndex,
|
||||
deleteAllAlerts,
|
||||
getQuerySignalIds,
|
||||
getQueryAlertIds,
|
||||
deleteAllRules,
|
||||
createRule,
|
||||
waitForSignalsToBePresent,
|
||||
getSignalsByIds,
|
||||
waitForAlertsToBePresent,
|
||||
getAlertsByIds,
|
||||
waitForRuleSuccess,
|
||||
getRuleForSignalTesting,
|
||||
getRuleForAlertTesting,
|
||||
setAlertTags,
|
||||
} from '../../utils';
|
||||
import { setAlertTags } from '../../utils/set_alert_tags';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
import { EsArchivePathBuilder } from '../../../../es_archive_path_builder';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext) => {
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const log = getService('log');
|
||||
const es = getService('es');
|
||||
// TODO: add a new service
|
||||
const config = getService('config');
|
||||
const isServerless = config.get('serverless');
|
||||
const dataPathBuilder = new EsArchivePathBuilder(isServerless);
|
||||
const path = dataPathBuilder.getPath('auditbeat/hosts');
|
||||
|
||||
describe('set_alert_tags', () => {
|
||||
describe('@ess @serverless set_alert_tags', () => {
|
||||
describe('validation checks', () => {
|
||||
it('should give errors when no alert ids are provided', async () => {
|
||||
const { body } = await supertest
|
||||
|
@ -65,19 +71,18 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
// Test is failing after changing refresh to false
|
||||
describe.skip('tests with auditbeat data', () => {
|
||||
describe('tests with auditbeat data', () => {
|
||||
before(async () => {
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts');
|
||||
await esArchiver.load(path);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts');
|
||||
await esArchiver.unload(path);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await deleteAllRules(supertest, log);
|
||||
await createSignalsIndex(supertest, log);
|
||||
await createAlertsIndex(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -86,13 +91,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should be able to add tags to multiple alerts', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alerts.hits.hits.map((alert) => alert._id);
|
||||
|
||||
await supertest
|
||||
|
@ -110,7 +115,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const { body }: { body: estypes.SearchResponse<DetectionAlert> } = await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(alertIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
body.hits.hits.map((alert) => {
|
||||
|
@ -120,13 +125,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should be able to add tags to alerts that have tags already and not duplicate them', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alerts.hits.hits.map((alert) => alert._id);
|
||||
|
||||
await supertest
|
||||
|
@ -156,7 +161,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const { body }: { body: estypes.SearchResponse<DetectionAlert> } = await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(alertIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
body.hits.hits.map((alert) => {
|
||||
|
@ -166,13 +171,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should be able to remove tags', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alerts.hits.hits.map((alert) => alert._id);
|
||||
|
||||
await supertest
|
||||
|
@ -202,7 +207,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const { body }: { body: estypes.SearchResponse<DetectionAlert> } = await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(alertIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
body.hits.hits.map((alert) => {
|
||||
|
@ -212,13 +217,13 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
it('should be able to remove tags that do not exist without breaking', async () => {
|
||||
const rule = {
|
||||
...getRuleForSignalTesting(['auditbeat-*']),
|
||||
...getRuleForAlertTesting(['auditbeat-*']),
|
||||
query: 'process.executable: "/usr/bin/sudo"',
|
||||
};
|
||||
const { id } = await createRule(supertest, log, rule);
|
||||
await waitForRuleSuccess({ supertest, log, id });
|
||||
await waitForSignalsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getSignalsByIds(supertest, log, [id]);
|
||||
await waitForAlertsToBePresent(supertest, log, 10, [id]);
|
||||
const alerts = await getAlertsByIds(supertest, log, [id]);
|
||||
const alertIds = alerts.hits.hits.map((alert) => alert._id);
|
||||
|
||||
await supertest
|
||||
|
@ -236,7 +241,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const { body }: { body: estypes.SearchResponse<DetectionAlert> } = await supertest
|
||||
.post(DETECTION_ENGINE_QUERY_SIGNALS_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send(getQuerySignalIds(alertIds))
|
||||
.send(getQueryAlertIds(alertIds))
|
||||
.expect(200);
|
||||
|
||||
body.hits.hits.map((alert) => {
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 { SignalIds as AlertIds } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
|
||||
export const getQueryAlertIds = (alertIds: AlertIds) => ({
|
||||
query: {
|
||||
terms: {
|
||||
_id: alertIds,
|
||||
},
|
||||
},
|
||||
});
|
|
@ -5,7 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
// TODO rename signal to alert
|
||||
export * from './create_alerts_index';
|
||||
export * from './delete_all_alerts';
|
||||
export * from './wait_for_alert_to_complete';
|
||||
|
@ -15,3 +14,9 @@ export * from './get_open_alerts';
|
|||
export * from './get_alerts_by_ids';
|
||||
export * from './get_query_alerts_ids';
|
||||
export * from './get_alerts_by_id';
|
||||
export * from './remove_random_valued_properties';
|
||||
export * from './set_alert_status';
|
||||
export * from './get_alert_status_empty_response';
|
||||
export * from './get_query_alert_ids';
|
||||
export * from './set_alert_tags';
|
||||
export * from './migrations';
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 { DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL } from '@kbn/security-solution-plugin/common/constants';
|
||||
|
||||
interface FinalizeMigrationResponse {
|
||||
id: string;
|
||||
completed?: boolean;
|
||||
error?: unknown;
|
||||
}
|
||||
|
||||
export const finalizeAlertsMigration = async ({
|
||||
migrationIds,
|
||||
supertest,
|
||||
log,
|
||||
}: {
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>;
|
||||
log: ToolingLog;
|
||||
migrationIds: string[];
|
||||
}): Promise<FinalizeMigrationResponse[]> => {
|
||||
const response = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_FINALIZE_MIGRATION_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ migration_ids: migrationIds });
|
||||
|
||||
const {
|
||||
body: { migrations },
|
||||
}: { body: { migrations: FinalizeMigrationResponse[] } } = response;
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
||||
`Did not get an expected 200 "ok" when finalizing alerts migration (finalizeAlertsMigration). CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify(
|
||||
response.body
|
||||
)}, status: ${JSON.stringify(response.status)}`
|
||||
);
|
||||
}
|
||||
return migrations;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 './finalize_alerts_migration';
|
||||
export * from './start_alerts_migration';
|
||||
export * from './delete_migrations';
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 { DETECTION_ENGINE_SIGNALS_MIGRATION_URL } from '@kbn/security-solution-plugin/common/constants';
|
||||
|
||||
interface CreateMigrationResponse {
|
||||
index: string;
|
||||
migration_index: string;
|
||||
migration_id: string;
|
||||
}
|
||||
|
||||
export const startAlertsMigration = async ({
|
||||
indices,
|
||||
supertest,
|
||||
log,
|
||||
}: {
|
||||
supertest: SuperTest.SuperTest<SuperTest.Test>;
|
||||
log: ToolingLog;
|
||||
indices: string[];
|
||||
}): Promise<CreateMigrationResponse[]> => {
|
||||
const response = await supertest
|
||||
.post(DETECTION_ENGINE_SIGNALS_MIGRATION_URL)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send({ index: indices });
|
||||
|
||||
const {
|
||||
body: { indices: created },
|
||||
}: { body: { indices: CreateMigrationResponse[] } } = response;
|
||||
if (response.status !== 200) {
|
||||
log.error(
|
||||
`Did not get an expected 200 "ok" when starting a alerts migration (startAlertsMigration). CI issues could happen. Suspect this line if you are seeing CI issues. body: ${JSON.stringify(
|
||||
response.body
|
||||
)}, status: ${JSON.stringify(response.status)}`
|
||||
);
|
||||
}
|
||||
return created;
|
||||
};
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DetectionAlert } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { ALERT_LAST_DETECTED, ALERT_START } from '@kbn/rule-data-utils';
|
||||
|
||||
export const removeRandomValuedProperties = (alert: DetectionAlert | undefined) => {
|
||||
if (!alert) {
|
||||
return undefined;
|
||||
}
|
||||
const {
|
||||
'kibana.version': version,
|
||||
'kibana.alert.rule.execution.uuid': execUuid,
|
||||
'kibana.alert.rule.uuid': uuid,
|
||||
'@timestamp': timestamp,
|
||||
'kibana.alert.rule.created_at': createdAt,
|
||||
'kibana.alert.rule.updated_at': updatedAt,
|
||||
'kibana.alert.uuid': alertUuid,
|
||||
[ALERT_START]: alertStart,
|
||||
[ALERT_LAST_DETECTED]: lastDetected,
|
||||
...restOfAlert
|
||||
} = alert;
|
||||
return restOfAlert;
|
||||
};
|
|
@ -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 {
|
||||
Status,
|
||||
SignalIds as AlertIds,
|
||||
} from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
|
||||
export const setAlertStatus = ({
|
||||
alertIds,
|
||||
query,
|
||||
status,
|
||||
}: {
|
||||
alertIds?: AlertIds;
|
||||
query?: object;
|
||||
status: Status;
|
||||
}) => ({
|
||||
signal_ids: alertIds,
|
||||
query,
|
||||
status,
|
||||
});
|
|
@ -8,11 +8,14 @@ export * from './rules';
|
|||
export * from './exception_list_and_item';
|
||||
export * from './alerts';
|
||||
export * from './actions';
|
||||
export * from './get_rule_so_by_id';
|
||||
export * from './create_rule_saved_object';
|
||||
export * from './get_rule_with_legacy_investigation_fields';
|
||||
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';
|
||||
export * from './refresh_index';
|
||||
export * from './wait_for';
|
||||
export * from './wait_for_index_to_populate';
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 { SavedQueryRuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { getRuleForAlertTesting } from './get_rule_for_alert_testing';
|
||||
|
||||
/**
|
||||
* This is a typical alert testing rule that is easy for most basic testing of output of Saved Query alerts.
|
||||
* It starts out in an enabled true state. The 'from' is set very far back to test the basics of alert
|
||||
* creation for SavedQuery and testing by getting all the alerts at once.
|
||||
* @param ruleId The optional ruleId which is threshold-rule by default.
|
||||
* @param enabled Enables the rule on creation or not. Defaulted to true.
|
||||
*/
|
||||
export const getSavedQueryRuleForAlertTesting = (
|
||||
index: string[],
|
||||
ruleId = 'saved-query-rule',
|
||||
enabled = true
|
||||
): SavedQueryRuleCreateProps => ({
|
||||
...getRuleForAlertTesting(index, ruleId, enabled),
|
||||
type: 'saved_query',
|
||||
saved_id: 'abcd',
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 { ThreatMatchRuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine';
|
||||
import { getRuleForAlertTesting } from './get_rule_for_alert_testing';
|
||||
|
||||
/**
|
||||
* This is a typical alert testing rule that is easy for most basic testing of output of Threat Match alerts.
|
||||
* It starts out in an enabled true state. The 'from' is set very far back to test the basics of alert
|
||||
* creation for Threat Match and testing by getting all the alerts at once.
|
||||
* @param ruleId The optional ruleId which is threshold-rule by default.
|
||||
* @param enabled Enables the rule on creation or not. Defaulted to true.
|
||||
*/
|
||||
export const getThreatMatchRuleForAlertTesting = (
|
||||
index: string[],
|
||||
ruleId = 'threat-match-rule',
|
||||
enabled = true
|
||||
): ThreatMatchRuleCreateProps => ({
|
||||
...getRuleForAlertTesting(index, ruleId, enabled),
|
||||
type: 'threat_match',
|
||||
language: 'kuery',
|
||||
query: '*:*',
|
||||
threat_query: '*:*',
|
||||
threat_mapping: [
|
||||
// We match host.name against host.name
|
||||
{
|
||||
entries: [
|
||||
{
|
||||
field: 'host.name',
|
||||
value: 'host.name',
|
||||
type: 'mapping',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
threat_index: index, // match against same index for simplicity
|
||||
});
|
|
@ -32,5 +32,10 @@ export * from './get_rule_with_web_hook_action';
|
|||
export * from './get_simple_rule_output_with_web_hook_action';
|
||||
export * from './rule_to_update_schema';
|
||||
export * from './update_rule';
|
||||
export * from './get_threat_match_rule_for_alert_testing';
|
||||
export * from './get_saved_query_rule_for_alert_testing';
|
||||
export * from './get_rule_so_by_id';
|
||||
export * from './create_rule_saved_object';
|
||||
export * from './get_rule_with_legacy_investigation_fields';
|
||||
|
||||
export * from './prebuilt_rules';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import type { ToolingLog } from '@kbn/tooling-log';
|
||||
import type { Client } from '@elastic/elasticsearch';
|
||||
import { waitFor } from './wait_for';
|
||||
import { waitFor } from '../../../../detection_engine_api_integration/utils/wait_for';
|
||||
|
||||
/**
|
||||
* Waits for the given index to contain documents
|
|
@ -29,6 +29,7 @@
|
|||
"@kbn/securitysolution-list-constants",
|
||||
"@kbn/core-saved-objects-server",
|
||||
"@kbn/core",
|
||||
"@kbn/alerting-plugin"
|
||||
"@kbn/alerting-plugin",
|
||||
"@kbn/securitysolution-ecs"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -106,7 +106,6 @@
|
|||
"@kbn/journeys",
|
||||
"@kbn/stdio-dev-helpers",
|
||||
"@kbn/alerting-api-integration-helpers",
|
||||
"@kbn/securitysolution-ecs",
|
||||
"@kbn/cloud-security-posture-plugin",
|
||||
"@kbn/cloud-integration-saml-provider-plugin",
|
||||
"@kbn/security-api-integration-helpers",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue