From 28b8f404e782f512e8673da0e8007236affdb8b3 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Wed, 29 Jun 2022 15:53:25 +0200 Subject: [PATCH] [ML] Adds API license check. --- x-pack/plugins/aiops/kibana.json | 5 +++- x-pack/plugins/aiops/server/lib/license.ts | 12 ++++++++++ x-pack/plugins/aiops/server/plugin.ts | 23 ++++++++++++++++--- .../server/routes/explain_log_rate_spikes.ts | 7 ++++++ x-pack/plugins/aiops/server/types.ts | 8 ++++++- 5 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/aiops/server/lib/license.ts diff --git a/x-pack/plugins/aiops/kibana.json b/x-pack/plugins/aiops/kibana.json index 2d1e60bca74e..558e5b475c45 100755 --- a/x-pack/plugins/aiops/kibana.json +++ b/x-pack/plugins/aiops/kibana.json @@ -9,7 +9,10 @@ "description": "AIOps plugin maintained by ML team.", "server": true, "ui": true, - "requiredPlugins": ["data"], + "requiredPlugins": [ + "data", + "licensing" + ], "optionalPlugins": [], "requiredBundles": ["kibanaReact"], "extraPublicDirs": ["common"] diff --git a/x-pack/plugins/aiops/server/lib/license.ts b/x-pack/plugins/aiops/server/lib/license.ts new file mode 100644 index 000000000000..6e2173ab21ef --- /dev/null +++ b/x-pack/plugins/aiops/server/lib/license.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ILicense, LicenseType } from '@kbn/licensing-plugin/common/types'; + +export function isActiveLicense(licenseType: LicenseType, license?: ILicense): boolean { + return (license && license.isActive && license.hasAtLeast(licenseType)) || false; +} diff --git a/x-pack/plugins/aiops/server/plugin.ts b/x-pack/plugins/aiops/server/plugin.ts index 56a2a8bb58ba..29b4b79884d8 100755 --- a/x-pack/plugins/aiops/server/plugin.ts +++ b/x-pack/plugins/aiops/server/plugin.ts @@ -5,12 +5,16 @@ * 2.0. */ +import { Subscription } from 'rxjs'; + import { PluginInitializerContext, CoreSetup, CoreStart, Plugin, Logger } from '@kbn/core/server'; import type { DataRequestHandlerContext } from '@kbn/data-plugin/server'; import { AIOPS_ENABLED } from '../common'; +import { isActiveLicense } from './lib/license'; import { + AiopsLicense, AiopsPluginSetup, AiopsPluginStart, AiopsPluginSetupDeps, @@ -22,19 +26,29 @@ export class AiopsPlugin implements Plugin { private readonly logger: Logger; + private licenseSubscription: Subscription | null = null; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); } - public setup(core: CoreSetup, deps: AiopsPluginSetupDeps) { + public setup(core: CoreSetup, plugins: AiopsPluginSetupDeps) { this.logger.debug('aiops: Setup'); + + // Subscribe to license changes and store the current license in `currentLicense`. + // This way we can pass on license changes to the route factory having always + // the current license because it's stored in a mutable attribute. + const aiopsLicense: AiopsLicense = { isActivePlatinumLicense: false }; + this.licenseSubscription = plugins.licensing.license$.subscribe(async (license) => { + aiopsLicense.isActivePlatinumLicense = isActiveLicense('platinum', license); + }); + const router = core.http.createRouter(); // Register server side APIs if (AIOPS_ENABLED) { core.getStartServices().then(([_, depsStart]) => { - defineExplainLogRateSpikesRoute(router, this.logger); + defineExplainLogRateSpikesRoute(router, aiopsLicense, this.logger); }); } @@ -46,5 +60,8 @@ export class AiopsPlugin return {}; } - public stop() {} + public stop() { + this.logger.debug('aiops: Stop'); + this.licenseSubscription?.unsubscribe(); + } } diff --git a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts index 4ab33e06a42c..ac9693734296 100644 --- a/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts +++ b/x-pack/plugins/aiops/server/routes/explain_log_rate_spikes.ts @@ -20,6 +20,8 @@ import { import { API_ENDPOINT } from '../../common/api'; import type { ChangePoint } from '../../common/types'; +import type { AiopsLicense } from '../types'; + import { fetchFieldCandidates } from './queries/fetch_field_candidates'; import { fetchChangePointPValues } from './queries/fetch_change_point_p_values'; @@ -29,6 +31,7 @@ const PROGRESS_STEP_P_VALUES = 0.8; export const defineExplainLogRateSpikesRoute = ( router: IRouter, + license: AiopsLicense, logger: Logger ) => { router.post( @@ -39,6 +42,10 @@ export const defineExplainLogRateSpikesRoute = ( }, }, async (context, request, response) => { + if (!license.isActivePlatinumLicense) { + response.forbidden(); + } + const client = (await context.core).elasticsearch.client.asCurrentUser; const controller = new AbortController(); diff --git a/x-pack/plugins/aiops/server/types.ts b/x-pack/plugins/aiops/server/types.ts index 3d27a9625db4..8678fe186d56 100755 --- a/x-pack/plugins/aiops/server/types.ts +++ b/x-pack/plugins/aiops/server/types.ts @@ -5,10 +5,12 @@ * 2.0. */ -import { PluginSetup, PluginStart } from '@kbn/data-plugin/server'; +import type { PluginSetup, PluginStart } from '@kbn/data-plugin/server'; +import type { LicensingPluginStart } from '@kbn/licensing-plugin/server'; export interface AiopsPluginSetupDeps { data: PluginSetup; + licensing: LicensingPluginStart; } export interface AiopsPluginStartDeps { @@ -26,3 +28,7 @@ export interface AiopsPluginSetup {} */ // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface AiopsPluginStart {} + +export interface AiopsLicense { + isActivePlatinumLicense: boolean; +}