mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ML] NP: migrate server (#58680)
* remove obsolete legacy server deps * licensePreRoutingFactory uses licensing plugin rather than legacy xpack * move schemas to dir in routes * use NP license check method for license check * store license data in plugin for passing to check * create server plugin files in NP plugin dir * remove dependency on legacy xpack plugin * add sample data links first step * move all server dirs from legacy to np dir * fix requiredPlugin spaces name and update import routes * delete unnecessary files and add sample data links * update license and privilege check tests * add routeInit types
This commit is contained in:
parent
facae44f5b
commit
8c3d71b370
339 changed files with 655 additions and 873 deletions
|
@ -26,7 +26,7 @@
|
|||
"xpack.logstash": "legacy/plugins/logstash",
|
||||
"xpack.main": "legacy/plugins/xpack_main",
|
||||
"xpack.maps": "legacy/plugins/maps",
|
||||
"xpack.ml": "legacy/plugins/ml",
|
||||
"xpack.ml": ["plugins/ml", "legacy/plugins/ml"],
|
||||
"xpack.monitoring": "legacy/plugins/monitoring",
|
||||
"xpack.remoteClusters": "plugins/remote_clusters",
|
||||
"xpack.reporting": ["plugins/reporting", "legacy/plugins/reporting"],
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export const API_BASE_PATH = '/api/transform/';
|
||||
export const PLUGIN_ID = 'ml';
|
||||
|
|
|
@ -8,3 +8,5 @@ export enum LICENSE_TYPE {
|
|||
BASIC,
|
||||
FULL, // >= platinum
|
||||
}
|
||||
|
||||
export const VALID_FULL_LICENSE_MODES = ['platinum', 'enterprise', 'trial'];
|
||||
|
|
|
@ -6,23 +6,13 @@
|
|||
|
||||
import { resolve } from 'path';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import KbnServer, { Server } from 'src/legacy/server/kbn_server';
|
||||
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
||||
import { plugin } from './server/new_platform';
|
||||
import { CloudSetup } from '../../../plugins/cloud/server';
|
||||
import { Server } from 'src/legacy/server/kbn_server';
|
||||
import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/utils';
|
||||
import {
|
||||
MlInitializerContext,
|
||||
MlCoreSetup,
|
||||
MlHttpServiceSetup,
|
||||
} from './server/new_platform/plugin';
|
||||
// @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
|
||||
import mappings from './mappings';
|
||||
|
||||
interface MlServer extends Server {
|
||||
addAppLinksToSampleDataset: () => {};
|
||||
}
|
||||
|
||||
export const ml = (kibana: any) => {
|
||||
return new kibana.Plugin({
|
||||
require: ['kibana', 'elasticsearch', 'xpack_main'],
|
||||
|
@ -60,43 +50,8 @@ export const ml = (kibana: any) => {
|
|||
},
|
||||
},
|
||||
|
||||
async init(server: MlServer) {
|
||||
const kbnServer = (server as unknown) as KbnServer;
|
||||
|
||||
const initializerContext = ({
|
||||
legacyConfig: server.config(),
|
||||
logger: {
|
||||
get(...contextParts: string[]) {
|
||||
return kbnServer.newPlatform.coreContext.logger.get('plugins', 'ml', ...contextParts);
|
||||
},
|
||||
},
|
||||
} as unknown) as MlInitializerContext;
|
||||
|
||||
const mlHttpService: MlHttpServiceSetup = {
|
||||
...kbnServer.newPlatform.setup.core.http,
|
||||
route: server.route.bind(server),
|
||||
};
|
||||
|
||||
const core: MlCoreSetup = {
|
||||
injectUiAppVars: server.injectUiAppVars,
|
||||
http: mlHttpService,
|
||||
savedObjects: server.savedObjects,
|
||||
coreSavedObjects: kbnServer.newPlatform.start.core.savedObjects,
|
||||
elasticsearch: kbnServer.newPlatform.setup.core.elasticsearch,
|
||||
};
|
||||
const { usageCollection, cloud, home } = kbnServer.newPlatform.setup.plugins;
|
||||
const plugins = {
|
||||
elasticsearch: server.plugins.elasticsearch, // legacy
|
||||
security: server.newPlatform.setup.plugins.security,
|
||||
xpackMain: server.plugins.xpack_main,
|
||||
spaces: server.plugins.spaces,
|
||||
home,
|
||||
usageCollection: usageCollection as UsageCollectionSetup,
|
||||
cloud: cloud as CloudSetup,
|
||||
ml: this,
|
||||
};
|
||||
|
||||
plugin(initializerContext).setup(core, plugins);
|
||||
async init(server: Server) {
|
||||
mirrorPluginStatus(server.plugins.xpack_main, this);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"id": "ml",
|
||||
"version": "0.0.1",
|
||||
"kibanaVersion": "kibana",
|
||||
"configPath": ["ml"],
|
||||
"server": true,
|
||||
"ui": true
|
||||
}
|
|
@ -82,9 +82,16 @@ function setLicenseExpired(features: any) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Temporary hack for cutting over server to NP
|
||||
function getFeatures() {
|
||||
return xpackInfo.get('features.ml');
|
||||
return {
|
||||
isAvailable: true,
|
||||
showLinks: true,
|
||||
enableLinks: true,
|
||||
licenseType: 1,
|
||||
hasExpired: false,
|
||||
};
|
||||
// return xpackInfo.get('features.ml');
|
||||
}
|
||||
|
||||
function redirectToKibana() {
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch';
|
||||
|
||||
export function callWithInternalUserFactory(elasticsearchPlugin: ElasticsearchPlugin): any;
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { once } from 'lodash';
|
||||
|
||||
const _callWithInternalUser = once(elasticsearchPlugin => {
|
||||
const { callWithInternalUser } = elasticsearchPlugin.getCluster('admin');
|
||||
return callWithInternalUser;
|
||||
});
|
||||
|
||||
export const callWithInternalUserFactory = elasticsearchPlugin => {
|
||||
return (...args) => {
|
||||
return _callWithInternalUser(elasticsearchPlugin)(...args);
|
||||
};
|
||||
};
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { callWithInternalUserFactory } from './call_with_internal_user_factory';
|
||||
|
||||
describe('call_with_internal_user_factory', () => {
|
||||
describe('callWithInternalUserFactory', () => {
|
||||
let elasticsearchPlugin: any;
|
||||
let callWithInternalUser: any;
|
||||
|
||||
beforeEach(() => {
|
||||
callWithInternalUser = jest.fn();
|
||||
elasticsearchPlugin = {
|
||||
getCluster: jest.fn(() => ({ callWithInternalUser })),
|
||||
};
|
||||
});
|
||||
|
||||
it('should use internal user "admin"', () => {
|
||||
const callWithInternalUserInstance = callWithInternalUserFactory(elasticsearchPlugin);
|
||||
callWithInternalUserInstance();
|
||||
|
||||
expect(elasticsearchPlugin.getCluster).toHaveBeenCalledWith('admin');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { once } from 'lodash';
|
||||
import { elasticsearchJsPlugin } from './elasticsearch_ml';
|
||||
|
||||
const callWithRequest = once(elasticsearchPlugin => {
|
||||
const config = { plugins: [elasticsearchJsPlugin] };
|
||||
const cluster = elasticsearchPlugin.createCluster('ml', config);
|
||||
|
||||
return cluster.callWithRequest;
|
||||
});
|
||||
|
||||
export const callWithRequestFactory = (elasticsearchPlugin, request) => {
|
||||
return (...args) => {
|
||||
return callWithRequest(elasticsearchPlugin)(request, ...args);
|
||||
};
|
||||
};
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { isSecurityDisabled } from '../security_utils';
|
||||
|
||||
describe('ML - security utils', () => {
|
||||
function mockXpackMainPluginFactory(isAvailable = true, isEnabled = true) {
|
||||
return {
|
||||
info: {
|
||||
isAvailable: () => isAvailable,
|
||||
feature: () => ({
|
||||
isEnabled: () => isEnabled,
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe('isSecurityDisabled', () => {
|
||||
it('returns not disabled for given mock server object #1', () => {
|
||||
expect(isSecurityDisabled(mockXpackMainPluginFactory())).to.be(false);
|
||||
});
|
||||
|
||||
it('returns not disabled for given mock server object #2', () => {
|
||||
expect(isSecurityDisabled(mockXpackMainPluginFactory(false))).to.be(false);
|
||||
});
|
||||
|
||||
it('returns disabled for given mock server object #3', () => {
|
||||
expect(isSecurityDisabled(mockXpackMainPluginFactory(true, false))).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { XPackMainPlugin } from '../../../xpack_main/server/xpack_main';
|
||||
|
||||
export function isSecurityDisabled(xpackMainPlugin: XPackMainPlugin): boolean;
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Contains utility functions related to x-pack security.
|
||||
*/
|
||||
|
||||
export function isSecurityDisabled(xpackMainPlugin) {
|
||||
const xpackInfo = xpackMainPlugin && xpackMainPlugin.info;
|
||||
// we assume that `xpack.isAvailable()` always returns `true` because we're inside x-pack
|
||||
// if for whatever reason it returns `false`, `isSecurityDisabled()` would also return `false`
|
||||
// which would result in follow-up behavior assuming security is enabled. This is intentional,
|
||||
// because it results in more defensive behavior.
|
||||
const securityInfo = xpackInfo && xpackInfo.isAvailable() && xpackInfo.feature('security');
|
||||
return securityInfo && securityInfo.isEnabled() === false;
|
||||
}
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ServerRoute } from 'hapi';
|
||||
import { KibanaConfig, SavedObjectsLegacyService } from 'src/legacy/server/kbn_server';
|
||||
import {
|
||||
Logger,
|
||||
PluginInitializerContext,
|
||||
CoreSetup,
|
||||
IRouter,
|
||||
IScopedClusterClient,
|
||||
SavedObjectsServiceStart,
|
||||
} from 'src/core/server';
|
||||
import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch';
|
||||
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
||||
import { ElasticsearchServiceSetup } from 'src/core/server';
|
||||
import { CloudSetup } from '../../../../../plugins/cloud/server';
|
||||
import { XPackMainPlugin } from '../../../xpack_main/server/xpack_main';
|
||||
import { addLinksToSampleDatasets } from '../lib/sample_data_sets';
|
||||
import { checkLicense } from '../lib/check_license';
|
||||
// @ts-ignore: could not find declaration file for module
|
||||
import { mirrorPluginStatus } from '../../../../server/lib/mirror_plugin_status';
|
||||
import { LICENSE_TYPE } from '../../common/constants/license';
|
||||
import { annotationRoutes } from '../routes/annotations';
|
||||
import { jobRoutes } from '../routes/anomaly_detectors';
|
||||
import { dataFeedRoutes } from '../routes/datafeeds';
|
||||
import { indicesRoutes } from '../routes/indices';
|
||||
import { jobValidationRoutes } from '../routes/job_validation';
|
||||
import { makeMlUsageCollector } from '../lib/ml_telemetry';
|
||||
import { notificationRoutes } from '../routes/notification_settings';
|
||||
import { systemRoutes } from '../routes/system';
|
||||
import { dataFrameAnalyticsRoutes } from '../routes/data_frame_analytics';
|
||||
import { dataRecognizer } from '../routes/modules';
|
||||
import { dataVisualizerRoutes } from '../routes/data_visualizer';
|
||||
import { calendars } from '../routes/calendars';
|
||||
// @ts-ignore: could not find declaration file for module
|
||||
import { fieldsService } from '../routes/fields_service';
|
||||
import { filtersRoutes } from '../routes/filters';
|
||||
import { resultsServiceRoutes } from '../routes/results_service';
|
||||
import { jobServiceRoutes } from '../routes/job_service';
|
||||
import { jobAuditMessagesRoutes } from '../routes/job_audit_messages';
|
||||
import { fileDataVisualizerRoutes } from '../routes/file_data_visualizer';
|
||||
import { initMlServerLog, LogInitialization } from '../client/log';
|
||||
import { HomeServerPluginSetup } from '../../../../../../src/plugins/home/server';
|
||||
// @ts-ignore: could not find declaration file for module
|
||||
import { elasticsearchJsPlugin } from '../client/elasticsearch_ml';
|
||||
|
||||
export const PLUGIN_ID = 'ml';
|
||||
|
||||
type CoreHttpSetup = CoreSetup['http'];
|
||||
export interface MlHttpServiceSetup extends CoreHttpSetup {
|
||||
route(route: ServerRoute | ServerRoute[]): void;
|
||||
}
|
||||
|
||||
export interface MlXpackMainPlugin extends XPackMainPlugin {
|
||||
status?: any;
|
||||
}
|
||||
|
||||
export interface MlCoreSetup {
|
||||
injectUiAppVars: (id: string, callback: () => {}) => any;
|
||||
http: MlHttpServiceSetup;
|
||||
savedObjects: SavedObjectsLegacyService;
|
||||
coreSavedObjects: SavedObjectsServiceStart;
|
||||
elasticsearch: ElasticsearchServiceSetup;
|
||||
}
|
||||
export interface MlInitializerContext extends PluginInitializerContext {
|
||||
legacyConfig: KibanaConfig;
|
||||
log: Logger;
|
||||
}
|
||||
export interface PluginsSetup {
|
||||
elasticsearch: ElasticsearchPlugin;
|
||||
xpackMain: MlXpackMainPlugin;
|
||||
security: any;
|
||||
spaces: any;
|
||||
usageCollection?: UsageCollectionSetup;
|
||||
cloud?: CloudSetup;
|
||||
home?: HomeServerPluginSetup;
|
||||
// TODO: this is temporary for `mirrorPluginStatus`
|
||||
ml: any;
|
||||
}
|
||||
|
||||
export interface RouteInitialization {
|
||||
commonRouteConfig: any;
|
||||
config?: any;
|
||||
elasticsearchPlugin: ElasticsearchPlugin;
|
||||
elasticsearchService: ElasticsearchServiceSetup;
|
||||
route(route: ServerRoute | ServerRoute[]): void;
|
||||
router: IRouter;
|
||||
xpackMainPlugin: MlXpackMainPlugin;
|
||||
savedObjects?: SavedObjectsServiceStart;
|
||||
spacesPlugin: any;
|
||||
securityPlugin: any;
|
||||
cloud?: CloudSetup;
|
||||
}
|
||||
|
||||
declare module 'kibana/server' {
|
||||
interface RequestHandlerContext {
|
||||
ml?: {
|
||||
mlClient: IScopedClusterClient;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class Plugin {
|
||||
private readonly pluginId: string = PLUGIN_ID;
|
||||
private config: any;
|
||||
private log: Logger;
|
||||
|
||||
constructor(initializerContext: MlInitializerContext) {
|
||||
this.config = initializerContext.legacyConfig;
|
||||
this.log = initializerContext.logger.get();
|
||||
}
|
||||
|
||||
public setup(core: MlCoreSetup, plugins: PluginsSetup) {
|
||||
const xpackMainPlugin: MlXpackMainPlugin = plugins.xpackMain;
|
||||
const { http, coreSavedObjects } = core;
|
||||
const pluginId = this.pluginId;
|
||||
|
||||
mirrorPluginStatus(xpackMainPlugin, plugins.ml);
|
||||
xpackMainPlugin.status.once('green', () => {
|
||||
// Register a function that is called whenever the xpack info changes,
|
||||
// to re-compute the license check results for this plugin
|
||||
const mlFeature = xpackMainPlugin.info.feature(pluginId);
|
||||
mlFeature.registerLicenseCheckResultsGenerator(checkLicense);
|
||||
|
||||
// Add links to the Kibana sample data sets if ml is enabled
|
||||
// and there is a full license (trial or platinum).
|
||||
if (mlFeature.isEnabled() === true && plugins.home) {
|
||||
const licenseCheckResults = mlFeature.getLicenseCheckResults();
|
||||
if (licenseCheckResults.licenseType === LICENSE_TYPE.FULL) {
|
||||
addLinksToSampleDatasets({
|
||||
addAppLinksToSampleDataset: plugins.home.sampleData.addAppLinksToSampleDataset,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
xpackMainPlugin.registerFeature({
|
||||
id: 'ml',
|
||||
name: i18n.translate('xpack.ml.featureRegistry.mlFeatureName', {
|
||||
defaultMessage: 'Machine Learning',
|
||||
}),
|
||||
icon: 'machineLearningApp',
|
||||
navLinkId: 'ml',
|
||||
app: ['ml', 'kibana'],
|
||||
catalogue: ['ml'],
|
||||
privileges: {},
|
||||
reserved: {
|
||||
privilege: {
|
||||
savedObject: {
|
||||
all: [],
|
||||
read: [],
|
||||
},
|
||||
ui: [],
|
||||
},
|
||||
description: i18n.translate('xpack.ml.feature.reserved.description', {
|
||||
defaultMessage:
|
||||
'To grant users access, you should also assign either the machine_learning_user or machine_learning_admin role.',
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
// Add server routes and initialize the plugin here
|
||||
const commonRouteConfig = {
|
||||
pre: [
|
||||
function forbidApiAccess() {
|
||||
const licenseCheckResults = xpackMainPlugin.info
|
||||
.feature(pluginId)
|
||||
.getLicenseCheckResults();
|
||||
if (licenseCheckResults.isAvailable) {
|
||||
return null;
|
||||
} else {
|
||||
throw Boom.forbidden(licenseCheckResults.message);
|
||||
}
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Can access via new platform router's handler function 'context' parameter - context.ml.mlClient
|
||||
const mlClient = core.elasticsearch.createClient('ml', { plugins: [elasticsearchJsPlugin] });
|
||||
http.registerRouteHandlerContext('ml', (context, request) => {
|
||||
return {
|
||||
mlClient: mlClient.asScoped(request),
|
||||
};
|
||||
});
|
||||
|
||||
const routeInitializationDeps: RouteInitialization = {
|
||||
commonRouteConfig,
|
||||
route: http.route,
|
||||
router: http.createRouter(),
|
||||
elasticsearchPlugin: plugins.elasticsearch,
|
||||
elasticsearchService: core.elasticsearch,
|
||||
xpackMainPlugin: plugins.xpackMain,
|
||||
spacesPlugin: plugins.spaces,
|
||||
securityPlugin: plugins.security,
|
||||
};
|
||||
|
||||
const extendedRouteInitializationDeps: RouteInitialization = {
|
||||
...routeInitializationDeps,
|
||||
config: this.config,
|
||||
savedObjects: coreSavedObjects,
|
||||
spacesPlugin: plugins.spaces,
|
||||
cloud: plugins.cloud,
|
||||
};
|
||||
|
||||
const logInitializationDeps: LogInitialization = {
|
||||
log: this.log,
|
||||
};
|
||||
|
||||
annotationRoutes(routeInitializationDeps);
|
||||
jobRoutes(routeInitializationDeps);
|
||||
dataFeedRoutes(routeInitializationDeps);
|
||||
dataFrameAnalyticsRoutes(routeInitializationDeps);
|
||||
indicesRoutes(routeInitializationDeps);
|
||||
jobValidationRoutes(extendedRouteInitializationDeps);
|
||||
notificationRoutes(routeInitializationDeps);
|
||||
systemRoutes(extendedRouteInitializationDeps);
|
||||
dataRecognizer(extendedRouteInitializationDeps);
|
||||
dataVisualizerRoutes(routeInitializationDeps);
|
||||
calendars(routeInitializationDeps);
|
||||
fieldsService(routeInitializationDeps);
|
||||
filtersRoutes(routeInitializationDeps);
|
||||
resultsServiceRoutes(routeInitializationDeps);
|
||||
jobServiceRoutes(routeInitializationDeps);
|
||||
jobAuditMessagesRoutes(routeInitializationDeps);
|
||||
fileDataVisualizerRoutes(extendedRouteInitializationDeps);
|
||||
|
||||
initMlServerLog(logInitializationDeps);
|
||||
makeMlUsageCollector(plugins.usageCollection, coreSavedObjects);
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
}
|
9
x-pack/plugins/ml/kibana.json
Normal file
9
x-pack/plugins/ml/kibana.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"id": "ml",
|
||||
"version": "0.0.1",
|
||||
"kibanaVersion": "kibana",
|
||||
"configPath": ["ml"],
|
||||
"requiredPlugins": ["cloud", "features", "home", "licensing", "security", "spaces", "usageCollection"],
|
||||
"server": true,
|
||||
"ui": false
|
||||
}
|
|
@ -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 '../../../../../src/core/server';
|
||||
|
||||
export interface LogInitialization {
|
||||
log: Logger;
|
|
@ -4,8 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { Plugin, MlInitializerContext } from './plugin';
|
||||
import { PluginInitializerContext } from 'kibana/server';
|
||||
import { MlServerPlugin } from './plugin';
|
||||
|
||||
export function plugin(initializerContext: MlInitializerContext) {
|
||||
return new Plugin(initializerContext);
|
||||
}
|
||||
export const plugin = (ctx: PluginInitializerContext) => new MlServerPlugin(ctx);
|
|
@ -10,7 +10,7 @@ import {
|
|||
ML_ANNOTATIONS_INDEX_ALIAS_READ,
|
||||
ML_ANNOTATIONS_INDEX_ALIAS_WRITE,
|
||||
ML_ANNOTATIONS_INDEX_PATTERN,
|
||||
} from '../../../common/constants/index_patterns';
|
||||
} from '../../../../../legacy/plugins/ml/common/constants/index_patterns';
|
||||
|
||||
// Annotations Feature is available if:
|
||||
// - ML_ANNOTATIONS_INDEX_PATTERN index is present
|
|
@ -7,12 +7,12 @@
|
|||
import expect from '@kbn/expect';
|
||||
import sinon from 'sinon';
|
||||
import { set } from 'lodash';
|
||||
import { XPackInfo } from '../../../../xpack_main/server/lib/xpack_info';
|
||||
import { LicenseCheckResult } from '../../types';
|
||||
import { checkLicense } from './check_license';
|
||||
|
||||
describe('check_license', () => {
|
||||
let mockLicenseInfo: XPackInfo;
|
||||
beforeEach(() => (mockLicenseInfo = {} as XPackInfo));
|
||||
let mockLicenseInfo: LicenseCheckResult;
|
||||
beforeEach(() => (mockLicenseInfo = {} as LicenseCheckResult));
|
||||
|
||||
describe('license information is undefined', () => {
|
||||
it('should set isAvailable to false', () => {
|
||||
|
@ -33,7 +33,9 @@ describe('check_license', () => {
|
|||
});
|
||||
|
||||
describe('license information is not available', () => {
|
||||
beforeEach(() => (mockLicenseInfo.isAvailable = () => false));
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.isAvailable = false;
|
||||
});
|
||||
|
||||
it('should set isAvailable to false', () => {
|
||||
expect(checkLicense(mockLicenseInfo).isAvailable).to.be(false);
|
||||
|
@ -54,8 +56,8 @@ describe('check_license', () => {
|
|||
|
||||
describe('license information is available', () => {
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.isAvailable = () => true;
|
||||
set(mockLicenseInfo, 'license.getType', () => 'basic');
|
||||
mockLicenseInfo.isAvailable = true;
|
||||
mockLicenseInfo.type = 'basic';
|
||||
});
|
||||
|
||||
describe('& ML is disabled in Elasticsearch', () => {
|
||||
|
@ -66,7 +68,7 @@ describe('check_license', () => {
|
|||
sinon
|
||||
.stub()
|
||||
.withArgs('ml')
|
||||
.returns({ isEnabled: () => false })
|
||||
.returns({ isEnabled: false })
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -89,21 +91,17 @@ describe('check_license', () => {
|
|||
|
||||
describe('& ML is enabled in Elasticsearch', () => {
|
||||
beforeEach(() => {
|
||||
set(
|
||||
mockLicenseInfo,
|
||||
'feature',
|
||||
sinon
|
||||
.stub()
|
||||
.withArgs('ml')
|
||||
.returns({ isEnabled: () => true })
|
||||
);
|
||||
mockLicenseInfo.isEnabled = true;
|
||||
});
|
||||
|
||||
describe('& license is >= platinum', () => {
|
||||
beforeEach(() => set(mockLicenseInfo, 'license.isOneOf', () => true));
|
||||
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.type = 'platinum';
|
||||
});
|
||||
describe('& license is active', () => {
|
||||
beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => true));
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.isActive = true;
|
||||
});
|
||||
|
||||
it('should set isAvailable to true', () => {
|
||||
expect(checkLicense(mockLicenseInfo).isAvailable).to.be(true);
|
||||
|
@ -123,7 +121,9 @@ describe('check_license', () => {
|
|||
});
|
||||
|
||||
describe('& license is expired', () => {
|
||||
beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => false));
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.isActive = false;
|
||||
});
|
||||
|
||||
it('should set isAvailable to true', () => {
|
||||
expect(checkLicense(mockLicenseInfo).isAvailable).to.be(true);
|
||||
|
@ -144,10 +144,14 @@ describe('check_license', () => {
|
|||
});
|
||||
|
||||
describe('& license is basic', () => {
|
||||
beforeEach(() => set(mockLicenseInfo, 'license.isOneOf', () => false));
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.type = 'basic';
|
||||
});
|
||||
|
||||
describe('& license is active', () => {
|
||||
beforeEach(() => set(mockLicenseInfo, 'license.isActive', () => true));
|
||||
beforeEach(() => {
|
||||
mockLicenseInfo.isActive = true;
|
||||
});
|
||||
|
||||
it('should set isAvailable to true', () => {
|
||||
expect(checkLicense(mockLicenseInfo).isAvailable).to.be(true);
|
|
@ -5,8 +5,11 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { LICENSE_TYPE } from '../../../common/constants/license';
|
||||
import { XPackInfo } from '../../../../../../legacy/plugins/xpack_main/server/lib/xpack_info';
|
||||
import {
|
||||
LICENSE_TYPE,
|
||||
VALID_FULL_LICENSE_MODES,
|
||||
} from '../../../../../legacy/plugins/ml/common/constants/license';
|
||||
import { LicenseCheckResult } from '../../types';
|
||||
|
||||
interface Response {
|
||||
isAvailable: boolean;
|
||||
|
@ -17,10 +20,10 @@ interface Response {
|
|||
message?: string;
|
||||
}
|
||||
|
||||
export function checkLicense(xpackLicenseInfo: XPackInfo): Response {
|
||||
export function checkLicense(licenseCheckResult: LicenseCheckResult): Response {
|
||||
// If, for some reason, we cannot get the license information
|
||||
// from Elasticsearch, assume worst case and disable the Machine Learning UI
|
||||
if (!xpackLicenseInfo || !xpackLicenseInfo.isAvailable()) {
|
||||
if (licenseCheckResult === undefined || !licenseCheckResult.isAvailable) {
|
||||
return {
|
||||
isAvailable: false,
|
||||
showLinks: true,
|
||||
|
@ -35,7 +38,7 @@ export function checkLicense(xpackLicenseInfo: XPackInfo): Response {
|
|||
};
|
||||
}
|
||||
|
||||
const featureEnabled = xpackLicenseInfo.feature('ml').isEnabled();
|
||||
const featureEnabled = licenseCheckResult.isEnabled;
|
||||
if (!featureEnabled) {
|
||||
return {
|
||||
isAvailable: false,
|
||||
|
@ -47,12 +50,11 @@ export function checkLicense(xpackLicenseInfo: XPackInfo): Response {
|
|||
};
|
||||
}
|
||||
|
||||
const VALID_FULL_LICENSE_MODES = ['platinum', 'enterprise', 'trial'];
|
||||
|
||||
const isLicenseModeValid = xpackLicenseInfo.license.isOneOf(VALID_FULL_LICENSE_MODES);
|
||||
const isLicenseModeValid =
|
||||
licenseCheckResult.type && VALID_FULL_LICENSE_MODES.includes(licenseCheckResult.type);
|
||||
const licenseType = isLicenseModeValid === true ? LICENSE_TYPE.FULL : LICENSE_TYPE.BASIC;
|
||||
const isLicenseActive = xpackLicenseInfo.license.isActive();
|
||||
const licenseTypeName = xpackLicenseInfo.license.getType();
|
||||
const isLicenseActive = licenseCheckResult.isActive;
|
||||
const licenseTypeName = licenseCheckResult.type;
|
||||
|
||||
// Platinum or trial license is valid but not active, i.e. expired
|
||||
if (licenseType === LICENSE_TYPE.FULL && isLicenseActive === false) {
|
|
@ -8,81 +8,29 @@ import { callWithRequestProvider } from './__mocks__/call_with_request';
|
|||
import { privilegesProvider } from './check_privileges';
|
||||
import { mlPrivileges } from './privileges';
|
||||
|
||||
const xpackMainPluginWithSecurity = {
|
||||
info: {
|
||||
isAvailable: () => true,
|
||||
feature: (f: string) => {
|
||||
switch (f) {
|
||||
case 'ml':
|
||||
return { isEnabled: () => true };
|
||||
case 'security':
|
||||
return { isEnabled: () => true };
|
||||
}
|
||||
},
|
||||
license: {
|
||||
isOneOf: () => true,
|
||||
isActive: () => true,
|
||||
getType: () => 'platinum',
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const licenseCheckResultWithSecurity = {
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
isSecurityDisabled: false,
|
||||
type: 'platinum',
|
||||
isActive: true,
|
||||
};
|
||||
|
||||
const xpackMainPluginWithOutSecurity = {
|
||||
info: {
|
||||
isAvailable: () => true,
|
||||
feature: (f: string) => {
|
||||
switch (f) {
|
||||
case 'ml':
|
||||
return { isEnabled: () => true };
|
||||
case 'security':
|
||||
return { isEnabled: () => false };
|
||||
}
|
||||
},
|
||||
license: {
|
||||
isOneOf: () => true,
|
||||
isActive: () => true,
|
||||
getType: () => 'platinum',
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const licenseCheckResultWithOutSecurity = {
|
||||
...licenseCheckResultWithSecurity,
|
||||
isSecurityDisabled: true,
|
||||
};
|
||||
|
||||
const xpackMainPluginWithOutSecurityBasicLicense = {
|
||||
info: {
|
||||
isAvailable: () => true,
|
||||
feature: (f: string) => {
|
||||
switch (f) {
|
||||
case 'ml':
|
||||
return { isEnabled: () => true };
|
||||
case 'security':
|
||||
return { isEnabled: () => false };
|
||||
}
|
||||
},
|
||||
license: {
|
||||
isOneOf: () => false,
|
||||
isActive: () => true,
|
||||
getType: () => 'basic',
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const licenseCheckResultWithOutSecurityBasicLicense = {
|
||||
...licenseCheckResultWithSecurity,
|
||||
isSecurityDisabled: true,
|
||||
type: 'basic',
|
||||
};
|
||||
|
||||
const xpackMainPluginWithSecurityBasicLicense = {
|
||||
info: {
|
||||
isAvailable: () => true,
|
||||
feature: (f: string) => {
|
||||
switch (f) {
|
||||
case 'ml':
|
||||
return { isEnabled: () => true };
|
||||
case 'security':
|
||||
return { isEnabled: () => true };
|
||||
}
|
||||
},
|
||||
license: {
|
||||
isOneOf: () => false,
|
||||
isActive: () => true,
|
||||
getType: () => 'basic',
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
const licenseCheckResultWithSecurityBasicLicense = {
|
||||
...licenseCheckResultWithSecurity,
|
||||
type: 'basic',
|
||||
};
|
||||
|
||||
const mlIsEnabled = async () => true;
|
||||
const mlIsNotEnabled = async () => false;
|
||||
|
@ -99,7 +47,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('partialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurity,
|
||||
licenseCheckResultWithSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities } = await getPrivileges();
|
||||
|
@ -114,7 +62,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('partialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurity,
|
||||
licenseCheckResultWithSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -149,7 +97,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('fullPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurity,
|
||||
licenseCheckResultWithSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -184,7 +132,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('upgradeWithFullPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurity,
|
||||
licenseCheckResultWithSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -219,7 +167,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('upgradeWithPartialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurity,
|
||||
licenseCheckResultWithSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -254,7 +202,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('partialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurityBasicLicense,
|
||||
licenseCheckResultWithSecurityBasicLicense,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -289,7 +237,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('fullPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurityBasicLicense,
|
||||
licenseCheckResultWithSecurityBasicLicense,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -324,7 +272,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('fullPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithSecurity,
|
||||
licenseCheckResultWithSecurity,
|
||||
mlIsNotEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -361,7 +309,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('partialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithOutSecurity,
|
||||
licenseCheckResultWithOutSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -396,7 +344,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('upgradeWithFullPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithOutSecurity,
|
||||
licenseCheckResultWithOutSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -431,7 +379,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('upgradeWithPartialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithOutSecurity,
|
||||
licenseCheckResultWithOutSecurity,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -466,7 +414,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('partialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithOutSecurityBasicLicense,
|
||||
licenseCheckResultWithOutSecurityBasicLicense,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -501,7 +449,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('fullPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithOutSecurityBasicLicense,
|
||||
licenseCheckResultWithOutSecurityBasicLicense,
|
||||
mlIsEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
||||
|
@ -536,7 +484,7 @@ describe('check_privileges', () => {
|
|||
const callWithRequest = callWithRequestProvider('partialPrivileges');
|
||||
const { getPrivileges } = privilegesProvider(
|
||||
callWithRequest,
|
||||
xpackMainPluginWithOutSecurity,
|
||||
licenseCheckResultWithOutSecurity,
|
||||
mlIsNotEnabled
|
||||
);
|
||||
const { capabilities, upgradeInProgress, mlFeatureEnabledInSpace } = await getPrivileges();
|
|
@ -5,12 +5,14 @@
|
|||
*/
|
||||
|
||||
import { IScopedClusterClient } from 'kibana/server';
|
||||
import { Privileges, getDefaultPrivileges } from '../../../common/types/privileges';
|
||||
import { XPackMainPlugin } from '../../../../xpack_main/server/xpack_main';
|
||||
import { isSecurityDisabled } from '../../lib/security_utils';
|
||||
import {
|
||||
Privileges,
|
||||
getDefaultPrivileges,
|
||||
} from '../../../../../legacy/plugins/ml/common/types/privileges';
|
||||
import { upgradeCheckProvider } from './upgrade';
|
||||
import { checkLicense } from '../check_license';
|
||||
import { LICENSE_TYPE } from '../../../common/constants/license';
|
||||
import { LICENSE_TYPE } from '../../../../../legacy/plugins/ml/common/constants/license';
|
||||
import { LicenseCheckResult } from '../../types';
|
||||
|
||||
import { mlPrivileges } from './privileges';
|
||||
|
||||
|
@ -25,7 +27,7 @@ interface Response {
|
|||
|
||||
export function privilegesProvider(
|
||||
callAsCurrentUser: IScopedClusterClient['callAsCurrentUser'],
|
||||
xpackMainPlugin: XPackMainPlugin,
|
||||
licenseCheckResult: LicenseCheckResult,
|
||||
isMlEnabledInSpace: () => Promise<boolean>,
|
||||
ignoreSpaces: boolean = false
|
||||
) {
|
||||
|
@ -35,8 +37,8 @@ export function privilegesProvider(
|
|||
const privileges = getDefaultPrivileges();
|
||||
|
||||
const upgradeInProgress = await isUpgradeInProgress();
|
||||
const securityDisabled = isSecurityDisabled(xpackMainPlugin);
|
||||
const license = checkLicense(xpackMainPlugin.info);
|
||||
const securityDisabled = licenseCheckResult.isSecurityDisabled;
|
||||
const license = checkLicense(licenseCheckResult);
|
||||
const isPlatinumOrTrialLicense = license.licenseType === LICENSE_TYPE.FULL;
|
||||
const mlFeatureEnabledInSpace = await isMlEnabledInSpace();
|
||||
|
|
@ -55,10 +55,9 @@ describe('ml_telemetry', () => {
|
|||
});
|
||||
|
||||
describe('incrementFileDataVisualizerIndexCreationCount', () => {
|
||||
let savedObjects: any;
|
||||
let internalRepository: any;
|
||||
let savedObjectsClient: any;
|
||||
|
||||
function createInternalRepositoryInstance(
|
||||
function createSavedObjectsClientInstance(
|
||||
telemetryEnabled?: boolean,
|
||||
indexCreationCount?: number
|
||||
) {
|
||||
|
@ -93,42 +92,39 @@ describe('ml_telemetry', () => {
|
|||
}
|
||||
|
||||
function mockInit(telemetryEnabled?: boolean, indexCreationCount?: number): void {
|
||||
internalRepository = createInternalRepositoryInstance(telemetryEnabled, indexCreationCount);
|
||||
savedObjects = {
|
||||
createInternalRepository: jest.fn(() => internalRepository),
|
||||
};
|
||||
savedObjectsClient = createSavedObjectsClientInstance(telemetryEnabled, indexCreationCount);
|
||||
}
|
||||
|
||||
it('should not increment if telemetry status cannot be determined', async () => {
|
||||
mockInit();
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjects);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient);
|
||||
|
||||
expect(internalRepository.create.mock.calls).toHaveLength(0);
|
||||
expect(savedObjectsClient.create.mock.calls).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should not increment if telemetry status is disabled', async () => {
|
||||
mockInit(false);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjects);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient);
|
||||
|
||||
expect(internalRepository.create.mock.calls).toHaveLength(0);
|
||||
expect(savedObjectsClient.create.mock.calls).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should initialize index_creation_count with 1', async () => {
|
||||
mockInit(true);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjects);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient);
|
||||
|
||||
expect(internalRepository.create.mock.calls[0][0]).toBe('ml-telemetry');
|
||||
expect(internalRepository.create.mock.calls[0][1]).toEqual({
|
||||
expect(savedObjectsClient.create.mock.calls[0][0]).toBe('ml-telemetry');
|
||||
expect(savedObjectsClient.create.mock.calls[0][1]).toEqual({
|
||||
file_data_visualizer: { index_creation_count: 1 },
|
||||
});
|
||||
});
|
||||
|
||||
it('should increment index_creation_count to 2', async () => {
|
||||
mockInit(true, 1);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjects);
|
||||
await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient);
|
||||
|
||||
expect(internalRepository.create.mock.calls[0][0]).toBe('ml-telemetry');
|
||||
expect(internalRepository.create.mock.calls[0][1]).toEqual({
|
||||
expect(savedObjectsClient.create.mock.calls[0][0]).toBe('ml-telemetry');
|
||||
expect(savedObjectsClient.create.mock.calls[0][1]).toEqual({
|
||||
file_data_visualizer: { index_creation_count: 2 },
|
||||
});
|
||||
});
|
|
@ -4,11 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import {
|
||||
SavedObjectAttributes,
|
||||
SavedObjectsServiceStart,
|
||||
ISavedObjectsRepository,
|
||||
} from 'src/core/server';
|
||||
import { SavedObjectAttributes, SavedObjectsClientContract } from 'src/core/server';
|
||||
|
||||
export interface MlTelemetry extends SavedObjectAttributes {
|
||||
file_data_visualizer: {
|
||||
|
@ -31,21 +27,20 @@ export function createMlTelemetry(count: number = 0): MlTelemetry {
|
|||
}
|
||||
// savedObjects
|
||||
export function storeMlTelemetry(
|
||||
internalRepository: ISavedObjectsRepository,
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
mlTelemetry: MlTelemetry
|
||||
): void {
|
||||
internalRepository.create('ml-telemetry', mlTelemetry, {
|
||||
savedObjectsClient.create('ml-telemetry', mlTelemetry, {
|
||||
id: ML_TELEMETRY_DOC_ID,
|
||||
overwrite: true,
|
||||
});
|
||||
}
|
||||
|
||||
export async function incrementFileDataVisualizerIndexCreationCount(
|
||||
savedObjects: SavedObjectsServiceStart
|
||||
savedObjectsClient: SavedObjectsClientContract
|
||||
): Promise<void> {
|
||||
const internalRepository = await savedObjects.createInternalRepository();
|
||||
try {
|
||||
const { attributes } = await internalRepository.get('telemetry', 'telemetry');
|
||||
const { attributes } = await savedObjectsClient.get('telemetry', 'telemetry');
|
||||
|
||||
if (attributes.enabled === false) {
|
||||
return;
|
||||
|
@ -59,7 +54,7 @@ export async function incrementFileDataVisualizerIndexCreationCount(
|
|||
let indicesCount = 1;
|
||||
|
||||
try {
|
||||
const { attributes } = (await internalRepository.get(
|
||||
const { attributes } = (await savedObjectsClient.get(
|
||||
'ml-telemetry',
|
||||
ML_TELEMETRY_DOC_ID
|
||||
)) as MlTelemetrySavedObject;
|
||||
|
@ -69,5 +64,5 @@ export async function incrementFileDataVisualizerIndexCreationCount(
|
|||
}
|
||||
|
||||
const mlTelemetry = createMlTelemetry(indicesCount);
|
||||
storeMlTelemetry(internalRepository, mlTelemetry);
|
||||
storeMlTelemetry(savedObjectsClient, mlTelemetry);
|
||||
}
|
|
@ -5,20 +5,19 @@
|
|||
*/
|
||||
|
||||
import { Request } from 'hapi';
|
||||
import { Space } from '../../../../../plugins/spaces/server';
|
||||
import { LegacySpacesPlugin } from '../../../spaces';
|
||||
import { Space, SpacesPluginSetup } from '../../../spaces/server';
|
||||
|
||||
interface GetActiveSpaceResponse {
|
||||
valid: boolean;
|
||||
space?: Space;
|
||||
}
|
||||
|
||||
export function spacesUtilsProvider(spacesPlugin: LegacySpacesPlugin, request: Request) {
|
||||
export function spacesUtilsProvider(spacesPlugin: SpacesPluginSetup, request: Request) {
|
||||
async function activeSpace(): Promise<GetActiveSpaceResponse> {
|
||||
try {
|
||||
return {
|
||||
valid: true,
|
||||
space: await spacesPlugin.getActiveSpace(request),
|
||||
space: await spacesPlugin.spacesService.getActiveSpace(request),
|
||||
};
|
||||
} catch (e) {
|
||||
return {
|
|
@ -8,9 +8,12 @@ import getAnnotationsRequestMock from './__mocks__/get_annotations_request.json'
|
|||
import getAnnotationsResponseMock from './__mocks__/get_annotations_response.json';
|
||||
import { RequestHandlerContext } from 'src/core/server';
|
||||
|
||||
import { ANNOTATION_TYPE } from '../../../common/constants/annotations';
|
||||
import { ML_ANNOTATIONS_INDEX_ALIAS_WRITE } from '../../../common/constants/index_patterns';
|
||||
import { Annotation, isAnnotations } from '../../../common/types/annotations';
|
||||
import { ANNOTATION_TYPE } from '../../../../../legacy/plugins/ml/common/constants/annotations';
|
||||
import { ML_ANNOTATIONS_INDEX_ALIAS_WRITE } from '../../../../../legacy/plugins/ml/common/constants/index_patterns';
|
||||
import {
|
||||
Annotation,
|
||||
isAnnotations,
|
||||
} from '../../../../../legacy/plugins/ml/common/types/annotations';
|
||||
|
||||
import { DeleteParams, GetResponse, IndexAnnotationArgs } from './annotation';
|
||||
import { annotationServiceProvider } from './index';
|
|
@ -8,18 +8,18 @@ import Boom from 'boom';
|
|||
import _ from 'lodash';
|
||||
import { RequestHandlerContext } from 'src/core/server';
|
||||
|
||||
import { ANNOTATION_TYPE } from '../../../common/constants/annotations';
|
||||
import { ANNOTATION_TYPE } from '../../../../../legacy/plugins/ml/common/constants/annotations';
|
||||
import {
|
||||
ML_ANNOTATIONS_INDEX_ALIAS_READ,
|
||||
ML_ANNOTATIONS_INDEX_ALIAS_WRITE,
|
||||
} from '../../../common/constants/index_patterns';
|
||||
} from '../../../../../legacy/plugins/ml/common/constants/index_patterns';
|
||||
|
||||
import {
|
||||
Annotation,
|
||||
Annotations,
|
||||
isAnnotation,
|
||||
isAnnotations,
|
||||
} from '../../../common/types/annotations';
|
||||
} from '../../../../../legacy/plugins/ml/common/types/annotations';
|
||||
|
||||
// TODO All of the following interface/type definitions should
|
||||
// eventually be replaced by the proper upstream definitions
|
|
@ -5,10 +5,10 @@
|
|||
*/
|
||||
|
||||
import { APICaller } from 'src/core/server';
|
||||
import { BucketSpanEstimatorData } from '../../../public/application/services/ml_api_service';
|
||||
import { BucketSpanEstimatorData } from '../../../../../legacy/plugins/ml/public/application/services/ml_api_service';
|
||||
|
||||
export function estimateBucketSpanFactory(
|
||||
callAsCurrentUser: APICaller,
|
||||
callAsInternalUser: APICaller,
|
||||
xpackMainPlugin: any
|
||||
isSecurityDisabled: boolean
|
||||
): (config: BucketSpanEstimatorData) => Promise<any>;
|
|
@ -12,9 +12,11 @@ import { INTERVALS } from './intervals';
|
|||
import { singleSeriesCheckerFactory } from './single_series_checker';
|
||||
import { polledDataCheckerFactory } from './polled_data_checker';
|
||||
|
||||
import { isSecurityDisabled } from '../../lib/security_utils';
|
||||
|
||||
export function estimateBucketSpanFactory(callAsCurrentUser, callAsInternalUser, xpackMainPlugin) {
|
||||
export function estimateBucketSpanFactory(
|
||||
callAsCurrentUser,
|
||||
callAsInternalUser,
|
||||
isSecurityDisabled
|
||||
) {
|
||||
const PolledDataChecker = polledDataCheckerFactory(callAsCurrentUser);
|
||||
const SingleSeriesChecker = singleSeriesCheckerFactory(callAsCurrentUser);
|
||||
|
||||
|
@ -384,7 +386,7 @@ export function estimateBucketSpanFactory(callAsCurrentUser, callAsInternalUser,
|
|||
});
|
||||
}
|
||||
|
||||
if (isSecurityDisabled(xpackMainPlugin)) {
|
||||
if (isSecurityDisabled) {
|
||||
getBucketSpanEstimation();
|
||||
} else {
|
||||
// if security is enabled, check that the user has permission to
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import Boom from 'boom';
|
||||
|
||||
import { GLOBAL_CALENDAR } from '../../../common/constants/calendars';
|
||||
import { GLOBAL_CALENDAR } from '../../../../../legacy/plugins/ml/common/constants/calendars';
|
||||
|
||||
export interface CalendarEvent {
|
||||
calendar_id?: string;
|
|
@ -4,9 +4,9 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { callWithRequestType } from '../../../common/types/kibana';
|
||||
import { ML_NOTIFICATION_INDEX_PATTERN } from '../../../common/constants/index_patterns';
|
||||
import { JobMessage } from '../../../common/types/audit_message';
|
||||
import { callWithRequestType } from '../../../../../legacy/plugins/ml/common/types/kibana';
|
||||
import { ML_NOTIFICATION_INDEX_PATTERN } from '../../../../../legacy/plugins/ml/common/constants/index_patterns';
|
||||
import { JobMessage } from '../../../../../legacy/plugins/ml/common/types/audit_message';
|
||||
|
||||
const SIZE = 50;
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { RequestHandlerContext } from 'kibana/server';
|
||||
import { Module } from '../../../common/types/modules';
|
||||
import { Module } from '../../../../../legacy/plugins/ml/common/types/modules';
|
||||
import { DataRecognizer } from '../data_recognizer';
|
||||
|
||||
describe('ML - data recognizer', () => {
|
|
@ -10,7 +10,7 @@ import numeral from '@elastic/numeral';
|
|||
import { CallAPIOptions, RequestHandlerContext, SavedObjectsClientContract } from 'kibana/server';
|
||||
import { IndexPatternAttributes } from 'src/plugins/data/server';
|
||||
import { merge } from 'lodash';
|
||||
import { MlJob } from '../../../common/types/jobs';
|
||||
import { MlJob } from '../../../../../legacy/plugins/ml/common/types/jobs';
|
||||
import {
|
||||
KibanaObjects,
|
||||
ModuleDataFeed,
|
||||
|
@ -23,8 +23,11 @@ import {
|
|||
JobResponse,
|
||||
KibanaObjectResponse,
|
||||
DataRecognizerConfigResponse,
|
||||
} from '../../../common/types/modules';
|
||||
import { getLatestDataOrBucketTimestamp, prefixDatafeedId } from '../../../common/util/job_utils';
|
||||
} from '../../../../../legacy/plugins/ml/common/types/modules';
|
||||
import {
|
||||
getLatestDataOrBucketTimestamp,
|
||||
prefixDatafeedId,
|
||||
} from '../../../../../legacy/plugins/ml/common/util/job_utils';
|
||||
import { mlLog } from '../../client/log';
|
||||
// @ts-ignore
|
||||
import { jobServiceProvider } from '../job_service';
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue