From d5c092811b41b7a93eca949cdaad6dfdf3752ee8 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 12 Mar 2020 10:04:40 +0000 Subject: [PATCH] [ML] Adding shared services to ml setup contract (#59730) * [ML] Adding shared services to ml setup contract * adding data recognizer * typescripting js client * adding results service * code clean up * adding generic ml index search * making cloud optional --- .../plugins/ml/common/types/ml_server_info.ts | 32 +++++++ .../legacy/plugins/ml/common/types/modules.ts | 2 +- x-pack/legacy/plugins/ml/index.ts | 2 +- .../use_create_analytics_form.ts | 2 +- .../file_based/file_datavisualizer.tsx | 2 +- .../jobs/new_job/utils/new_job_utils.ts | 2 +- .../public/application/routing/breadcrumbs.ts | 2 +- .../ml/public/application/routing/router.tsx | 2 +- .../application/routing/use_resolver.ts | 2 +- .../services/ml_api_service/index.d.ts | 17 +--- .../application/services/ml_server_info.ts | 16 +--- .../application/util/dependency_cache.ts | 2 +- x-pack/legacy/plugins/ml/public/index.ts | 2 +- x-pack/legacy/plugins/ml/public/legacy.ts | 2 +- x-pack/legacy/plugins/ml/public/plugin.ts | 2 +- ...csearch_ml.js => elasticsearch_ml.test.ts} | 20 ++-- ...lasticsearch_ml.js => elasticsearch_ml.ts} | 2 +- .../plugins/ml/server/client/error_wrapper.ts | 2 +- x-pack/plugins/ml/server/client/log.ts | 2 +- x-pack/plugins/ml/server/index.ts | 1 + .../ml/server/lib/check_annotations/index.ts | 2 +- .../lib/check_privileges/check_privileges.ts | 4 +- .../ml/server/lib/check_privileges/index.ts | 2 +- .../server/lib/license/ml_server_license.ts | 2 +- .../ml_telemetry/make_ml_usage_collector.ts | 2 +- .../server/lib/ml_telemetry/ml_telemetry.ts | 7 +- x-pack/plugins/ml/server/lib/spaces_utils.ts | 7 +- .../annotation_service/annotation.test.ts | 48 ++++------ .../models/annotation_service/annotation.ts | 5 +- .../server/models/annotation_service/index.ts | 6 +- .../bucket_span_estimator.d.ts | 2 +- .../calculate_model_memory_limit.d.ts | 2 +- .../models/calendar/calendar_manager.ts | 2 +- .../data_recognizer/data_recognizer.test.ts | 24 ++--- .../models/data_recognizer/data_recognizer.ts | 14 +-- .../ml/server/models/data_recognizer/index.ts | 2 +- .../models/data_visualizer/data_visualizer.ts | 2 +- .../models/fields_service/fields_service.d.ts | 2 +- .../file_data_visualizer.ts | 6 +- .../file_data_visualizer/import_data.ts | 6 +- .../ml/server/models/filter/filter_manager.ts | 2 +- .../job_audit_messages.d.ts | 2 +- .../ml/server/models/job_service/datafeeds.ts | 2 +- .../ml/server/models/job_service/groups.ts | 2 +- .../ml/server/models/job_service/index.ts | 2 +- .../ml/server/models/job_service/jobs.ts | 2 +- .../models/job_service/new_job_caps/rollup.ts | 2 +- .../models/job_validation/job_validation.d.ts | 2 +- .../job_validation/validate_cardinality.d.ts | 2 +- .../job_validation/validate_time_range.ts | 2 +- .../models/results_service/results_service.ts | 6 +- x-pack/plugins/ml/server/plugin.ts | 21 +++- .../plugins/ml/server/routes/annotations.ts | 12 ++- x-pack/plugins/ml/server/routes/calendars.ts | 2 +- .../ml/server/routes/fields_service.ts | 2 +- .../ml/server/routes/file_data_visualizer.ts | 4 +- x-pack/plugins/ml/server/routes/filters.ts | 2 +- .../plugins/ml/server/routes/job_service.ts | 2 +- .../ml/server/routes/job_validation.ts | 2 +- x-pack/plugins/ml/server/routes/modules.ts | 21 +++- .../ml/server/routes/results_service.ts | 12 +-- .../ml/server/shared_services/index.ts} | 4 +- .../server/shared_services/license_checks.ts | 26 +++++ .../providers/anomaly_detectors.ts | 29 ++++++ .../shared_services/providers/job_service.ts | 22 +++++ .../shared_services/providers/modules.ts | 95 +++++++++++++++++++ .../providers/results_service.ts | 22 +++++ .../shared_services/providers/system.ts | 74 +++++++++++++++ .../server/shared_services/shared_services.ts | 41 ++++++++ x-pack/plugins/ml/server/types.ts | 2 +- 70 files changed, 511 insertions(+), 173 deletions(-) create mode 100644 x-pack/legacy/plugins/ml/common/types/ml_server_info.ts rename x-pack/plugins/ml/server/client/{__tests__/elasticsearch_ml.js => elasticsearch_ml.test.ts} (77%) rename x-pack/plugins/ml/server/client/{elasticsearch_ml.js => elasticsearch_ml.ts} (99%) rename x-pack/{legacy/plugins/ml/common/types/angular.ts => plugins/ml/server/shared_services/index.ts} (75%) create mode 100644 x-pack/plugins/ml/server/shared_services/license_checks.ts create mode 100644 x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts create mode 100644 x-pack/plugins/ml/server/shared_services/providers/job_service.ts create mode 100644 x-pack/plugins/ml/server/shared_services/providers/modules.ts create mode 100644 x-pack/plugins/ml/server/shared_services/providers/results_service.ts create mode 100644 x-pack/plugins/ml/server/shared_services/providers/system.ts create mode 100644 x-pack/plugins/ml/server/shared_services/shared_services.ts diff --git a/x-pack/legacy/plugins/ml/common/types/ml_server_info.ts b/x-pack/legacy/plugins/ml/common/types/ml_server_info.ts new file mode 100644 index 00000000000000..26dd1758827b4a --- /dev/null +++ b/x-pack/legacy/plugins/ml/common/types/ml_server_info.ts @@ -0,0 +1,32 @@ +/* + * 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 { CategorizationAnalyzer } from './categories'; + +export interface MlServerDefaults { + anomaly_detectors: { + categorization_examples_limit?: number; + model_memory_limit?: string; + model_snapshot_retention_days?: number; + categorization_analyzer?: CategorizationAnalyzer; + }; + datafeeds: { scroll_size?: number }; +} + +export interface MlServerLimits { + max_model_memory_limit?: string; +} + +export interface MlInfoResponse { + defaults: MlServerDefaults; + limits: MlServerLimits; + native_code: { + build_hash: string; + version: string; + }; + upgrade_mode: boolean; + cloudId?: string; +} diff --git a/x-pack/legacy/plugins/ml/common/types/modules.ts b/x-pack/legacy/plugins/ml/common/types/modules.ts index 87e19d09da30c4..4e77687b564184 100644 --- a/x-pack/legacy/plugins/ml/common/types/modules.ts +++ b/x-pack/legacy/plugins/ml/common/types/modules.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectAttributes } from 'src/core/public'; +import { SavedObjectAttributes } from 'kibana/public'; import { Datafeed, Job } from '../types/anomaly_detection_jobs'; export interface ModuleJob { diff --git a/x-pack/legacy/plugins/ml/index.ts b/x-pack/legacy/plugins/ml/index.ts index 47df7c8c3e5e62..e138426e75724e 100755 --- a/x-pack/legacy/plugins/ml/index.ts +++ b/x-pack/legacy/plugins/ml/index.ts @@ -10,7 +10,7 @@ import { Server } from 'src/legacy/server/kbn_server'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils'; // @ts-ignore: could not find declaration file for module import { mirrorPluginStatus } from '../../server/lib/mirror_plugin_status'; -// @ts-ignore: could not find declaration file for module +// @ts-ignore: importing JSON file import mappings from './mappings'; export const ml = (kibana: any) => { diff --git a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts index 350b3f98d46731..9a243e1b0316d8 100644 --- a/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts +++ b/x-pack/legacy/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts @@ -8,7 +8,7 @@ import { useReducer } from 'react'; import { i18n } from '@kbn/i18n'; -import { SimpleSavedObject } from 'src/core/public'; +import { SimpleSavedObject } from 'kibana/public'; import { ml } from '../../../../../services/ml_api_service'; import { useMlContext } from '../../../../../contexts/ml'; diff --git a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx index 5c32d62c39f845..1bde182e9c61b0 100644 --- a/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx +++ b/x-pack/legacy/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx @@ -5,7 +5,7 @@ */ import React, { FC, Fragment } from 'react'; -import { IUiSettingsClient } from 'src/core/public'; +import { IUiSettingsClient } from 'kibana/public'; import { useTimefilter } from '../../contexts/kibana'; import { NavigationMenu } from '../../components/navigation_menu'; diff --git a/x-pack/legacy/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts b/x-pack/legacy/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts index 835232a0303830..96075e89400833 100644 --- a/x-pack/legacy/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts +++ b/x-pack/legacy/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IUiSettingsClient } from 'src/core/public'; +import { IUiSettingsClient } from 'kibana/public'; import { esQuery, Query, esKuery } from '../../../../../../../../../src/plugins/data/public'; import { IIndexPattern } from '../../../../../../../../../src/plugins/data/common/index_patterns'; import { SEARCH_QUERY_LANGUAGE } from '../../../../../common/constants/search'; diff --git a/x-pack/legacy/plugins/ml/public/application/routing/breadcrumbs.ts b/x-pack/legacy/plugins/ml/public/application/routing/breadcrumbs.ts index 6d8138d4bcd2c6..74dbe055fead31 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/breadcrumbs.ts +++ b/x-pack/legacy/plugins/ml/public/application/routing/breadcrumbs.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { ChromeBreadcrumb } from '../../../../../../../src/core/public'; +import { ChromeBreadcrumb } from 'kibana/public'; export const ML_BREADCRUMB: ChromeBreadcrumb = Object.freeze({ text: i18n.translate('xpack.ml.machineLearningBreadcrumbLabel', { diff --git a/x-pack/legacy/plugins/ml/public/application/routing/router.tsx b/x-pack/legacy/plugins/ml/public/application/routing/router.tsx index 6b56bc154e8015..23c3908c9af076 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/router.tsx +++ b/x-pack/legacy/plugins/ml/public/application/routing/router.tsx @@ -8,7 +8,7 @@ import React, { FC } from 'react'; import { HashRouter, Route, RouteProps } from 'react-router-dom'; import { Location } from 'history'; -import { IUiSettingsClient, ChromeStart } from 'src/core/public'; +import { IUiSettingsClient, ChromeStart } from 'kibana/public'; import { ChromeBreadcrumb } from 'kibana/public'; import { IndexPatternsContract } from 'src/plugins/data/public'; import { MlContext, MlContextValue } from '../contexts/ml'; diff --git a/x-pack/legacy/plugins/ml/public/application/routing/use_resolver.ts b/x-pack/legacy/plugins/ml/public/application/routing/use_resolver.ts index ee4f77767fce8c..6df7eee3d64a61 100644 --- a/x-pack/legacy/plugins/ml/public/application/routing/use_resolver.ts +++ b/x-pack/legacy/plugins/ml/public/application/routing/use_resolver.ts @@ -5,7 +5,7 @@ */ import { useEffect, useState } from 'react'; -import { IUiSettingsClient } from 'src/core/public'; +import { IUiSettingsClient } from 'kibana/public'; import { getIndexPatternById, getIndexPatternsContract, diff --git a/x-pack/legacy/plugins/ml/public/application/services/ml_api_service/index.d.ts b/x-pack/legacy/plugins/ml/public/application/services/ml_api_service/index.d.ts index 97e001389c5f1a..9aec9a4c0bfad7 100644 --- a/x-pack/legacy/plugins/ml/public/application/services/ml_api_service/index.d.ts +++ b/x-pack/legacy/plugins/ml/public/application/services/ml_api_service/index.d.ts @@ -11,7 +11,11 @@ import { AggFieldNamePair } from '../../../../common/types/fields'; import { Category } from '../../../../common/types/categories'; import { ExistingJobsAndGroups } from '../job_service'; import { PrivilegesResponse } from '../../../../common/types/privileges'; -import { MlServerDefaults, MlServerLimits } from '../ml_server_info'; +import { + MlInfoResponse, + MlServerDefaults, + MlServerLimits, +} from '../../../../common/types/ml_server_info'; import { ES_AGGREGATION } from '../../../../common/constants/aggregation_types'; import { DataFrameAnalyticsStats } from '../../data_frame_analytics/pages/analytics_management/components/analytics_list/common'; import { JobMessage } from '../../../../common/types/audit_message'; @@ -69,17 +73,6 @@ export interface BucketSpanEstimatorResponse { message?: { msg: string } | string; } -export interface MlInfoResponse { - defaults: MlServerDefaults; - limits: MlServerLimits; - native_code: { - build_hash: string; - version: string; - }; - upgrade_mode: boolean; - cloudId?: string; -} - export interface SuccessCardinality { id: 'success_cardinality'; } diff --git a/x-pack/legacy/plugins/ml/public/application/services/ml_server_info.ts b/x-pack/legacy/plugins/ml/public/application/services/ml_server_info.ts index 304778281c2f2f..8ab955b479108c 100644 --- a/x-pack/legacy/plugins/ml/public/application/services/ml_server_info.ts +++ b/x-pack/legacy/plugins/ml/public/application/services/ml_server_info.ts @@ -5,21 +5,7 @@ */ import { ml } from './ml_api_service'; -import { CategorizationAnalyzer } from '../../../common/types/categories'; - -export interface MlServerDefaults { - anomaly_detectors: { - categorization_examples_limit?: number; - model_memory_limit?: string; - model_snapshot_retention_days?: number; - categorization_analyzer?: CategorizationAnalyzer; - }; - datafeeds: { scroll_size?: number }; -} - -export interface MlServerLimits { - max_model_memory_limit?: string; -} +import { MlServerDefaults, MlServerLimits } from '../../../common/types/ml_server_info'; export interface CloudInfo { cloudId: string | null; diff --git a/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts b/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts index 6982d3d2dba976..f7d524c3a19b7d 100644 --- a/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts +++ b/x-pack/legacy/plugins/ml/public/application/util/dependency_cache.ts @@ -11,7 +11,7 @@ import { SavedObjectsClientContract, ApplicationStart, HttpStart, -} from 'src/core/public'; +} from 'kibana/public'; import { IndexPatternsContract, DataPublicPluginStart } from 'src/plugins/data/public'; import { DocLinksStart, diff --git a/x-pack/legacy/plugins/ml/public/index.ts b/x-pack/legacy/plugins/ml/public/index.ts index bafeb7277927f5..56fbdb43f34f24 100755 --- a/x-pack/legacy/plugins/ml/public/index.ts +++ b/x-pack/legacy/plugins/ml/public/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializer } from '../../../../../src/core/public'; +import { PluginInitializer } from 'kibana/public'; import { MlPlugin, Setup, Start } from './plugin'; export const plugin: PluginInitializer = () => new MlPlugin(); diff --git a/x-pack/legacy/plugins/ml/public/legacy.ts b/x-pack/legacy/plugins/ml/public/legacy.ts index 9fb53e78d9454a..8a8ff5a7a9d13a 100644 --- a/x-pack/legacy/plugins/ml/public/legacy.ts +++ b/x-pack/legacy/plugins/ml/public/legacy.ts @@ -5,7 +5,7 @@ */ import { npSetup, npStart } from 'ui/new_platform'; -import { PluginInitializerContext } from 'src/core/public'; +import { PluginInitializerContext } from 'kibana/public'; import { SecurityPluginSetup } from '../../../../plugins/security/public'; import { LicensingPluginSetup } from '../../../../plugins/licensing/public'; diff --git a/x-pack/legacy/plugins/ml/public/plugin.ts b/x-pack/legacy/plugins/ml/public/plugin.ts index 1ef700f55b4dbc..928f353fd622e4 100644 --- a/x-pack/legacy/plugins/ml/public/plugin.ts +++ b/x-pack/legacy/plugins/ml/public/plugin.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Plugin, CoreStart, CoreSetup } from 'src/core/public'; +import { Plugin, CoreStart, CoreSetup } from 'kibana/public'; import { MlDependencies } from './application/app'; export class MlPlugin implements Plugin { diff --git a/x-pack/plugins/ml/server/client/__tests__/elasticsearch_ml.js b/x-pack/plugins/ml/server/client/elasticsearch_ml.test.ts similarity index 77% rename from x-pack/plugins/ml/server/client/__tests__/elasticsearch_ml.js rename to x-pack/plugins/ml/server/client/elasticsearch_ml.test.ts index 44a2cb00748b3d..543cf4ddad9820 100644 --- a/x-pack/plugins/ml/server/client/__tests__/elasticsearch_ml.js +++ b/x-pack/plugins/ml/server/client/elasticsearch_ml.test.ts @@ -4,14 +4,22 @@ * you may not use this file except in compliance with the Elastic License. */ -import expect from '@kbn/expect'; -import { elasticsearchJsPlugin } from '../elasticsearch_ml'; +import { elasticsearchJsPlugin } from './elasticsearch_ml'; + +interface Endpoint { + fmt: string; +} + +interface ClientAction { + urls?: Endpoint[]; + url: Endpoint; +} describe('ML - Endpoints', () => { // Check all paths in the ML elasticsearchJsPlugin start with a leading forward slash // so they work if Kibana is run behind a reverse proxy - const PATH_START = '/'; - const urls = []; + const PATH_START: string = '/'; + const urls: string[] = []; // Stub objects const Client = { @@ -20,7 +28,7 @@ describe('ML - Endpoints', () => { const components = { clientAction: { - factory: function(obj) { + factory(obj: ClientAction) { // add each endpoint URL to a list if (obj.urls) { obj.urls.forEach(url => { @@ -45,7 +53,7 @@ describe('ML - Endpoints', () => { describe('paths', () => { it(`should start with ${PATH_START}`, () => { urls.forEach(url => { - expect(url[0]).to.eql(PATH_START); + expect(url[0]).toEqual(PATH_START); }); }); }); diff --git a/x-pack/plugins/ml/server/client/elasticsearch_ml.js b/x-pack/plugins/ml/server/client/elasticsearch_ml.ts similarity index 99% rename from x-pack/plugins/ml/server/client/elasticsearch_ml.js rename to x-pack/plugins/ml/server/client/elasticsearch_ml.ts index e3092abb5d34ee..1d09a6c765e295 100644 --- a/x-pack/plugins/ml/server/client/elasticsearch_ml.js +++ b/x-pack/plugins/ml/server/client/elasticsearch_ml.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export const elasticsearchJsPlugin = (Client, config, components) => { +export const elasticsearchJsPlugin = (Client: any, config: any, components: any) => { const ca = components.clientAction.factory; Client.prototype.ml = components.clientAction.namespaceFactory(); diff --git a/x-pack/plugins/ml/server/client/error_wrapper.ts b/x-pack/plugins/ml/server/client/error_wrapper.ts index 6ab31d11f4b32c..7f691732954821 100644 --- a/x-pack/plugins/ml/server/client/error_wrapper.ts +++ b/x-pack/plugins/ml/server/client/error_wrapper.ts @@ -5,7 +5,7 @@ */ import { boomify, isBoom } from 'boom'; -import { ResponseError, CustomHttpResponseOptions } from 'src/core/server'; +import { ResponseError, CustomHttpResponseOptions } from 'kibana/server'; export function wrapError(error: any): CustomHttpResponseOptions { const boom = isBoom(error) ? error : boomify(error, { statusCode: error.status }); diff --git a/x-pack/plugins/ml/server/client/log.ts b/x-pack/plugins/ml/server/client/log.ts index 8ee5882f6c2c16..243e3b6398aad1 100644 --- a/x-pack/plugins/ml/server/client/log.ts +++ b/x-pack/plugins/ml/server/client/log.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger } from '../../../../../src/core/server'; +import { Logger } from 'kibana/server'; export interface LogInitialization { log: Logger; diff --git a/x-pack/plugins/ml/server/index.ts b/x-pack/plugins/ml/server/index.ts index 55e87ed6f0c6a3..6cfa1b23408c0b 100644 --- a/x-pack/plugins/ml/server/index.ts +++ b/x-pack/plugins/ml/server/index.ts @@ -6,5 +6,6 @@ import { PluginInitializerContext } from 'kibana/server'; import { MlServerPlugin } from './plugin'; +export { MlStartContract, MlSetupContract } from './plugin'; export const plugin = (ctx: PluginInitializerContext) => new MlServerPlugin(ctx); diff --git a/x-pack/plugins/ml/server/lib/check_annotations/index.ts b/x-pack/plugins/ml/server/lib/check_annotations/index.ts index 8d9d56ad665c43..f74aca0f05f45c 100644 --- a/x-pack/plugins/ml/server/lib/check_annotations/index.ts +++ b/x-pack/plugins/ml/server/lib/check_annotations/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { mlLog } from '../../client/log'; import { diff --git a/x-pack/plugins/ml/server/lib/check_privileges/check_privileges.ts b/x-pack/plugins/ml/server/lib/check_privileges/check_privileges.ts index f26040385b9f50..111db8d35463c4 100644 --- a/x-pack/plugins/ml/server/lib/check_privileges/check_privileges.ts +++ b/x-pack/plugins/ml/server/lib/check_privileges/check_privileges.ts @@ -16,7 +16,7 @@ import { mlPrivileges } from './privileges'; type ClusterPrivilege = Record; -interface Response { +export interface MlCapabilities { capabilities: Privileges; upgradeInProgress: boolean; isPlatinumOrTrialLicense: boolean; @@ -30,7 +30,7 @@ export function privilegesProvider( ignoreSpaces: boolean = false ) { const { isUpgradeInProgress } = upgradeCheckProvider(callAsCurrentUser); - async function getPrivileges(): Promise { + async function getPrivileges(): Promise { // get the default privileges, forced to be false. const privileges = getDefaultPrivileges(); diff --git a/x-pack/plugins/ml/server/lib/check_privileges/index.ts b/x-pack/plugins/ml/server/lib/check_privileges/index.ts index 45621218c22a9d..67b435116aa007 100644 --- a/x-pack/plugins/ml/server/lib/check_privileges/index.ts +++ b/x-pack/plugins/ml/server/lib/check_privileges/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { privilegesProvider } from './check_privileges'; +export { privilegesProvider, MlCapabilities } from './check_privileges'; diff --git a/x-pack/plugins/ml/server/lib/license/ml_server_license.ts b/x-pack/plugins/ml/server/lib/license/ml_server_license.ts index 7602ab4919e818..90a863d17222f8 100644 --- a/x-pack/plugins/ml/server/lib/license/ml_server_license.ts +++ b/x-pack/plugins/ml/server/lib/license/ml_server_license.ts @@ -8,7 +8,7 @@ import { KibanaResponseFactory, RequestHandler, RequestHandlerContext, -} from 'src/core/server'; +} from 'kibana/server'; import { MlLicense } from '../../../../../legacy/plugins/ml/common/license'; diff --git a/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts b/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts index a120450bbb2b0a..15a430a08eac19 100644 --- a/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts +++ b/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts @@ -5,7 +5,7 @@ */ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { SavedObjectsServiceStart } from 'src/core/server'; +import { SavedObjectsServiceStart } from 'kibana/server'; import { createMlTelemetry, ML_TELEMETRY_DOC_ID, diff --git a/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts b/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts index 8cf24213961b18..e1db7b7008b3b9 100644 --- a/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts +++ b/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectAttributes, SavedObjectsClientContract } from 'src/core/server'; +import { SavedObjectAttributes, SavedObjectsClientContract } from 'kibana/server'; export interface MlTelemetry extends SavedObjectAttributes { file_data_visualizer: { @@ -40,7 +40,10 @@ export async function incrementFileDataVisualizerIndexCreationCount( savedObjectsClient: SavedObjectsClientContract ): Promise { try { - const { attributes } = await savedObjectsClient.get('telemetry', 'telemetry'); + const { attributes } = await savedObjectsClient.get<{ enabled: boolean }>( + 'telemetry', + 'telemetry' + ); if (attributes.enabled === false) { return; diff --git a/x-pack/plugins/ml/server/lib/spaces_utils.ts b/x-pack/plugins/ml/server/lib/spaces_utils.ts index ed684eadb95704..c3f5b013e36e5b 100644 --- a/x-pack/plugins/ml/server/lib/spaces_utils.ts +++ b/x-pack/plugins/ml/server/lib/spaces_utils.ts @@ -4,15 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Request } from 'hapi'; +import { Legacy } from 'kibana'; +import { KibanaRequest } from 'kibana/server'; import { Space, SpacesPluginSetup } from '../../../spaces/server'; +export type RequestFacade = KibanaRequest | Legacy.Request; + interface GetActiveSpaceResponse { valid: boolean; space?: Space; } -export function spacesUtilsProvider(spacesPlugin: SpacesPluginSetup, request: Request) { +export function spacesUtilsProvider(spacesPlugin: SpacesPluginSetup, request: RequestFacade) { async function activeSpace(): Promise { try { return { diff --git a/x-pack/plugins/ml/server/models/annotation_service/annotation.test.ts b/x-pack/plugins/ml/server/models/annotation_service/annotation.test.ts index d7a13154a6f378..4e38a6be1df561 100644 --- a/x-pack/plugins/ml/server/models/annotation_service/annotation.test.ts +++ b/x-pack/plugins/ml/server/models/annotation_service/annotation.test.ts @@ -6,7 +6,7 @@ import getAnnotationsRequestMock from './__mocks__/get_annotations_request.json'; import getAnnotationsResponseMock from './__mocks__/get_annotations_response.json'; -import { RequestHandlerContext } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { ANNOTATION_TYPE } from '../../../../../legacy/plugins/ml/common/constants/annotations'; import { ML_ANNOTATIONS_INDEX_ALIAS_WRITE } from '../../../../../legacy/plugins/ml/common/constants/index_patterns'; @@ -26,27 +26,21 @@ describe('annotation_service', () => { let callWithRequestSpy: any; beforeEach(() => { - callWithRequestSpy = ({ - ml: { - mlClient: { - callAsCurrentUser: jest.fn((action: string) => { - switch (action) { - case 'delete': - case 'index': - return Promise.resolve(acknowledgedResponseMock); - case 'search': - return Promise.resolve(getAnnotationsResponseMock); - } - }), - }, - }, - } as unknown) as RequestHandlerContext; + callWithRequestSpy = (jest.fn((action: string) => { + switch (action) { + case 'delete': + case 'index': + return Promise.resolve(acknowledgedResponseMock); + case 'search': + return Promise.resolve(getAnnotationsResponseMock); + } + }) as unknown) as APICaller; }); describe('deleteAnnotation()', () => { it('should delete annotation', async done => { const { deleteAnnotation } = annotationServiceProvider(callWithRequestSpy); - const mockFunct = callWithRequestSpy.ml.mlClient.callAsCurrentUser; + const mockFunct = callWithRequestSpy; const annotationMockId = 'mockId'; const deleteParamsMock: DeleteParams = { @@ -67,7 +61,7 @@ describe('annotation_service', () => { describe('getAnnotation()', () => { it('should get annotations for specific job', async done => { const { getAnnotations } = annotationServiceProvider(callWithRequestSpy); - const mockFunct = callWithRequestSpy.ml.mlClient.callAsCurrentUser; + const mockFunct = callWithRequestSpy; const indexAnnotationArgsMock: IndexAnnotationArgs = { jobIds: [jobIdMock], @@ -93,15 +87,9 @@ describe('annotation_service', () => { message: 'mock error message', }; - const callWithRequestSpyError = ({ - ml: { - mlClient: { - callAsCurrentUser: jest.fn(() => { - return Promise.resolve(mockEsError); - }), - }, - }, - } as unknown) as RequestHandlerContext; + const callWithRequestSpyError = (jest.fn(() => { + return Promise.resolve(mockEsError); + }) as unknown) as APICaller; const { getAnnotations } = annotationServiceProvider(callWithRequestSpyError); @@ -121,7 +109,7 @@ describe('annotation_service', () => { describe('indexAnnotation()', () => { it('should index annotation', async done => { const { indexAnnotation } = annotationServiceProvider(callWithRequestSpy); - const mockFunct = callWithRequestSpy.ml.mlClient.callAsCurrentUser; + const mockFunct = callWithRequestSpy; const annotationMock: Annotation = { annotation: 'Annotation text', @@ -149,7 +137,7 @@ describe('annotation_service', () => { it('should remove ._id and .key before updating annotation', async done => { const { indexAnnotation } = annotationServiceProvider(callWithRequestSpy); - const mockFunct = callWithRequestSpy.ml.mlClient.callAsCurrentUser; + const mockFunct = callWithRequestSpy; const annotationMock: Annotation = { _id: 'mockId', @@ -181,7 +169,7 @@ describe('annotation_service', () => { it('should update annotation text and the username for modified_username', async done => { const { getAnnotations, indexAnnotation } = annotationServiceProvider(callWithRequestSpy); - const mockFunct = callWithRequestSpy.ml.mlClient.callAsCurrentUser; + const mockFunct = callWithRequestSpy; const indexAnnotationArgsMock: IndexAnnotationArgs = { jobIds: [jobIdMock], diff --git a/x-pack/plugins/ml/server/models/annotation_service/annotation.ts b/x-pack/plugins/ml/server/models/annotation_service/annotation.ts index 042d7bbc80653a..bccfb99e9cf6df 100644 --- a/x-pack/plugins/ml/server/models/annotation_service/annotation.ts +++ b/x-pack/plugins/ml/server/models/annotation_service/annotation.ts @@ -6,7 +6,7 @@ import Boom from 'boom'; import _ from 'lodash'; -import { RequestHandlerContext } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { ANNOTATION_TYPE } from '../../../../../legacy/plugins/ml/common/constants/annotations'; import { @@ -68,8 +68,7 @@ export type callWithRequestType = ( params: annotationProviderParams ) => Promise; -export function annotationProvider(context: RequestHandlerContext) { - const callAsCurrentUser = context.ml!.mlClient.callAsCurrentUser; +export function annotationProvider(callAsCurrentUser: APICaller) { async function indexAnnotation(annotation: Annotation, username: string) { if (isAnnotation(annotation) === false) { // No need to translate, this will not be exposed in the UI. diff --git a/x-pack/plugins/ml/server/models/annotation_service/index.ts b/x-pack/plugins/ml/server/models/annotation_service/index.ts index 9847ce1db6552b..995f800b0a498e 100644 --- a/x-pack/plugins/ml/server/models/annotation_service/index.ts +++ b/x-pack/plugins/ml/server/models/annotation_service/index.ts @@ -4,11 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { annotationProvider } from './annotation'; -export function annotationServiceProvider(context: RequestHandlerContext) { +export function annotationServiceProvider(callAsCurrentUser: APICaller) { return { - ...annotationProvider(context), + ...annotationProvider(callAsCurrentUser), }; } diff --git a/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.d.ts b/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.d.ts index e39a0177c31b95..8be0d6615780ad 100644 --- a/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.d.ts +++ b/x-pack/plugins/ml/server/models/bucket_span_estimator/bucket_span_estimator.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { BucketSpanEstimatorData } from '../../../../../legacy/plugins/ml/public/application/services/ml_api_service'; export function estimateBucketSpanFactory( diff --git a/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.d.ts b/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.d.ts index 87c9a8c978274c..927728040bdd78 100644 --- a/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.d.ts +++ b/x-pack/plugins/ml/server/models/calculate_model_memory_limit/calculate_model_memory_limit.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; export function calculateModelMemoryLimitProvider( callAsCurrentUser: APICaller diff --git a/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts b/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts index 61f21c316be233..64d750f511f3a7 100644 --- a/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts +++ b/x-pack/plugins/ml/server/models/calendar/calendar_manager.ts @@ -6,7 +6,7 @@ import { difference } from 'lodash'; import Boom from 'boom'; -import { IScopedClusterClient } from 'src/core/server'; +import { IScopedClusterClient } from 'kibana/server'; import { EventManager, CalendarEvent } from './event_manager'; interface BasicCalendar { diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts index c51f65714bc055..fd1023251cc811 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.test.ts @@ -4,26 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { APICaller, SavedObjectsClientContract } from 'kibana/server'; import { Module } from '../../../../../legacy/plugins/ml/common/types/modules'; import { DataRecognizer } from '../data_recognizer'; describe('ML - data recognizer', () => { - const dr = new DataRecognizer(({ - ml: { - mlClient: { - callAsCurrentUser: jest.fn(), - }, - }, - core: { - savedObjects: { - client: { - find: jest.fn(), - bulkCreate: jest.fn(), - }, - }, - }, - } as unknown) as RequestHandlerContext); + const dr = new DataRecognizer( + jest.fn() as APICaller, + ({ + find: jest.fn(), + bulkCreate: jest.fn(), + } as never) as SavedObjectsClientContract + ); const moduleIds = [ 'apache_ecs', diff --git a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts index 020a77baa4e358..6852d089290e1e 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts @@ -7,7 +7,7 @@ import fs from 'fs'; import Boom from 'boom'; import numeral from '@elastic/numeral'; -import { CallAPIOptions, RequestHandlerContext, SavedObjectsClientContract } from 'kibana/server'; +import { CallAPIOptions, APICaller, SavedObjectsClientContract } from 'kibana/server'; import { IndexPatternAttributes } from 'src/plugins/data/server'; import { merge } from 'lodash'; import { CombinedJobWithStats } from '../../../../../legacy/plugins/ml/common/types/anomaly_detection_jobs'; @@ -68,7 +68,7 @@ interface Config { json: RawModuleConfig; } -interface Result { +export interface RecognizeResult { id: string; title: string; query: any; @@ -118,9 +118,9 @@ export class DataRecognizer { options?: CallAPIOptions ) => Promise; - constructor(context: RequestHandlerContext) { - this.callAsCurrentUser = context.ml!.mlClient.callAsCurrentUser; - this.savedObjectsClient = context.core.savedObjects.client; + constructor(callAsCurrentUser: APICaller, savedObjectsClient: SavedObjectsClientContract) { + this.callAsCurrentUser = callAsCurrentUser; + this.savedObjectsClient = savedObjectsClient; } // list all directories under the given directory @@ -189,9 +189,9 @@ export class DataRecognizer { } // called externally by an endpoint - async findMatches(indexPattern: string): Promise { + async findMatches(indexPattern: string): Promise { const manifestFiles = await this.loadManifestFiles(); - const results: Result[] = []; + const results: RecognizeResult[] = []; await Promise.all( manifestFiles.map(async i => { diff --git a/x-pack/plugins/ml/server/models/data_recognizer/index.ts b/x-pack/plugins/ml/server/models/data_recognizer/index.ts index cc66fdac85af74..10e1cb90484e0e 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/index.ts +++ b/x-pack/plugins/ml/server/models/data_recognizer/index.ts @@ -4,4 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { DataRecognizer } from './data_recognizer'; +export { DataRecognizer, RecognizeResult } from './data_recognizer'; diff --git a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts index 9463f74e1e746e..9e663248864ba3 100644 --- a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts +++ b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { CallAPIOptions, IScopedClusterClient } from 'src/core/server'; +import { CallAPIOptions, IScopedClusterClient } from 'kibana/server'; import _ from 'lodash'; import { ML_JOB_FIELD_TYPES } from '../../../../../legacy/plugins/ml/common/constants/field_types'; import { getSafeAggregationName } from '../../../../../legacy/plugins/ml/common/util/job_utils'; diff --git a/x-pack/plugins/ml/server/models/fields_service/fields_service.d.ts b/x-pack/plugins/ml/server/models/fields_service/fields_service.d.ts index 38f7dce93546d6..4a7e57d290b176 100644 --- a/x-pack/plugins/ml/server/models/fields_service/fields_service.d.ts +++ b/x-pack/plugins/ml/server/models/fields_service/fields_service.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; export function fieldsServiceProvider( callAsCurrentUser: APICaller diff --git a/x-pack/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts b/x-pack/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts index 1d0452f2337f95..e3c492545d03ab 100644 --- a/x-pack/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts +++ b/x-pack/plugins/ml/server/models/file_data_visualizer/file_data_visualizer.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { RequestHandlerContext } from 'kibana/server'; +import { APICaller } from 'kibana/server'; import { FindFileStructureResponse } from '../../../../../legacy/plugins/ml/common/types/file_datavisualizer'; export type InputData = any[]; @@ -25,12 +25,12 @@ export interface AnalysisResult { overrides?: FormattedOverrides; } -export function fileDataVisualizerProvider(context: RequestHandlerContext) { +export function fileDataVisualizerProvider(callAsCurrentUser: APICaller) { async function analyzeFile(data: any, overrides: any): Promise { let results = []; try { - results = await context.ml!.mlClient.callAsCurrentUser('ml.fileStructure', { + results = await callAsCurrentUser('ml.fileStructure', { body: data, ...overrides, }); diff --git a/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts b/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts index e4de71ad0793d2..02682a70c8c1f7 100644 --- a/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts +++ b/x-pack/plugins/ml/server/models/file_data_visualizer/import_data.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'kibana/server'; +import { APICaller } from 'kibana/server'; import { INDEX_META_DATA_CREATED_BY } from '../../../../../legacy/plugins/ml/common/constants/file_datavisualizer'; import { InputData } from './file_data_visualizer'; @@ -30,9 +30,7 @@ interface Failure { doc: any; } -export function importDataProvider(context: RequestHandlerContext) { - const callAsCurrentUser = context.ml!.mlClient.callAsCurrentUser; - +export function importDataProvider(callAsCurrentUser: APICaller) { async function importData( id: string, index: string, diff --git a/x-pack/plugins/ml/server/models/filter/filter_manager.ts b/x-pack/plugins/ml/server/models/filter/filter_manager.ts index baba495257acac..282517a1c09675 100644 --- a/x-pack/plugins/ml/server/models/filter/filter_manager.ts +++ b/x-pack/plugins/ml/server/models/filter/filter_manager.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { IScopedClusterClient } from 'src/core/server'; +import { IScopedClusterClient } from 'kibana/server'; import { DetectorRule, diff --git a/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.d.ts b/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.d.ts index c4910b2535fb1c..00538f498d61b1 100644 --- a/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.d.ts +++ b/x-pack/plugins/ml/server/models/job_audit_messages/job_audit_messages.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; export function jobAuditMessagesProvider( callAsCurrentUser: APICaller diff --git a/x-pack/plugins/ml/server/models/job_service/datafeeds.ts b/x-pack/plugins/ml/server/models/job_service/datafeeds.ts index 47a0d8f2546595..0ec622f322f450 100644 --- a/x-pack/plugins/ml/server/models/job_service/datafeeds.ts +++ b/x-pack/plugins/ml/server/models/job_service/datafeeds.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { i18n } from '@kbn/i18n'; import { JOB_STATE, diff --git a/x-pack/plugins/ml/server/models/job_service/groups.ts b/x-pack/plugins/ml/server/models/job_service/groups.ts index 58d71aa331ea9d..ca283153a4ba51 100644 --- a/x-pack/plugins/ml/server/models/job_service/groups.ts +++ b/x-pack/plugins/ml/server/models/job_service/groups.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { CalendarManager } from '../calendar'; import { GLOBAL_CALENDAR } from '../../../../../legacy/plugins/ml/common/constants/calendars'; import { Job } from '../../../../../legacy/plugins/ml/common/types/anomaly_detection_jobs'; diff --git a/x-pack/plugins/ml/server/models/job_service/index.ts b/x-pack/plugins/ml/server/models/job_service/index.ts index 37a1daa20cab2d..eb70a3ccecfc19 100644 --- a/x-pack/plugins/ml/server/models/job_service/index.ts +++ b/x-pack/plugins/ml/server/models/job_service/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { datafeedsProvider } from './datafeeds'; import { jobsProvider } from './jobs'; import { groupsProvider } from './groups'; diff --git a/x-pack/plugins/ml/server/models/job_service/jobs.ts b/x-pack/plugins/ml/server/models/job_service/jobs.ts index 6ced623273f742..4d708bb356f5c2 100644 --- a/x-pack/plugins/ml/server/models/job_service/jobs.ts +++ b/x-pack/plugins/ml/server/models/job_service/jobs.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import { uniq } from 'lodash'; -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { JOB_STATE, DATAFEED_STATE, diff --git a/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts b/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts index 4cbdfe4f360e03..45daed6dca0277 100644 --- a/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts +++ b/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObject } from 'src/core/server'; +import { SavedObject } from 'kibana/server'; import { IndexPatternAttributes } from 'src/plugins/data/server'; import { SavedObjectsClientContract } from 'kibana/server'; import { FieldId } from '../../../../../../legacy/plugins/ml/common/types/fields'; diff --git a/x-pack/plugins/ml/server/models/job_validation/job_validation.d.ts b/x-pack/plugins/ml/server/models/job_validation/job_validation.d.ts index bb8a372eaba30c..33f5d5ec95fad5 100644 --- a/x-pack/plugins/ml/server/models/job_validation/job_validation.d.ts +++ b/x-pack/plugins/ml/server/models/job_validation/job_validation.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { TypeOf } from '@kbn/config-schema'; import { validateJobSchema } from '../../routes/schemas/job_validation_schema'; diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.d.ts b/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.d.ts index ada2a1222281db..da83a81546994b 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.d.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_cardinality.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { CombinedJob } from '../../../../../legacy/plugins/ml/common/types/anomaly_detection_jobs'; export function validateCardinality(callAsCurrentUser: APICaller, job: CombinedJob): any[]; diff --git a/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts b/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts index e2f6e0dca1a6f4..d012f928f059c1 100644 --- a/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts +++ b/x-pack/plugins/ml/server/models/job_validation/validate_time_range.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { APICaller } from 'src/core/server'; +import { APICaller } from 'kibana/server'; import { ES_FIELD_TYPES } from '../../../../../../src/plugins/data/server'; import { parseInterval } from '../../../../../legacy/plugins/ml/common/util/parse_interval'; import { CombinedJob } from '../../../../../legacy/plugins/ml/common/types/anomaly_detection_jobs'; diff --git a/x-pack/plugins/ml/server/models/results_service/results_service.ts b/x-pack/plugins/ml/server/models/results_service/results_service.ts index 324cbb91ca8c10..1cef0544fb5aca 100644 --- a/x-pack/plugins/ml/server/models/results_service/results_service.ts +++ b/x-pack/plugins/ml/server/models/results_service/results_service.ts @@ -7,7 +7,7 @@ import _ from 'lodash'; import moment from 'moment'; import { SearchResponse } from 'elasticsearch'; -import { RequestHandlerContext } from 'kibana/server'; +import { APICaller } from 'kibana/server'; import { buildAnomalyTableItems, AnomaliesTableRecord } from './build_anomaly_table_items'; import { ML_RESULTS_INDEX_PATTERN } from '../../../../../legacy/plugins/ml/common/constants/index_patterns'; import { ANOMALIES_TABLE_DEFAULT_QUERY_SIZE } from '../../../../../legacy/plugins/ml/common/constants/search'; @@ -30,9 +30,7 @@ interface Influencer { fieldValue: any; } -export function resultsServiceProvider(client: RequestHandlerContext | ((...args: any[]) => any)) { - const callAsCurrentUser = - typeof client === 'object' ? client.ml!.mlClient.callAsCurrentUser : client; +export function resultsServiceProvider(callAsCurrentUser: APICaller) { // Obtains data for the anomalies table, aggregating anomalies by day or hour as requested. // Return an Object with properties 'anomalies' and 'interval' (interval used to aggregate anomalies, // one of day, hour or second. Note 'auto' can be provided as the aggregationInterval in the request, diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 547d3f8ab06cb5..cac5036ca5445f 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -5,11 +5,16 @@ */ import { i18n } from '@kbn/i18n'; -import { CoreSetup, IScopedClusterClient, Logger, PluginInitializerContext } from 'src/core/server'; +import { + CoreSetup, + Plugin, + IScopedClusterClient, + Logger, + PluginInitializerContext, +} from 'kibana/server'; import { PluginsSetup, RouteInitialization } from './types'; import { PLUGIN_ID } from '../../../legacy/plugins/ml/common/constants/app'; -// @ts-ignore: could not find declaration file for module import { elasticsearchJsPlugin } from './client/elasticsearch_ml'; import { makeMlUsageCollector } from './lib/ml_telemetry'; import { initMlServerLog } from './client/log'; @@ -34,6 +39,7 @@ import { resultsServiceRoutes } from './routes/results_service'; import { systemRoutes } from './routes/system'; import { MlLicense } from '../../../legacy/plugins/ml/common/license'; import { MlServerLicense } from './lib/license'; +import { createSharedServices, SharedServices } from './shared_services'; declare module 'kibana/server' { interface RequestHandlerContext { @@ -43,7 +49,10 @@ declare module 'kibana/server' { } } -export class MlServerPlugin { +export type MlSetupContract = SharedServices; +export type MlStartContract = void; + +export class MlServerPlugin implements Plugin { private log: Logger; private version: string; private mlLicense: MlServerLicense; @@ -54,7 +63,7 @@ export class MlServerPlugin { this.mlLicense = new MlServerLicense(); } - public setup(coreSetup: CoreSetup, plugins: PluginsSetup) { + public setup(coreSetup: CoreSetup, plugins: PluginsSetup): MlSetupContract { plugins.features.registerFeature({ id: PLUGIN_ID, name: i18n.translate('xpack.ml.featureRegistry.mlFeatureName', { @@ -124,9 +133,11 @@ export class MlServerPlugin { coreSetup.getStartServices().then(([core]) => { makeMlUsageCollector(plugins.usageCollection, core.savedObjects); }); + + return createSharedServices(this.mlLicense, plugins.spaces, plugins.cloud); } - public start() {} + public start(): MlStartContract {} public stop() { this.mlLicense.unsubscribe(); diff --git a/x-pack/plugins/ml/server/routes/annotations.ts b/x-pack/plugins/ml/server/routes/annotations.ts index c481fb8698855f..025b7ae853b0db 100644 --- a/x-pack/plugins/ml/server/routes/annotations.ts +++ b/x-pack/plugins/ml/server/routes/annotations.ts @@ -62,7 +62,9 @@ export function annotationRoutes( }, mlLicense.fullLicenseAPIGuard(async (context, request, response) => { try { - const { getAnnotations } = annotationServiceProvider(context); + const { getAnnotations } = annotationServiceProvider( + context.ml!.mlClient.callAsCurrentUser + ); const resp = await getAnnotations(request.body); return response.ok({ @@ -100,7 +102,9 @@ export function annotationRoutes( throw getAnnotationsFeatureUnavailableErrorMessage(); } - const { indexAnnotation } = annotationServiceProvider(context); + const { indexAnnotation } = annotationServiceProvider( + context.ml!.mlClient.callAsCurrentUser + ); const currentUser = securityPlugin !== undefined ? securityPlugin.authc.getCurrentUser(request) : {}; @@ -143,7 +147,9 @@ export function annotationRoutes( } const annotationId = request.params.annotationId; - const { deleteAnnotation } = annotationServiceProvider(context); + const { deleteAnnotation } = annotationServiceProvider( + context.ml!.mlClient.callAsCurrentUser + ); const resp = await deleteAnnotation(annotationId); return response.ok({ diff --git a/x-pack/plugins/ml/server/routes/calendars.ts b/x-pack/plugins/ml/server/routes/calendars.ts index 5d1161e928d110..63984728a18dd0 100644 --- a/x-pack/plugins/ml/server/routes/calendars.ts +++ b/x-pack/plugins/ml/server/routes/calendars.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'src/core/server'; +import { RequestHandlerContext } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; diff --git a/x-pack/plugins/ml/server/routes/fields_service.ts b/x-pack/plugins/ml/server/routes/fields_service.ts index f4d4e5759a1054..db7613b163457e 100644 --- a/x-pack/plugins/ml/server/routes/fields_service.ts +++ b/x-pack/plugins/ml/server/routes/fields_service.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'src/core/server'; +import { RequestHandlerContext } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; import { diff --git a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts index 69ec79704deee6..c3a2fb542e0b33 100644 --- a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts @@ -22,7 +22,7 @@ import { RouteInitialization } from '../types'; import { incrementFileDataVisualizerIndexCreationCount } from '../lib/ml_telemetry'; function analyzeFiles(context: RequestHandlerContext, data: InputData, overrides: InputOverrides) { - const { analyzeFile } = fileDataVisualizerProvider(context); + const { analyzeFile } = fileDataVisualizerProvider(context.ml!.mlClient.callAsCurrentUser); return analyzeFile(data, overrides); } @@ -35,7 +35,7 @@ function importData( ingestPipeline: InjectPipeline, data: InputData ) { - const { importData: importDataFunc } = importDataProvider(context); + const { importData: importDataFunc } = importDataProvider(context.ml!.mlClient.callAsCurrentUser); return importDataFunc(id, index, settings, mappings, ingestPipeline, data); } diff --git a/x-pack/plugins/ml/server/routes/filters.ts b/x-pack/plugins/ml/server/routes/filters.ts index 1f8891c247c67c..2f823d79a8e53f 100644 --- a/x-pack/plugins/ml/server/routes/filters.ts +++ b/x-pack/plugins/ml/server/routes/filters.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'src/core/server'; +import { RequestHandlerContext } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; diff --git a/x-pack/plugins/ml/server/routes/job_service.ts b/x-pack/plugins/ml/server/routes/job_service.ts index bb4530bfb1c6c5..718f9e81603b14 100644 --- a/x-pack/plugins/ml/server/routes/job_service.ts +++ b/x-pack/plugins/ml/server/routes/job_service.ts @@ -6,7 +6,7 @@ import Boom from 'boom'; import { schema } from '@kbn/config-schema'; -import { IScopedClusterClient } from 'src/core/server'; +import { IScopedClusterClient } from 'kibana/server'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; import { diff --git a/x-pack/plugins/ml/server/routes/job_validation.ts b/x-pack/plugins/ml/server/routes/job_validation.ts index 7d5a7a22859779..fd5c8dc7e9a7a0 100644 --- a/x-pack/plugins/ml/server/routes/job_validation.ts +++ b/x-pack/plugins/ml/server/routes/job_validation.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { RequestHandlerContext } from 'src/core/server'; +import { RequestHandlerContext } from 'kibana/server'; import { schema, TypeOf } from '@kbn/config-schema'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; diff --git a/x-pack/plugins/ml/server/routes/modules.ts b/x-pack/plugins/ml/server/routes/modules.ts index a51718acb74254..332d3bfbdeec7b 100644 --- a/x-pack/plugins/ml/server/routes/modules.ts +++ b/x-pack/plugins/ml/server/routes/modules.ts @@ -5,6 +5,7 @@ */ import { schema } from '@kbn/config-schema'; + import { RequestHandlerContext } from 'kibana/server'; import { DatafeedOverride, JobOverride } from '../../../../legacy/plugins/ml/common/types/modules'; import { wrapError } from '../client/error_wrapper'; @@ -13,12 +14,18 @@ import { getModuleIdParamSchema, setupModuleBodySchema } from './schemas/modules import { RouteInitialization } from '../types'; function recognize(context: RequestHandlerContext, indexPatternTitle: string) { - const dr = new DataRecognizer(context); + const dr = new DataRecognizer( + context.ml!.mlClient.callAsCurrentUser, + context.core.savedObjects.client + ); return dr.findMatches(indexPatternTitle); } function getModule(context: RequestHandlerContext, moduleId: string) { - const dr = new DataRecognizer(context); + const dr = new DataRecognizer( + context.ml!.mlClient.callAsCurrentUser, + context.core.savedObjects.client + ); if (moduleId === undefined) { return dr.listModules(); } else { @@ -40,7 +47,10 @@ function saveModuleItems( jobOverrides: JobOverride[], datafeedOverrides: DatafeedOverride[] ) { - const dr = new DataRecognizer(context); + const dr = new DataRecognizer( + context.ml!.mlClient.callAsCurrentUser, + context.core.savedObjects.client + ); return dr.setupModuleItems( moduleId, prefix, @@ -57,7 +67,10 @@ function saveModuleItems( } function dataRecognizerJobsExist(context: RequestHandlerContext, moduleId: string) { - const dr = new DataRecognizer(context); + const dr = new DataRecognizer( + context.ml!.mlClient.callAsCurrentUser, + context.core.savedObjects.client + ); return dr.dataRecognizerJobsExist(moduleId); } diff --git a/x-pack/plugins/ml/server/routes/results_service.ts b/x-pack/plugins/ml/server/routes/results_service.ts index 7a12e5196b9a5d..9849410eaf0d41 100644 --- a/x-pack/plugins/ml/server/routes/results_service.ts +++ b/x-pack/plugins/ml/server/routes/results_service.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { RequestHandlerContext } from 'src/core/server'; +import { RequestHandlerContext } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { wrapError } from '../client/error_wrapper'; import { RouteInitialization } from '../types'; @@ -18,7 +18,7 @@ import { import { resultsServiceProvider } from '../models/results_service'; function getAnomaliesTableData(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context); + const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser); const { jobIds, criteriaFields, @@ -48,24 +48,24 @@ function getAnomaliesTableData(context: RequestHandlerContext, payload: any) { } function getCategoryDefinition(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context); + const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser); return rs.getCategoryDefinition(payload.jobId, payload.categoryId); } function getCategoryExamples(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context); + const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser); const { jobId, categoryIds, maxExamples } = payload; return rs.getCategoryExamples(jobId, categoryIds, maxExamples); } function getMaxAnomalyScore(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context); + const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser); const { jobIds, earliestMs, latestMs } = payload; return rs.getMaxAnomalyScore(jobIds, earliestMs, latestMs); } function getPartitionFieldsValues(context: RequestHandlerContext, payload: any) { - const rs = resultsServiceProvider(context); + const rs = resultsServiceProvider(context.ml!.mlClient.callAsCurrentUser); const { jobId, searchTerm, criteriaFields, earliestMs, latestMs } = payload; return rs.getPartitionFieldsValues(jobId, searchTerm, criteriaFields, earliestMs, latestMs); } diff --git a/x-pack/legacy/plugins/ml/common/types/angular.ts b/x-pack/plugins/ml/server/shared_services/index.ts similarity index 75% rename from x-pack/legacy/plugins/ml/common/types/angular.ts rename to x-pack/plugins/ml/server/shared_services/index.ts index a70ee0d4e379bf..61c24e64ba7386 100644 --- a/x-pack/legacy/plugins/ml/common/types/angular.ts +++ b/x-pack/plugins/ml/server/shared_services/index.ts @@ -4,6 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export interface InjectorService { - get(name: string, caller?: string): T; -} +export { SharedServices, createSharedServices } from './shared_services'; diff --git a/x-pack/plugins/ml/server/shared_services/license_checks.ts b/x-pack/plugins/ml/server/shared_services/license_checks.ts new file mode 100644 index 00000000000000..191124ffa5f3af --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/license_checks.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MlServerLicense } from '../lib/license'; + +export type LicenseCheck = () => void; + +export function licenseChecks( + mlLicense: MlServerLicense +): { isFullLicense: LicenseCheck; isMinimumLicense: LicenseCheck } { + return { + isFullLicense() { + if (mlLicense.isFullLicense() === false) { + throw Error('Platinum, Enterprise or trial license needed'); + } + }, + isMinimumLicense() { + if (mlLicense.isMinimumLicense() === false) { + throw Error('Basic license needed'); + } + }, + }; +} diff --git a/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts b/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts new file mode 100644 index 00000000000000..73696dfdeef868 --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/providers/anomaly_detectors.ts @@ -0,0 +1,29 @@ +/* + * 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 { APICaller } from 'kibana/server'; +import { LicenseCheck } from '../license_checks'; + +export interface AnomalyDetectorsProvider { + anomalyDetectorsProvider( + callAsCurrentUser: APICaller + ): { + jobs(jobId?: string): Promise; + }; +} + +export function getAnomalyDetectorsProvider(isFullLicense: LicenseCheck): AnomalyDetectorsProvider { + return { + anomalyDetectorsProvider(callAsCurrentUser: APICaller) { + return { + jobs(jobId?: string) { + isFullLicense(); + return callAsCurrentUser('ml.jobs', jobId !== undefined ? { jobId } : {}); + }, + }; + }, + }; +} diff --git a/x-pack/plugins/ml/server/shared_services/providers/job_service.ts b/x-pack/plugins/ml/server/shared_services/providers/job_service.ts new file mode 100644 index 00000000000000..8dd3f1ca145823 --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/providers/job_service.ts @@ -0,0 +1,22 @@ +/* + * 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 { APICaller } from 'kibana/server'; +import { LicenseCheck } from '../license_checks'; +import { jobServiceProvider } from '../../models/job_service'; + +export interface JobServiceProvider { + jobServiceProvider(callAsCurrentUser: APICaller): ReturnType; +} + +export function getJobServiceProvider(isFullLicense: LicenseCheck): JobServiceProvider { + return { + jobServiceProvider(callAsCurrentUser: APICaller) { + isFullLicense(); + return jobServiceProvider(callAsCurrentUser); + }, + }; +} diff --git a/x-pack/plugins/ml/server/shared_services/providers/modules.ts b/x-pack/plugins/ml/server/shared_services/providers/modules.ts new file mode 100644 index 00000000000000..e8b7047b9a3f3f --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/providers/modules.ts @@ -0,0 +1,95 @@ +/* + * 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 { APICaller, SavedObjectsClientContract } from 'kibana/server'; +import { LicenseCheck } from '../license_checks'; +import { DataRecognizer, RecognizeResult } from '../../models/data_recognizer'; +import { + Module, + DatafeedOverride, + JobOverride, + DataRecognizerConfigResponse, +} from '../../../../../legacy/plugins/ml/common/types/modules'; + +export interface ModulesProvider { + modulesProvider( + callAsCurrentUser: APICaller, + savedObjectsClient: SavedObjectsClientContract + ): { + recognize(indexPatternTitle: string): Promise; + getModule(moduleId?: string): Promise; + saveModuleItems( + moduleId: string, + prefix: string, + groups: string[], + indexPatternName: string, + query: any, + useDedicatedIndex: boolean, + startDatafeed: boolean, + start: number, + end: number, + jobOverrides: JobOverride[], + datafeedOverrides: DatafeedOverride[] + ): Promise; + }; +} + +export function getModulesProvider(isFullLicense: LicenseCheck): ModulesProvider { + return { + modulesProvider(callAsCurrentUser: APICaller, savedObjectsClient: SavedObjectsClientContract) { + isFullLicense(); + return { + recognize(indexPatternTitle: string) { + const dr = dataRecognizerFactory(callAsCurrentUser, savedObjectsClient); + return dr.findMatches(indexPatternTitle); + }, + getModule(moduleId?: string) { + const dr = dataRecognizerFactory(callAsCurrentUser, savedObjectsClient); + if (moduleId === undefined) { + return dr.listModules(); + } else { + return dr.getModule(moduleId); + } + }, + saveModuleItems( + moduleId: string, + prefix: string, + groups: string[], + indexPatternName: string, + query: any, + useDedicatedIndex: boolean, + startDatafeed: boolean, + start: number, + end: number, + jobOverrides: JobOverride[], + datafeedOverrides: DatafeedOverride[] + ) { + const dr = dataRecognizerFactory(callAsCurrentUser, savedObjectsClient); + return dr.setupModuleItems( + moduleId, + prefix, + groups, + indexPatternName, + query, + useDedicatedIndex, + startDatafeed, + start, + end, + jobOverrides, + datafeedOverrides + ); + }, + }; + }, + }; +} + +function dataRecognizerFactory( + callAsCurrentUser: APICaller, + savedObjectsClient: SavedObjectsClientContract +) { + return new DataRecognizer(callAsCurrentUser, savedObjectsClient); +} diff --git a/x-pack/plugins/ml/server/shared_services/providers/results_service.ts b/x-pack/plugins/ml/server/shared_services/providers/results_service.ts new file mode 100644 index 00000000000000..e321713e27d81f --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/providers/results_service.ts @@ -0,0 +1,22 @@ +/* + * 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 { APICaller } from 'kibana/server'; +import { LicenseCheck } from '../license_checks'; +import { resultsServiceProvider } from '../../models/results_service'; + +export interface ResultsServiceProvider { + resultsServiceProvider(callAsCurrentUser: APICaller): ReturnType; +} + +export function getResultsServiceProvider(isFullLicense: LicenseCheck): ResultsServiceProvider { + return { + resultsServiceProvider(callAsCurrentUser: APICaller) { + isFullLicense(); + return resultsServiceProvider(callAsCurrentUser); + }, + }; +} diff --git a/x-pack/plugins/ml/server/shared_services/providers/system.ts b/x-pack/plugins/ml/server/shared_services/providers/system.ts new file mode 100644 index 00000000000000..db5653dbf7d8e8 --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/providers/system.ts @@ -0,0 +1,74 @@ +/* + * 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 { APICaller } from 'kibana/server'; +import { SearchResponse, SearchParams } from 'elasticsearch'; +import { MlServerLicense } from '../../lib/license'; +import { CloudSetup } from '../../../../cloud/server'; +import { LicenseCheck } from '../license_checks'; +import { spacesUtilsProvider, RequestFacade } from '../../lib/spaces_utils'; +import { SpacesPluginSetup } from '../../../../spaces/server'; +import { privilegesProvider, MlCapabilities } from '../../lib/check_privileges'; +import { MlInfoResponse } from '../../../../../legacy/plugins/ml/common/types/ml_server_info'; +import { ML_RESULTS_INDEX_PATTERN } from '../../../../../legacy/plugins/ml/common/constants/index_patterns'; + +export interface MlSystemProvider { + mlSystemProvider( + callAsCurrentUser: APICaller, + request: RequestFacade + ): { + mlCapabilities(ignoreSpaces?: boolean): Promise; + mlInfo(): Promise; + mlSearch(searchParams: SearchParams): Promise>; + }; +} + +export function getMlSystemProvider( + isMinimumLicense: LicenseCheck, + isFullLicense: LicenseCheck, + mlLicense: MlServerLicense, + spaces: SpacesPluginSetup | undefined, + cloud: CloudSetup | undefined +): MlSystemProvider { + return { + mlSystemProvider(callAsCurrentUser: APICaller, request: RequestFacade) { + return { + mlCapabilities(ignoreSpaces?: boolean) { + isMinimumLicense(); + + const { isMlEnabledInSpace } = + spaces !== undefined + ? spacesUtilsProvider(spaces, request) + : { isMlEnabledInSpace: async () => true }; + + const { getPrivileges } = privilegesProvider( + callAsCurrentUser, + mlLicense, + isMlEnabledInSpace, + ignoreSpaces + ); + return getPrivileges(); + }, + async mlInfo(): Promise { + isMinimumLicense(); + const info = await callAsCurrentUser('ml.info'); + const cloudId = cloud && cloud.cloudId; + return { + ...info, + cloudId, + }; + }, + async mlSearch(searchParams: SearchParams): Promise> { + isFullLicense(); + return callAsCurrentUser('search', { + ...searchParams, + index: ML_RESULTS_INDEX_PATTERN, + }); + }, + }; + }, + }; +} diff --git a/x-pack/plugins/ml/server/shared_services/shared_services.ts b/x-pack/plugins/ml/server/shared_services/shared_services.ts new file mode 100644 index 00000000000000..f08eb5c23b272c --- /dev/null +++ b/x-pack/plugins/ml/server/shared_services/shared_services.ts @@ -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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { MlServerLicense } from '../lib/license'; + +import { SpacesPluginSetup } from '../../../spaces/server'; +import { CloudSetup } from '../../../cloud/server'; +import { licenseChecks } from './license_checks'; +import { MlSystemProvider, getMlSystemProvider } from './providers/system'; +import { JobServiceProvider, getJobServiceProvider } from './providers/job_service'; +import { ModulesProvider, getModulesProvider } from './providers/modules'; +import { ResultsServiceProvider, getResultsServiceProvider } from './providers/results_service'; +import { + AnomalyDetectorsProvider, + getAnomalyDetectorsProvider, +} from './providers/anomaly_detectors'; + +export type SharedServices = JobServiceProvider & + AnomalyDetectorsProvider & + MlSystemProvider & + ModulesProvider & + ResultsServiceProvider; + +export function createSharedServices( + mlLicense: MlServerLicense, + spaces: SpacesPluginSetup | undefined, + cloud: CloudSetup +): SharedServices { + const { isFullLicense, isMinimumLicense } = licenseChecks(mlLicense); + + return { + ...getJobServiceProvider(isFullLicense), + ...getAnomalyDetectorsProvider(isFullLicense), + ...getMlSystemProvider(isMinimumLicense, isFullLicense, mlLicense, spaces, cloud), + ...getModulesProvider(isFullLicense), + ...getResultsServiceProvider(isFullLicense), + }; +} diff --git a/x-pack/plugins/ml/server/types.ts b/x-pack/plugins/ml/server/types.ts index def8a1e5fa649a..ff4d07bd79e42d 100644 --- a/x-pack/plugins/ml/server/types.ts +++ b/x-pack/plugins/ml/server/types.ts @@ -6,7 +6,7 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { HomeServerPluginSetup } from 'src/plugins/home/server'; -import { IRouter } from 'src/core/server'; +import { IRouter } from 'kibana/server'; import { CloudSetup } from '../../cloud/server'; import { SecurityPluginSetup } from '../../security/server'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';