mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[SecuritySolution] Fix flaky schedule_now API test (#194450)
## Summary * * Refactor all risk engine API tests to use the new tear-down risk engine API before and after the test runs. * Updates the `tearDown` API to ignore 404 errors. * Add error logging to the test API client. Now, it also logs the request body.
This commit is contained in:
parent
ac743be23d
commit
e40011d1c1
10 changed files with 276 additions and 308 deletions
|
@ -203,29 +203,41 @@ export class RiskScoreDataClient {
|
|||
const addError = (e: Error) => errors.push(e);
|
||||
|
||||
await esClient.transform
|
||||
.deleteTransform({
|
||||
transform_id: getLatestTransformId(namespace),
|
||||
delete_dest_index: true,
|
||||
force: true,
|
||||
})
|
||||
.deleteTransform(
|
||||
{
|
||||
transform_id: getLatestTransformId(namespace),
|
||||
delete_dest_index: true,
|
||||
force: true,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
)
|
||||
.catch(addError);
|
||||
|
||||
await esClient.indices
|
||||
.deleteDataStream({
|
||||
name: indexPatterns.alias,
|
||||
})
|
||||
.deleteDataStream(
|
||||
{
|
||||
name: indexPatterns.alias,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
)
|
||||
.catch(addError);
|
||||
|
||||
await esClient.indices
|
||||
.deleteIndexTemplate({
|
||||
name: indexPatterns.template,
|
||||
})
|
||||
.deleteIndexTemplate(
|
||||
{
|
||||
name: indexPatterns.template,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
)
|
||||
.catch(addError);
|
||||
|
||||
await esClient.cluster
|
||||
.deleteComponentTemplate({
|
||||
name: mappingComponentName,
|
||||
})
|
||||
.deleteComponentTemplate(
|
||||
{
|
||||
name: mappingComponentName,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
)
|
||||
.catch(addError);
|
||||
|
||||
return errors;
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
CriticalityValues,
|
||||
} from '@kbn/security-solution-plugin/server/lib/entity_analytics/asset_criticality/constants';
|
||||
import {
|
||||
cleanRiskEngine,
|
||||
cleanAssetCriticality,
|
||||
assetCriticalityRouteHelpersFactory,
|
||||
getAssetCriticalityDoc,
|
||||
|
@ -23,6 +22,7 @@ import {
|
|||
enableAssetCriticalityAdvancedSetting,
|
||||
disableAssetCriticalityAdvancedSetting,
|
||||
createAssetCriticalityRecords,
|
||||
riskEngineRouteHelpersFactory,
|
||||
} from '../../utils';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
|
@ -34,14 +34,23 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const assetCriticalityRoutes = assetCriticalityRouteHelpersFactory(supertest);
|
||||
|
||||
describe('@ess @serverless @skipInServerlessMKI asset_criticality Asset Criticality APIs', () => {
|
||||
beforeEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
const riskEngineRoutes = riskEngineRouteHelpersFactory(supertest);
|
||||
|
||||
before(async () => {
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await cleanAssetCriticality({ log, es });
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await disableAssetCriticalityAdvancedSetting(kibanaServer, log);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await enableAssetCriticalityAdvancedSetting(kibanaServer, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await cleanAssetCriticality({ log, es });
|
||||
});
|
||||
|
||||
|
@ -248,10 +257,6 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
const createRecords = () => createAssetCriticalityRecords(records, es);
|
||||
|
||||
before(async () => {
|
||||
await enableAssetCriticalityAdvancedSetting(kibanaServer, log);
|
||||
});
|
||||
|
||||
it('@skipInServerless should return the first 10 asset criticality records if no args provided', async () => {
|
||||
await createRecords();
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
installLegacyRiskScore,
|
||||
getLegacyRiskScoreDashboards,
|
||||
clearLegacyDashboards,
|
||||
cleanRiskEngine,
|
||||
} from '../../utils';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
||||
|
@ -29,12 +28,12 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
|
||||
// Failing: See https://github.com/elastic/kibana/issues/191637
|
||||
describe.skip('@ess @serverless @serverlessQA init_and_status_apis', () => {
|
||||
beforeEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
before(async () => {
|
||||
await riskEngineRoutes.cleanUp();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await clearLegacyTransforms({ es, log });
|
||||
await clearLegacyDashboards({ supertest, log });
|
||||
});
|
||||
|
@ -356,9 +355,9 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(status2.body.risk_engine_status).to.be('ENABLED');
|
||||
expect(status2.body.legacy_risk_engine_status).to.be('NOT_INSTALLED');
|
||||
|
||||
expect(status2.body.risk_engine_task_status.runAt).to.be.a('string');
|
||||
expect(status2.body.risk_engine_task_status.status).to.be('idle');
|
||||
expect(status2.body.risk_engine_task_status.startedAt).to.be(undefined);
|
||||
expect(status2.body.risk_engine_task_status?.runAt).to.be.a('string');
|
||||
expect(status2.body.risk_engine_task_status?.status).to.be('idle');
|
||||
expect(status2.body.risk_engine_task_status?.startedAt).to.be(undefined);
|
||||
|
||||
await riskEngineRoutes.disable();
|
||||
const status3 = await riskEngineRoutes.getStatus();
|
||||
|
@ -374,9 +373,9 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(status4.body.risk_engine_status).to.be('ENABLED');
|
||||
expect(status4.body.legacy_risk_engine_status).to.be('NOT_INSTALLED');
|
||||
|
||||
expect(status4.body.risk_engine_task_status.runAt).to.be.a('string');
|
||||
expect(status4.body.risk_engine_task_status.status).to.be('idle');
|
||||
expect(status4.body.risk_engine_task_status.startedAt).to.be(undefined);
|
||||
expect(status4.body.risk_engine_task_status?.runAt).to.be.a('string');
|
||||
expect(status4.body.risk_engine_task_status?.status).to.be('idle');
|
||||
expect(status4.body.risk_engine_task_status?.startedAt).to.be(undefined);
|
||||
});
|
||||
|
||||
it('should return status of legacy risk engine', async () => {
|
||||
|
@ -395,9 +394,9 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(status2.body.risk_engine_status).to.be('ENABLED');
|
||||
expect(status2.body.legacy_risk_engine_status).to.be('NOT_INSTALLED');
|
||||
|
||||
expect(status2.body.risk_engine_task_status.runAt).to.be.a('string');
|
||||
expect(status2.body.risk_engine_task_status.status).to.be('idle');
|
||||
expect(status2.body.risk_engine_task_status.startedAt).to.be(undefined);
|
||||
expect(status2.body.risk_engine_task_status?.runAt).to.be.a('string');
|
||||
expect(status2.body.risk_engine_task_status?.status).to.be('idle');
|
||||
expect(status2.body.risk_engine_task_status?.startedAt).to.be(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -54,7 +54,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
expect(status2.body.risk_engine_status).to.be('ENABLED');
|
||||
expect(status2.body.legacy_risk_engine_status).to.be('NOT_INSTALLED');
|
||||
|
||||
const response = await riskEngineRoutes.delete();
|
||||
const response = await riskEngineRoutes.cleanUp();
|
||||
expect(response.body).to.eql({
|
||||
cleanup_successful: true,
|
||||
});
|
||||
|
|
|
@ -9,11 +9,11 @@ import { v4 as uuidv4 } from 'uuid';
|
|||
import { deleteAllAlerts, deleteAllRules } from '../../../../../common/utils/security_solution';
|
||||
import {
|
||||
buildDocument,
|
||||
cleanRiskEngine,
|
||||
clearLegacyDashboards,
|
||||
clearLegacyTransforms,
|
||||
createAndSyncRuleAndAlertsFactory,
|
||||
riskEngineRouteHelpersFactory,
|
||||
waitForRiskEngineRun,
|
||||
waitForRiskScoresToBePresent,
|
||||
} from '../../utils';
|
||||
import { FtrProviderContext } from '../../../../ftr_provider_context';
|
||||
|
@ -23,11 +23,18 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
const es = getService('es');
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const riskEngineRoutes = riskEngineRouteHelpersFactory(supertest);
|
||||
const log = getService('log');
|
||||
|
||||
describe('@ess @serverless @serverlessQA init_and_status_apis', () => {
|
||||
const cleanAllResources = async () => {
|
||||
await clearLegacyTransforms({ es, log });
|
||||
await clearLegacyDashboards({ supertest, log });
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
await riskEngineRoutes.cleanUp();
|
||||
};
|
||||
|
||||
describe('@ess @serverless @serverlessQA Risk Engine schedule_now', () => {
|
||||
const createAndSyncRuleAndAlerts = createAndSyncRuleAndAlertsFactory({ supertest, log });
|
||||
const { indexListOfDocuments } = dataGeneratorFactory({
|
||||
es,
|
||||
|
@ -36,6 +43,7 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
before(async () => {
|
||||
await cleanAllResources();
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
|
||||
});
|
||||
|
||||
|
@ -44,31 +52,24 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await clearLegacyTransforms({ es, log });
|
||||
await clearLegacyDashboards({ supertest, log });
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
await cleanAllResources();
|
||||
});
|
||||
|
||||
it('should run the risk engine when "scheduleNow" is called', async () => {
|
||||
// create a document
|
||||
const firstDocumentId = uuidv4();
|
||||
await indexListOfDocuments([buildDocument({ host: { name: 'host-1' } }, firstDocumentId)]);
|
||||
await createAndSyncRuleAndAlerts({ query: `id: ${firstDocumentId}` });
|
||||
|
||||
// first risk engine run
|
||||
await riskEngineRoutes.init();
|
||||
await waitForRiskEngineRun({ log, supertest });
|
||||
await waitForRiskScoresToBePresent({ es, log, scoreCount: 1 });
|
||||
|
||||
const secondDocumentId = uuidv4();
|
||||
await indexListOfDocuments([buildDocument({ host: { name: 'host-2' } }, secondDocumentId)]);
|
||||
await createAndSyncRuleAndAlerts({
|
||||
query: `id: ${secondDocumentId}`,
|
||||
});
|
||||
|
||||
// second risk engine run
|
||||
await riskEngineRoutes.scheduleNow();
|
||||
|
||||
// Should index 2 more document on the second run
|
||||
await waitForRiskScoresToBePresent({ es, log, scoreCount: 3 });
|
||||
await waitForRiskEngineRun({ log, supertest });
|
||||
await waitForRiskScoresToBePresent({ es, log, scoreCount: 2 }); // Should calculate risk score again for the same document
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -16,7 +16,6 @@ import { deleteAllAlerts, deleteAllRules } from '../../../../../common/utils/sec
|
|||
import {
|
||||
buildDocument,
|
||||
createAndSyncRuleAndAlertsFactory,
|
||||
deleteAllRiskScores,
|
||||
readRiskScores,
|
||||
normalizeScores,
|
||||
waitForRiskScoresToBePresent,
|
||||
|
@ -24,7 +23,6 @@ import {
|
|||
cleanAssetCriticality,
|
||||
waitForAssetCriticalityToBePresent,
|
||||
riskEngineRouteHelpersFactory,
|
||||
cleanRiskEngine,
|
||||
enableAssetCriticalityAdvancedSetting,
|
||||
sanitizeScores,
|
||||
} from '../../utils';
|
||||
|
@ -91,6 +89,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
|
||||
before(async () => {
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
|
||||
});
|
||||
|
||||
|
@ -103,15 +102,12 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
beforeEach(async () => {
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteAllRiskScores(log, es);
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await riskEngineRoutes.cleanUp();
|
||||
});
|
||||
|
||||
it('calculates and persists risk score for entity', async () => {
|
||||
|
|
|
@ -19,7 +19,6 @@ import {
|
|||
updateRiskEngineConfigSO,
|
||||
getRiskEngineTask,
|
||||
waitForRiskEngineTaskToBeGone,
|
||||
cleanRiskEngine,
|
||||
assetCriticalityRouteHelpersFactory,
|
||||
cleanAssetCriticality,
|
||||
waitForAssetCriticalityToBePresent,
|
||||
|
@ -45,6 +44,7 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
|
||||
before(async () => {
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
|
||||
});
|
||||
|
||||
|
@ -55,13 +55,12 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
|
|
@ -16,8 +16,6 @@ import {
|
|||
waitForRiskScoresToBePresent,
|
||||
normalizeScores,
|
||||
riskEngineRouteHelpersFactory,
|
||||
cleanRiskEngine,
|
||||
deleteRiskScoreIndices,
|
||||
} from '../../../utils';
|
||||
|
||||
import type { FtrProviderContextWithSpaces } from '../../../../../ftr_provider_context_with_spaces';
|
||||
|
@ -27,17 +25,26 @@ export default ({ getService }: FtrProviderContextWithSpaces): void => {
|
|||
const esArchiver = getService('esArchiver');
|
||||
const es = getService('es');
|
||||
const log = getService('log');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
describe('@ess Risk Scoring Task in non-default space', () => {
|
||||
context('with auditbeat data', () => {
|
||||
describe('with alerts in a non-default space', () => {
|
||||
const { indexListOfDocuments } = dataGeneratorFactory({
|
||||
es,
|
||||
index: 'ecs_compliant',
|
||||
log,
|
||||
});
|
||||
const namespace = uuidv4();
|
||||
const documentId = uuidv4();
|
||||
const index = [`risk-score.risk-score-${namespace}`];
|
||||
const createAndSyncRuleAndAlertsForOtherSpace = createAndSyncRuleAndAlertsFactory({
|
||||
supertest,
|
||||
log,
|
||||
namespace,
|
||||
});
|
||||
const riskEngineRoutesForNamespace = riskEngineRouteHelpersFactory(supertest, namespace);
|
||||
|
||||
before(async () => {
|
||||
await riskEngineRoutesForNamespace.cleanUp();
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
|
||||
});
|
||||
|
||||
|
@ -48,82 +55,56 @@ export default ({ getService }: FtrProviderContextWithSpaces): void => {
|
|||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
|
||||
const spaces = getService('spaces');
|
||||
await spaces.create({
|
||||
id: namespace,
|
||||
name: namespace,
|
||||
disabledFeatures: [],
|
||||
});
|
||||
|
||||
const baseEvent = buildDocument({ host: { name: 'host-1' } }, documentId);
|
||||
await indexListOfDocuments(
|
||||
Array(10)
|
||||
.fill(baseEvent)
|
||||
.map((_baseEvent, _index) => ({
|
||||
..._baseEvent,
|
||||
'host.name': `host-${_index}`,
|
||||
}))
|
||||
);
|
||||
|
||||
await createAndSyncRuleAndAlertsForOtherSpace({
|
||||
query: `id: ${documentId}`,
|
||||
alerts: 10,
|
||||
riskScore: 40,
|
||||
});
|
||||
|
||||
await riskEngineRoutesForNamespace.init();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await riskEngineRoutesForNamespace.cleanUp();
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
await getService('spaces').delete(namespace);
|
||||
});
|
||||
describe('with alerts in a non-default space', () => {
|
||||
let namespace: string;
|
||||
let index: string[];
|
||||
let documentId: string;
|
||||
let createAndSyncRuleAndAlertsForOtherSpace: ReturnType<
|
||||
typeof createAndSyncRuleAndAlertsFactory
|
||||
>;
|
||||
|
||||
beforeEach(async () => {
|
||||
documentId = uuidv4();
|
||||
namespace = uuidv4();
|
||||
index = [`risk-score.risk-score-${namespace}`];
|
||||
|
||||
createAndSyncRuleAndAlertsForOtherSpace = createAndSyncRuleAndAlertsFactory({
|
||||
supertest,
|
||||
log,
|
||||
namespace,
|
||||
});
|
||||
const riskEngineRoutesForNamespace = riskEngineRouteHelpersFactory(supertest, namespace);
|
||||
|
||||
const spaces = getService('spaces');
|
||||
await spaces.create({
|
||||
id: namespace,
|
||||
name: namespace,
|
||||
disabledFeatures: [],
|
||||
});
|
||||
|
||||
const baseEvent = buildDocument({ host: { name: 'host-1' } }, documentId);
|
||||
await indexListOfDocuments(
|
||||
Array(10)
|
||||
.fill(baseEvent)
|
||||
.map((_baseEvent, _index) => ({
|
||||
..._baseEvent,
|
||||
'host.name': `host-${_index}`,
|
||||
}))
|
||||
);
|
||||
|
||||
await createAndSyncRuleAndAlertsForOtherSpace({
|
||||
query: `id: ${documentId}`,
|
||||
alerts: 10,
|
||||
riskScore: 40,
|
||||
});
|
||||
|
||||
await riskEngineRoutesForNamespace.init();
|
||||
it('calculates and persists risk scores for alert documents', async () => {
|
||||
await waitForRiskScoresToBePresent({
|
||||
es,
|
||||
log,
|
||||
scoreCount: 10,
|
||||
index,
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await getService('spaces').delete(namespace);
|
||||
await deleteRiskScoreIndices({ log, es, namespace });
|
||||
});
|
||||
|
||||
it('calculates and persists risk scores for alert documents', async () => {
|
||||
await waitForRiskScoresToBePresent({
|
||||
es,
|
||||
log,
|
||||
scoreCount: 10,
|
||||
index,
|
||||
});
|
||||
|
||||
const scores = await readRiskScores(es, index);
|
||||
expect(normalizeScores(scores).map(({ id_value: idValue }) => idValue)).to.eql(
|
||||
Array(10)
|
||||
.fill(0)
|
||||
.map((_, _index) => `host-${_index}`)
|
||||
);
|
||||
});
|
||||
const scores = await readRiskScores(es, index);
|
||||
expect(normalizeScores(scores).map(({ id_value: idValue }) => idValue)).to.eql(
|
||||
Array(10)
|
||||
.fill(0)
|
||||
.map((_, _index) => `host-${_index}`)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,7 +14,6 @@ import {
|
|||
createAndSyncRuleAndAlertsFactory,
|
||||
waitForRiskScoresToBePresent,
|
||||
riskEngineRouteHelpersFactory,
|
||||
cleanRiskEngine,
|
||||
getRiskEngineStats,
|
||||
areRiskScoreIndicesEmpty,
|
||||
} from '../../utils';
|
||||
|
@ -35,25 +34,27 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
index: 'ecs_compliant',
|
||||
log,
|
||||
});
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
|
||||
before(async () => {
|
||||
await riskEngineRoutes.cleanUp();
|
||||
await esArchiver.load('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('x-pack/test/functional/es_archives/security_solution/ecs_compliant');
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await cleanRiskEngine({ kibanaServer, es, log });
|
||||
await deleteAllAlerts(supertest, log, es);
|
||||
await deleteAllRules(supertest, log);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await riskEngineRoutes.cleanUp();
|
||||
});
|
||||
|
||||
it('should return empty metrics when the risk engine is disabled', async () => {
|
||||
await retry.try(async () => {
|
||||
const stats = await getRiskEngineStats(supertest, log);
|
||||
|
@ -61,7 +62,6 @@ export default ({ getService }: FtrProviderContext) => {
|
|||
});
|
||||
});
|
||||
|
||||
// https://github.com/elastic/kibana/issues/183246
|
||||
it('@skipInServerlessMKI should return metrics with expected values when risk engine is enabled', async () => {
|
||||
expect(await areRiskScoreIndicesEmpty({ log, es })).to.be(true);
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@ import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types';
|
|||
import { removeLegacyTransforms } from '@kbn/security-solution-plugin/server/lib/entity_analytics/utils/transforms';
|
||||
import { EntityRiskScoreRecord } from '@kbn/security-solution-plugin/common/api/entity_analytics/common';
|
||||
import { SupertestWithoutAuthProviderType } from '@kbn/ftr-common-functional-services';
|
||||
|
||||
import { RiskEngineStatusResponse } from '@kbn/security-solution-plugin/common/api/entity_analytics';
|
||||
import {
|
||||
createRule,
|
||||
waitForAlertsToBePresent,
|
||||
|
@ -96,7 +98,7 @@ export const createAndSyncRuleAndAlertsFactory =
|
|||
query: string;
|
||||
riskScoreOverride?: string;
|
||||
}): Promise<void> => {
|
||||
const rule = getRuleForAlertTesting(['ecs_compliant']);
|
||||
const rule = getRuleForAlertTesting(['ecs_compliant'], uuidv4());
|
||||
const { id } = await createRule(
|
||||
supertest,
|
||||
log,
|
||||
|
@ -130,27 +132,6 @@ export const getLatestRiskScoreIndexMapping: (
|
|||
)[riskScoreLatestIndex]?.mappings;
|
||||
};
|
||||
|
||||
export const deleteRiskScoreIndices = async ({
|
||||
log,
|
||||
es,
|
||||
namespace = 'default',
|
||||
}: {
|
||||
log: ToolingLog;
|
||||
es: Client;
|
||||
namespace?: string;
|
||||
}) => {
|
||||
try {
|
||||
await Promise.allSettled([
|
||||
es.indices.deleteDataStream({ name: [`risk-score.risk-score-${namespace}`] }),
|
||||
es.indices.delete({
|
||||
index: [`risk-score.risk-score-latest-${namespace}`],
|
||||
}),
|
||||
]);
|
||||
} catch (e) {
|
||||
log.warning(`Error deleting risk score indices: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const areRiskScoreIndicesEmpty = async ({
|
||||
es,
|
||||
namespace = 'default',
|
||||
|
@ -276,6 +257,31 @@ export const waitForRiskScoresToBePresent = async ({
|
|||
);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* It waits for the risk engine 'runAt' time to be bigger than the initial time.
|
||||
*/
|
||||
export const waitForRiskEngineRun = async ({
|
||||
supertest,
|
||||
log,
|
||||
}: {
|
||||
supertest: SuperTest.Agent;
|
||||
log: ToolingLog;
|
||||
}): Promise<void> => {
|
||||
const initialTime = new Date();
|
||||
const riskEngineRoutes = riskEngineRouteHelpersFactory(supertest);
|
||||
|
||||
await waitFor(
|
||||
async () => {
|
||||
const { body } = await riskEngineRoutes.getStatus();
|
||||
const runAtTime = body?.risk_engine_task_status?.runAt;
|
||||
return !!runAtTime && new Date(runAtTime) > initialTime;
|
||||
},
|
||||
'waitForRiskEngineToRun',
|
||||
log
|
||||
);
|
||||
};
|
||||
|
||||
export const getRiskEngineTasks = async ({
|
||||
es,
|
||||
index = ['.kibana_task_manager*'],
|
||||
|
@ -306,35 +312,6 @@ export const getRiskEngineTask = async ({
|
|||
return result.hits.hits[0]?._source;
|
||||
};
|
||||
|
||||
export const deleteRiskEngineTask = async ({
|
||||
es,
|
||||
log,
|
||||
index = ['.kibana_task_manager*'],
|
||||
}: {
|
||||
es: Client;
|
||||
log: ToolingLog;
|
||||
index?: string[];
|
||||
}) => {
|
||||
await countDownTest(
|
||||
async () => {
|
||||
await es.deleteByQuery({
|
||||
index,
|
||||
query: {
|
||||
match: {
|
||||
'task.taskType': 'risk_engine:risk_scoring',
|
||||
},
|
||||
},
|
||||
conflicts: 'proceed',
|
||||
});
|
||||
return {
|
||||
passed: true,
|
||||
};
|
||||
},
|
||||
'deleteRiskEngineTask',
|
||||
log
|
||||
);
|
||||
};
|
||||
|
||||
export const waitForRiskEngineTaskToBeGone = async ({
|
||||
es,
|
||||
log,
|
||||
|
@ -362,38 +339,6 @@ export const getRiskEngineConfigSO = async ({ kibanaServer }: { kibanaServer: Kb
|
|||
return soResponse?.saved_objects?.[0];
|
||||
};
|
||||
|
||||
export const cleanRiskEngineConfig = async ({
|
||||
kibanaServer,
|
||||
}: {
|
||||
kibanaServer: KbnClient;
|
||||
}): Promise<void> => {
|
||||
const so = await getRiskEngineConfigSO({ kibanaServer });
|
||||
if (so) {
|
||||
await kibanaServer.savedObjects.delete({
|
||||
type: riskEngineConfigurationTypeName,
|
||||
id: so.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* General helper for cleaning up risk engine artifacts. This should be used before and after any risk engine tests so as not to pollute the test environment.
|
||||
*/
|
||||
export const cleanRiskEngine = async ({
|
||||
es,
|
||||
kibanaServer,
|
||||
log,
|
||||
}: {
|
||||
es: Client;
|
||||
kibanaServer: KbnClient;
|
||||
log: ToolingLog;
|
||||
}): Promise<void> => {
|
||||
await deleteRiskEngineTask({ es, log });
|
||||
await cleanRiskEngineConfig({ kibanaServer });
|
||||
await clearTransforms({ es, log });
|
||||
await deleteRiskScoreIndices({ log, es });
|
||||
};
|
||||
|
||||
export const updateRiskEngineConfigSO = async ({
|
||||
attributes,
|
||||
kibanaServer,
|
||||
|
@ -423,23 +368,6 @@ export const legacyTransformIds = [
|
|||
'ml_userriskscore_latest_transform_default',
|
||||
];
|
||||
|
||||
export const clearTransforms = async ({
|
||||
es,
|
||||
log,
|
||||
}: {
|
||||
es: Client;
|
||||
log: ToolingLog;
|
||||
}): Promise<void> => {
|
||||
try {
|
||||
await es.transform.deleteTransform({
|
||||
transform_id: 'risk_score_latest_transform_default',
|
||||
force: true,
|
||||
});
|
||||
} catch (e) {
|
||||
log.warning(`Error deleting risk_score_latest_transform_default: ${e.message}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const clearLegacyTransforms = async ({
|
||||
es,
|
||||
log,
|
||||
|
@ -530,68 +458,96 @@ export const getLegacyRiskScoreDashboards = async ({
|
|||
return savedObejectLens?.saved_objects.filter((s) => s?.attributes?.title?.includes('Risk'));
|
||||
};
|
||||
|
||||
export const riskEngineRouteHelpersFactory = (supertest: SuperTest.Agent, namespace?: string) => ({
|
||||
init: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_INIT_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
const assertStatusCode = (statusCode: number, response: SuperTest.Response) => {
|
||||
if (response.status !== statusCode) {
|
||||
throw new Error(
|
||||
`Expected status code ${statusCode}, but got ${response.statusCode} \n` + response.text
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
getStatus: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.get(routeWithNamespace(RISK_ENGINE_STATUS_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
export const riskEngineRouteHelpersFactory = (supertest: SuperTest.Agent, namespace?: string) => {
|
||||
return {
|
||||
init: async (expectStatusCode: number = 200) => {
|
||||
const response = await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_INIT_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send();
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
return response;
|
||||
},
|
||||
|
||||
enable: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_ENABLE_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
getStatus: async (
|
||||
expectStatusCode: number = 200
|
||||
): Promise<{ body: RiskEngineStatusResponse }> => {
|
||||
const response = await supertest
|
||||
.get(routeWithNamespace(RISK_ENGINE_STATUS_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send();
|
||||
|
||||
disable: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_DISABLE_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
|
||||
privileges: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.get(RISK_ENGINE_PRIVILEGES_URL)
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
return response;
|
||||
},
|
||||
|
||||
delete: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.delete(routeWithNamespace(RISK_ENGINE_CLEANUP_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '2023-10-31')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
enable: async (expectStatusCode: number = 200) => {
|
||||
const response = await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_ENABLE_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send();
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
return response;
|
||||
},
|
||||
|
||||
scheduleNow: async (expectStatusCode: number = 200) =>
|
||||
await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_SCHEDULE_NOW_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
});
|
||||
disable: async (expectStatusCode: number = 200) => {
|
||||
const response = await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_DISABLE_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send();
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
return response;
|
||||
},
|
||||
|
||||
privileges: async (expectStatusCode: number = 200) => {
|
||||
const response = await supertest
|
||||
.get(RISK_ENGINE_PRIVILEGES_URL)
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send();
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
return response;
|
||||
},
|
||||
|
||||
cleanUp: async (expectStatusCode: number = 200) => {
|
||||
const response = await supertest
|
||||
.delete(routeWithNamespace(RISK_ENGINE_CLEANUP_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '2023-10-31')
|
||||
.send();
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
return response;
|
||||
},
|
||||
|
||||
scheduleNow: async (expectStatusCode: number = 200) => {
|
||||
const response = await supertest
|
||||
.post(routeWithNamespace(RISK_ENGINE_SCHEDULE_NOW_URL, namespace))
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '2023-10-31')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send();
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
return response;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
interface Credentials {
|
||||
username: string;
|
||||
|
@ -602,41 +558,60 @@ export const riskEngineRouteHelpersFactoryNoAuth = (
|
|||
supertestWithoutAuth: SupertestWithoutAuthProviderType,
|
||||
namespace?: string
|
||||
) => ({
|
||||
privilegesForUser: async ({ username, password }: Credentials) =>
|
||||
await supertestWithoutAuth
|
||||
privilegesForUser: async (
|
||||
{ username, password }: Credentials,
|
||||
expectStatusCode: number = 200
|
||||
) => {
|
||||
const response = await supertestWithoutAuth
|
||||
.get(RISK_ENGINE_PRIVILEGES_URL)
|
||||
.auth(username, password)
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(200),
|
||||
init: async ({ username, password }: Credentials, expectStatusCode: number = 200) =>
|
||||
await supertestWithoutAuth
|
||||
.send();
|
||||
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
|
||||
return response;
|
||||
},
|
||||
init: async ({ username, password }: Credentials, expectStatusCode: number = 200) => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(routeWithNamespace(RISK_ENGINE_INIT_URL, namespace))
|
||||
.auth(username, password)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
enable: async ({ username, password }: Credentials, expectStatusCode: number = 200) =>
|
||||
await supertestWithoutAuth
|
||||
.send();
|
||||
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
|
||||
return response;
|
||||
},
|
||||
enable: async ({ username, password }: Credentials, expectStatusCode: number = 200) => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(routeWithNamespace(RISK_ENGINE_ENABLE_URL, namespace))
|
||||
.auth(username, password)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
disable: async ({ username, password }: Credentials, expectStatusCode: number = 200) =>
|
||||
await supertestWithoutAuth
|
||||
.send();
|
||||
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
|
||||
return response;
|
||||
},
|
||||
disable: async ({ username, password }: Credentials, expectStatusCode: number = 200) => {
|
||||
const response = await supertestWithoutAuth
|
||||
.post(routeWithNamespace(RISK_ENGINE_DISABLE_URL, namespace))
|
||||
.auth(username, password)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.set('elastic-api-version', '1')
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.send()
|
||||
.expect(expectStatusCode),
|
||||
.send();
|
||||
|
||||
assertStatusCode(expectStatusCode, response);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
export const installLegacyRiskScore = async ({ supertest }: { supertest: SuperTest.Agent }) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue