mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ML] Disabling ML if license feature is disabled (#73187)
* [ML] Disabling ML if license feature is disabled * disabling UI feature * removing unused import * small refactor * disabling ml using plugin updater * function rename * update comment Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
1b4d4d8a57
commit
10cbaf5ca1
6 changed files with 73 additions and 45 deletions
|
@ -11,4 +11,5 @@ export {
|
|||
MINIMUM_LICENSE,
|
||||
isFullLicense,
|
||||
isMinimumLicense,
|
||||
isMlEnabled,
|
||||
} from './ml_license';
|
||||
|
|
|
@ -82,3 +82,7 @@ export function isFullLicense(license: ILicense) {
|
|||
export function isMinimumLicense(license: ILicense) {
|
||||
return license.check(PLUGIN_ID, MINIMUM_LICENSE).state === 'valid';
|
||||
}
|
||||
|
||||
export function isMlEnabled(license: ILicense) {
|
||||
return license.getFeature(PLUGIN_ID).isEnabled;
|
||||
}
|
||||
|
|
|
@ -11,37 +11,28 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { take } from 'rxjs/operators';
|
||||
|
||||
import { CoreSetup } from 'kibana/public';
|
||||
import { MlStartDependencies, MlSetupDependencies } from '../../plugin';
|
||||
import { ManagementSetup } from 'src/plugins/management/public';
|
||||
import { MlStartDependencies } from '../../plugin';
|
||||
|
||||
import { ManagementAppMountParams } from '../../../../../../src/plugins/management/public';
|
||||
import { PLUGIN_ID } from '../../../common/constants/app';
|
||||
import { MINIMUM_FULL_LICENSE } from '../../../common/license';
|
||||
|
||||
export function initManagementSection(
|
||||
pluginsSetup: MlSetupDependencies,
|
||||
export function registerManagementSection(
|
||||
management: ManagementSetup | undefined,
|
||||
core: CoreSetup<MlStartDependencies>
|
||||
) {
|
||||
const licensing = pluginsSetup.licensing.license$.pipe(take(1));
|
||||
licensing.subscribe((license) => {
|
||||
const management = pluginsSetup.management;
|
||||
if (
|
||||
management !== undefined &&
|
||||
license.check(PLUGIN_ID, MINIMUM_FULL_LICENSE).state === 'valid'
|
||||
) {
|
||||
management.sections.section.insightsAndAlerting.registerApp({
|
||||
id: 'jobsListLink',
|
||||
title: i18n.translate('xpack.ml.management.jobsListTitle', {
|
||||
defaultMessage: 'Machine Learning Jobs',
|
||||
}),
|
||||
order: 2,
|
||||
async mount(params: ManagementAppMountParams) {
|
||||
const { mountApp } = await import('./jobs_list');
|
||||
return mountApp(core, params);
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
if (management !== undefined) {
|
||||
management.sections.section.insightsAndAlerting.registerApp({
|
||||
id: 'jobsListLink',
|
||||
title: i18n.translate('xpack.ml.management.jobsListTitle', {
|
||||
defaultMessage: 'Machine Learning Jobs',
|
||||
}),
|
||||
order: 2,
|
||||
async mount(params: ManagementAppMountParams) {
|
||||
const { mountApp } = await import('./jobs_list');
|
||||
return mountApp(core, params);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import {
|
|||
AppMountParameters,
|
||||
PluginInitializerContext,
|
||||
} from 'kibana/public';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { ManagementSetup } from 'src/plugins/management/public';
|
||||
import { SharePluginSetup, SharePluginStart, UrlGeneratorState } from 'src/plugins/share/public';
|
||||
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
||||
|
@ -19,9 +21,10 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
|||
import { DataPublicPluginStart } from 'src/plugins/data/public';
|
||||
import { HomePublicPluginSetup } from 'src/plugins/home/public';
|
||||
import { EmbeddableSetup } from 'src/plugins/embeddable/public';
|
||||
import { AppStatus, AppUpdater } from '../../../../src/core/public';
|
||||
import { SecurityPluginSetup } from '../../security/public';
|
||||
import { LicensingPluginSetup } from '../../licensing/public';
|
||||
import { initManagementSection } from './application/management';
|
||||
import { registerManagementSection } from './application/management';
|
||||
import { LicenseManagementUIPluginSetup } from '../../license_management/public';
|
||||
import { setDependencyCache } from './application/util/dependency_cache';
|
||||
import { PLUGIN_ID, PLUGIN_ICON } from '../common/constants/app';
|
||||
|
@ -31,7 +34,8 @@ import { registerEmbeddables } from './embeddables';
|
|||
import { UiActionsSetup, UiActionsStart } from '../../../../src/plugins/ui_actions/public';
|
||||
import { registerMlUiActions } from './ui_actions';
|
||||
import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public';
|
||||
import { MlUrlGenerator, MlUrlGeneratorState, ML_APP_URL_GENERATOR } from './url_generator';
|
||||
import { registerUrlGenerator, MlUrlGeneratorState, ML_APP_URL_GENERATOR } from './url_generator';
|
||||
import { isMlEnabled, isFullLicense } from '../common/license';
|
||||
|
||||
export interface MlStartDependencies {
|
||||
data: DataPublicPluginStart;
|
||||
|
@ -61,18 +65,11 @@ declare module '../../../../src/plugins/share/public' {
|
|||
export type MlCoreSetup = CoreSetup<MlStartDependencies, MlPluginStart>;
|
||||
|
||||
export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
||||
private appUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
|
||||
constructor(private initializerContext: PluginInitializerContext) {}
|
||||
|
||||
setup(core: MlCoreSetup, pluginsSetup: MlSetupDependencies) {
|
||||
const baseUrl = core.http.basePath.prepend('/app/ml');
|
||||
|
||||
pluginsSetup.share.urlGenerators.registerUrlGenerator(
|
||||
new MlUrlGenerator({
|
||||
appBasePath: baseUrl,
|
||||
useHash: core.uiSettings.get('state:storeInSessionStorage'),
|
||||
})
|
||||
);
|
||||
|
||||
core.application.register({
|
||||
id: PLUGIN_ID,
|
||||
title: i18n.translate('xpack.ml.plugin.title', {
|
||||
|
@ -82,6 +79,7 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
euiIconType: PLUGIN_ICON,
|
||||
appRoute: '/app/ml',
|
||||
category: DEFAULT_APP_CATEGORIES.kibana,
|
||||
updater$: this.appUpdater,
|
||||
mount: async (params: AppMountParameters) => {
|
||||
const [coreStart, pluginsStart] = await core.getStartServices();
|
||||
const kibanaVersion = this.initializerContext.env.packageInfo.version;
|
||||
|
@ -112,11 +110,26 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
|
|||
},
|
||||
});
|
||||
|
||||
registerFeature(pluginsSetup.home);
|
||||
const licensing = pluginsSetup.licensing.license$.pipe(take(1));
|
||||
licensing.subscribe((license) => {
|
||||
if (isMlEnabled(license)) {
|
||||
// add ML to home page
|
||||
registerFeature(pluginsSetup.home);
|
||||
|
||||
initManagementSection(pluginsSetup, core);
|
||||
registerEmbeddables(pluginsSetup.embeddable, core);
|
||||
registerMlUiActions(pluginsSetup.uiActions, core);
|
||||
// register various ML plugin features which require a full license
|
||||
if (isFullLicense(license)) {
|
||||
registerManagementSection(pluginsSetup.management, core);
|
||||
registerEmbeddables(pluginsSetup.embeddable, core);
|
||||
registerMlUiActions(pluginsSetup.uiActions, core);
|
||||
registerUrlGenerator(pluginsSetup.share, core);
|
||||
}
|
||||
} else {
|
||||
// if ml is disabled in elasticsearch, disable ML in kibana
|
||||
this.appUpdater.next(() => ({
|
||||
status: AppStatus.inaccessible,
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { UrlGeneratorsDefinition } from '../../../../src/plugins/share/public';
|
||||
import { CoreSetup } from 'kibana/public';
|
||||
import { SharePluginSetup, UrlGeneratorsDefinition } from '../../../../src/plugins/share/public';
|
||||
import { TimeRange } from '../../../../src/plugins/data/public';
|
||||
import { setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public';
|
||||
import { JobId } from '../../reporting/common/types';
|
||||
import { ExplorerAppState } from './application/explorer/explorer_dashboard_service';
|
||||
import { MlStartDependencies } from './plugin';
|
||||
|
||||
export const ML_APP_URL_GENERATOR = 'ML_APP_URL_GENERATOR';
|
||||
|
||||
|
@ -88,3 +90,19 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition<typeof ML_APP_URL
|
|||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the URL generator
|
||||
*/
|
||||
export function registerUrlGenerator(
|
||||
share: SharePluginSetup,
|
||||
core: CoreSetup<MlStartDependencies>
|
||||
) {
|
||||
const baseUrl = core.http.basePath.prepend('/app/ml');
|
||||
share.urlGenerators.registerUrlGenerator(
|
||||
new MlUrlGenerator({
|
||||
appBasePath: baseUrl,
|
||||
useHash: core.uiSettings.get('state:storeInSessionStorage'),
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Observable } from 'rxjs';
|
|||
import { take } from 'rxjs/operators';
|
||||
import { CapabilitiesSwitcher, CoreSetup, Logger } from 'src/core/server';
|
||||
import { ILicense } from '../../../../licensing/common/types';
|
||||
import { isFullLicense, isMinimumLicense } from '../../../common/license';
|
||||
import { isFullLicense, isMinimumLicense, isMlEnabled } from '../../../common/license';
|
||||
import { MlCapabilities, basicLicenseMlCapabilities } from '../../../common/types/capabilities';
|
||||
|
||||
export const setupCapabilitiesSwitcher = (
|
||||
|
@ -30,9 +30,10 @@ function getSwitcher(license$: Observable<ILicense>, logger: Logger): Capabiliti
|
|||
|
||||
try {
|
||||
const license = await license$.pipe(take(1)).toPromise();
|
||||
const mlEnabled = isMlEnabled(license);
|
||||
|
||||
// full license, leave capabilities as they were
|
||||
if (isFullLicense(license)) {
|
||||
if (mlEnabled && isFullLicense(license)) {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
|
@ -45,7 +46,7 @@ function getSwitcher(license$: Observable<ILicense>, logger: Logger): Capabiliti
|
|||
});
|
||||
|
||||
// for a basic license, reapply the original capabilities for the basic license features
|
||||
if (isMinimumLicense(license)) {
|
||||
if (mlEnabled && isMinimumLicense(license)) {
|
||||
basicLicenseMlCapabilities.forEach((c) => (mlCaps[c] = originalCapabilities[c]));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue