Skip to content

Commit

Permalink
Filter out non-security jobs when collecting Detections telemetry (#7…
Browse files Browse the repository at this point in the history
…4456) (#74467)

Our jobs summary call returns all installed jobs regardless of group;
passing groups as jobIds does not perform group filtering.

This adds a helper predicate function on which to filter these results,
and updates tests accordingly.
  • Loading branch information
rylnd authored Aug 6, 2020
1 parent 3643a17 commit c6c1eb4
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 5 deletions.
7 changes: 7 additions & 0 deletions x-pack/plugins/security_solution/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ export const UNAUTHENTICATED_USER = 'Unauthenticated';
*/
export const MINIMUM_ML_LICENSE = 'platinum';

/*
Machine Learning constants
*/
export const ML_GROUP_ID = 'security';
export const LEGACY_ML_GROUP_ID = 'siem';
export const ML_GROUP_IDS = [ML_GROUP_ID, LEGACY_ML_GROUP_ID];

/*
Rule notifications options
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { MlSummaryJob } from '../../../ml/common/types/anomaly_detection_jobs';
import { isSecurityJob } from './is_security_job';

describe('isSecurityJob', () => {
it('counts a job with a group of "siem"', () => {
const job = { groups: ['siem', 'other'] } as MlSummaryJob;
expect(isSecurityJob(job)).toEqual(true);
});

it('counts a job with a group of "security"', () => {
const job = { groups: ['security', 'other'] } as MlSummaryJob;
expect(isSecurityJob(job)).toEqual(true);
});

it('counts a job in both "security" and "siem"', () => {
const job = { groups: ['siem', 'security'] } as MlSummaryJob;
expect(isSecurityJob(job)).toEqual(true);
});

it('does not count a job in a related group', () => {
const job = { groups: ['auditbeat', 'process'] } as MlSummaryJob;
expect(isSecurityJob(job)).toEqual(false);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { MlSummaryJob } from '../../../ml/common/types/anomaly_detection_jobs';
import { ML_GROUP_IDS } from '../constants';

export const isSecurityJob = (job: MlSummaryJob): boolean =>
job.groups.some((group) => ML_GROUP_IDS.includes(group));
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const getMockJobSummaryResponse = () => [
{
id: 'other_job',
description: 'a job that is custom',
groups: ['auditbeat', 'process'],
groups: ['auditbeat', 'process', 'security'],
processed_record_count: 0,
memory_status: 'ok',
jobState: 'closed',
Expand All @@ -54,6 +54,19 @@ export const getMockJobSummaryResponse = () => [
{
id: 'another_job',
description: 'another job that is custom',
groups: ['auditbeat', 'process', 'security'],
processed_record_count: 0,
memory_status: 'ok',
jobState: 'opened',
hasDatafeed: true,
datafeedId: 'datafeed-another',
datafeedIndices: ['auditbeat-*'],
datafeedState: 'started',
isSingleMetricViewerJob: true,
},
{
id: 'irrelevant_job',
description: 'a non-security job',
groups: ['auditbeat', 'process'],
processed_record_count: 0,
memory_status: 'ok',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { MlPluginSetup } from '../../../../ml/server';
import { SIGNALS_ID, INTERNAL_IMMUTABLE_KEY } from '../../../common/constants';
import { DetectionRulesUsage, MlJobsUsage } from './index';
import { isJobStarted } from '../../../common/machine_learning/helpers';
import { isSecurityJob } from '../../../common/machine_learning/is_security_job';

interface DetectionsMetric {
isElastic: boolean;
Expand Down Expand Up @@ -182,11 +183,9 @@ export const getMlJobsUsage = async (ml: MlPluginSetup | undefined): Promise<MlJ
.modulesProvider(internalMlClient, fakeRequest, fakeSOClient)
.listModules();
const moduleJobs = modules.flatMap((module) => module.jobs);
const jobs = await ml
.jobServiceProvider(internalMlClient, fakeRequest)
.jobsSummary(['siem', 'security']);
const jobs = await ml.jobServiceProvider(internalMlClient, fakeRequest).jobsSummary();

jobsUsage = jobs.reduce((usage, job) => {
jobsUsage = jobs.filter(isSecurityJob).reduce((usage, job) => {
const isElastic = moduleJobs.some((moduleJob) => moduleJob.id === job.id);
const isEnabled = isJobStarted(job.jobState, job.datafeedState);

Expand Down

0 comments on commit c6c1eb4

Please sign in to comment.