[Security Solution][Detections] Update telemetry to use ML contract (#71665)

* Update security solution telemetry to use ML providers

This interface recently changed and we're now able to use the ML
contract to retrieve these values. A few unnecessary arguments are
stubbed as we're in a non-user, non-request context.

* Simplify our capabilities stub assignment

This is more legible but still gets the point across; the intermediate
variable was explicit but ultimately unnnecessary.

* Update tests following telemetry refactor

We're not calling different methods, so our mocks need to change
slightly.
This commit is contained in:
Ryland Herrick 2020-07-14 14:20:24 -05:00 committed by GitHub
parent 513d0e09e1
commit 9e2ebe2040
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 33 deletions

View file

@ -13,6 +13,7 @@ import { TypeOf } from '@kbn/config-schema';
import { DataRecognizer } from '../../models/data_recognizer';
import { SharedServicesChecks } from '../shared_services';
import { moduleIdParamSchema, setupModuleBodySchema } from '../../routes/schemas/modules';
import { HasMlCapabilities } from '../../lib/capabilities';
export type ModuleSetupPayload = TypeOf<typeof moduleIdParamSchema> &
TypeOf<typeof setupModuleBodySchema>;
@ -40,8 +41,14 @@ export function getModulesProvider({
request: KibanaRequest,
savedObjectsClient: SavedObjectsClientContract
) {
const hasMlCapabilities = getHasMlCapabilities(request);
let hasMlCapabilities: HasMlCapabilities;
if (request.params === 'DummyKibanaRequest') {
hasMlCapabilities = () => Promise.resolve();
} else {
hasMlCapabilities = getHasMlCapabilities(request);
}
const dr = dataRecognizerFactory(mlClusterClient, savedObjectsClient, request);
return {
async recognize(...args) {
isFullLicense();

View file

@ -16,6 +16,8 @@ const createMockMlSystemProvider = () =>
export const mlServicesMock = {
create: () =>
(({
modulesProvider: jest.fn(),
jobServiceProvider: jest.fn(),
mlSystemProvider: createMockMlSystemProvider(),
mlClient: createMockClient(),
} as unknown) as jest.Mocked<MlPluginSetup>),

View file

@ -6,8 +6,6 @@
import { LegacyAPICaller } from '../../../../../../src/core/server';
import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks';
import { jobServiceProvider } from '../../../../ml/server/models/job_service';
import { DataRecognizer } from '../../../../ml/server/models/data_recognizer';
import { mlServicesMock } from '../../lib/machine_learning/mocks';
import {
getMockJobSummaryResponse,
@ -16,9 +14,6 @@ import {
} from './detections.mocks';
import { fetchDetectionsUsage } from './index';
jest.mock('../../../../ml/server/models/job_service');
jest.mock('../../../../ml/server/models/data_recognizer');
describe('Detections Usage', () => {
describe('fetchDetectionsUsage()', () => {
let callClusterMock: jest.Mocked<LegacyAPICaller>;
@ -79,12 +74,12 @@ describe('Detections Usage', () => {
it('tallies jobs data given jobs results', async () => {
const mockJobSummary = jest.fn().mockResolvedValue(getMockJobSummaryResponse());
const mockListModules = jest.fn().mockResolvedValue(getMockListModulesResponse());
(jobServiceProvider as jest.Mock).mockImplementation(() => ({
jobsSummary: mockJobSummary,
}));
(DataRecognizer as jest.Mock).mockImplementation(() => ({
mlMock.modulesProvider.mockReturnValue(({
listModules: mockListModules,
}));
} as unknown) as ReturnType<typeof mlMock.modulesProvider>);
mlMock.jobServiceProvider.mockReturnValue({
jobsSummary: mockJobSummary,
});
const result = await fetchDetectionsUsage('', callClusterMock, mlMock);

View file

@ -5,13 +5,12 @@
*/
import { SearchParams } from 'elasticsearch';
import { ILegacyScopedClusterClient, KibanaRequest } from 'kibana/server';
import { LegacyAPICaller, SavedObjectsClient } from '../../../../../../src/core/server';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { jobServiceProvider } from '../../../../ml/server/models/job_service';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { DataRecognizer } from '../../../../ml/server/models/data_recognizer';
import {
LegacyAPICaller,
SavedObjectsClient,
KibanaRequest,
} from '../../../../../../src/core/server';
import { MlPluginSetup } from '../../../../ml/server';
import { SIGNALS_ID, INTERNAL_IMMUTABLE_KEY } from '../../../common/constants';
import { DetectionRulesUsage, MlJobsUsage } from './index';
@ -164,25 +163,20 @@ export const getRulesUsage = async (
export const getMlJobsUsage = async (ml: MlPluginSetup | undefined): Promise<MlJobsUsage> => {
let jobsUsage: MlJobsUsage = initialMlJobsUsage;
// Fake objects to be passed to ML functions.
// TODO - These ML functions should come from ML's setup contract
// and not be imported directly.
const fakeScopedClusterClient = {
callAsCurrentUser: ml?.mlClient.callAsInternalUser,
callAsInternalUser: ml?.mlClient.callAsInternalUser,
} as ILegacyScopedClusterClient;
const fakeSavedObjectsClient = {} as SavedObjectsClient;
const fakeRequest = {} as KibanaRequest;
if (ml) {
try {
const modules = await new DataRecognizer(
fakeScopedClusterClient,
fakeSavedObjectsClient,
fakeRequest
).listModules();
const fakeRequest = { headers: {}, params: 'DummyKibanaRequest' } as KibanaRequest;
const fakeSOClient = {} as SavedObjectsClient;
const internalMlClient = {
callAsCurrentUser: ml?.mlClient.callAsInternalUser,
callAsInternalUser: ml?.mlClient.callAsInternalUser,
};
const modules = await ml
.modulesProvider(internalMlClient, fakeRequest, fakeSOClient)
.listModules();
const moduleJobs = modules.flatMap((module) => module.jobs);
const jobs = await jobServiceProvider(fakeScopedClusterClient).jobsSummary(['siem']);
const jobs = await ml.jobServiceProvider(internalMlClient, fakeRequest).jobsSummary(['siem']);
jobsUsage = jobs.reduce((usage, job) => {
const isElastic = moduleJobs.some((moduleJob) => moduleJob.id === job.id);