Skip to content

Commit

Permalink
Extract License service into es_ui_shared and consume it in CCR.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjcenizal committed Apr 2, 2021
1 parent 6bfb2a8 commit 4ba7a29
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 60 deletions.
1 change: 1 addition & 0 deletions src/plugins/es_ui_shared/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

export { isEsError, handleEsError, parseEsError } from './errors';
export { License } from './license';

/** dummy plugin*/
export function plugin() {
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/es_ui_shared/server/license/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

export { License } from './license';
Original file line number Diff line number Diff line change
@@ -1,87 +1,96 @@
/*
* 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.
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { i18n } from '@kbn/i18n';
import { Logger } from 'src/core/server';
import { KibanaRequest, KibanaResponseFactory, RequestHandler } from 'src/core/server';

import type { LicenseType, LicenseCheckState } from '../../../licensing/common/types';
import type { CcrRequestHandlerContext } from '../types';

import { LicensingPluginSetup } from '../../../licensing/server';
import { PLUGIN } from '../../common/constants';
import {
Logger,
KibanaRequest,
KibanaResponseFactory,
RequestHandler,
RequestHandlerContext,
} from 'src/core/server';

/* eslint-disable @kbn/eslint/no-restricted-paths */
import type {
LicenseType,
LicenseCheckState,
} from '../../../../../x-pack/plugins/licensing/common/types';
import type { LicensingPluginStart } from '../../../../../x-pack/plugins/licensing/server/types';
/* eslint-enable @kbn/eslint/no-restricted-paths */

interface SetupSettings {
pluginName: string;
logger: Logger;
}

interface StartSettings {
pluginId: string;
minimumLicenseType: LicenseType;
licensing: LicensingPluginStart;
}

export class License {
private pluginName?: string;
private logger?: Logger;
private licenseCheckState: LicenseCheckState = 'unavailable';
private licenseType?: LicenseType;
private logger?: Logger;

private _isEsSecurityEnabled: boolean = false;

setup(
{ pluginId, minimumLicenseType }: SetupSettings,
{ licensing, logger }: { licensing: LicensingPluginSetup; logger: Logger }
) {
setup({ pluginName, logger }: SetupSettings) {
this.pluginName = pluginName;
this.logger = logger;
}

start({ pluginId, minimumLicenseType, licensing }: StartSettings) {
licensing.license$.subscribe((license) => {
this.licenseType = license.type;
this.licenseCheckState = license.check(pluginId, minimumLicenseType).state;
this.licenseCheckState = license.check(pluginId, minimumLicenseType!).state;

// Retrieving security checks the results of GET /_xpack as well as license state,
// so we're also checking whether the security is disabled in elasticsearch.yml.
// so we're also checking whether security is disabled in elasticsearch.yml.
this._isEsSecurityEnabled = license.getFeature('security').isEnabled;
});
}

getLicenseErrorMessage(licenseCheckState: LicenseCheckState): string {
switch (licenseCheckState) {
case 'invalid':
return i18n.translate(
'xpack.crossClusterReplication.licensingCheck.errorUnsupportedMessage',
{
defaultMessage:
'Your {licenseType} license does not support {pluginName}. Please upgrade your license.',
values: { licenseType: this.licenseType!, pluginName: PLUGIN.TITLE },
}
);
return i18n.translate('xpack.esUi.license.errorUnsupportedMessage', {
defaultMessage:
'Your {licenseType} license does not support {pluginName}. Please upgrade your license.',
values: { licenseType: this.licenseType!, pluginName: this.pluginName },
});

case 'expired':
return i18n.translate('xpack.crossClusterReplication.licensingCheck.errorExpiredMessage', {
return i18n.translate('xpack.esUi.license.errorExpiredMessage', {
defaultMessage:
'You cannot use {pluginName} because your {licenseType} license has expired.',
values: { licenseType: this.licenseType!, pluginName: PLUGIN.TITLE },
values: { licenseType: this.licenseType!, pluginName: this.pluginName },
});

case 'unavailable':
return i18n.translate(
'xpack.crossClusterReplication.licensingCheck.errorUnavailableMessage',
{
defaultMessage:
'You cannot use {pluginName} because license information is not available at this time.',
values: { pluginName: PLUGIN.TITLE },
}
);
return i18n.translate('xpack.esUi.license.errorUnavailableMessage', {
defaultMessage:
'You cannot use {pluginName} because license information is not available at this time.',
values: { pluginName: this.pluginName },
});
}

return i18n.translate('xpack.crossClusterReplication.licensingCheck.genericErrorMessage', {
return i18n.translate('xpack.esUi.license.genericErrorMessage', {
defaultMessage: 'You cannot use {pluginName} because the license check failed.',
values: { pluginName: PLUGIN.TITLE },
values: { pluginName: this.pluginName },
});
}

guardApiRoute<P, Q, B>(handler: RequestHandler<P, Q, B, CcrRequestHandlerContext>) {
const licenseCheck = (
ctx: CcrRequestHandlerContext,
guardApiRoute<P, Q, B>(handler: RequestHandler<P, Q, B, RequestHandlerContext>) {
return (
ctx: RequestHandlerContext,
request: KibanaRequest<P, Q, B>,
response: KibanaResponseFactory
) => {
Expand All @@ -100,8 +109,6 @@ export class License {

return handler(ctx, request, response);
};

return licenseCheck;
}

// eslint-disable-next-line @typescript-eslint/explicit-member-accessibility
Expand Down
1 change: 1 addition & 0 deletions src/plugins/es_ui_shared/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"static/**/*"
],
"references": [
{ "path": "../../../x-pack/plugins/licensing/tsconfig.json" },
{ "path": "../../core/tsconfig.json" },
{ "path": "../data/tsconfig.json" },
]
Expand Down
29 changes: 15 additions & 14 deletions x-pack/plugins/cross_cluster_replication/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ import { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import {
CoreSetup,
CoreStart,
ILegacyCustomClusterClient,
Plugin,
Logger,
PluginInitializerContext,
LegacyAPICaller,
} from 'src/core/server';

import { License } from '../../../../src/plugins/es_ui_shared/server';
import { Index } from '../../index_management/server';
import { PLUGIN } from '../common/constants';
import type { Dependencies, CcrRequestHandlerContext } from './types';
import type { SetupDependencies, CcrRequestHandlerContext } from './types';
import { registerApiRoutes } from './routes';
import { License } from './services';
import { elasticsearchJsPlugin } from './client/elasticsearch_ccr';
import { CrossClusterReplicationConfig } from './config';
import { isEsError } from './shared_imports';
Expand Down Expand Up @@ -76,7 +77,7 @@ export class CrossClusterReplicationServerPlugin implements Plugin<void, void, a

setup(
{ http, getStartServices }: CoreSetup,
{ features, licensing, indexManagement, remoteClusters }: Dependencies
{ features, licensing, indexManagement, remoteClusters }: SetupDependencies
) {
this.config$
.pipe(first())
Expand All @@ -96,16 +97,10 @@ export class CrossClusterReplicationServerPlugin implements Plugin<void, void, a
}
});

this.license.setup(
{
pluginId: PLUGIN.ID,
minimumLicenseType: PLUGIN.minimumLicenseType,
},
{
licensing,
logger: this.logger,
}
);
this.license.setup({
pluginName: PLUGIN.TITLE,
logger: this.logger,
});

features.registerElasticsearchFeature({
id: 'cross_cluster_replication',
Expand Down Expand Up @@ -140,7 +135,13 @@ export class CrossClusterReplicationServerPlugin implements Plugin<void, void, a
});
}

start() {}
start(core: CoreStart, { licensing }: StartDependencies) {
this.license.start({
pluginId: PLUGIN.ID,
minimumLicenseType: PLUGIN.minimumLicenseType,
licensing,
});
}

stop() {
if (this.ccrEsClient) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
* 2.0.
*/

export { License } from './license';
export { addBasePath } from './add_base_path';
11 changes: 8 additions & 3 deletions x-pack/plugins/cross_cluster_replication/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,25 @@

import { IRouter, ILegacyScopedClusterClient, RequestHandlerContext } from 'src/core/server';
import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server';
import { LicensingPluginSetup } from '../../licensing/server';
import { LicensingPluginSetup, LicensingPluginStart } from '../../licensing/server';
import { IndexManagementPluginSetup } from '../../index_management/server';
import { RemoteClustersPluginSetup } from '../../remote_clusters/server';
import { License } from './services';
import { isEsError } from './shared_imports';
import { formatEsError } from './lib/format_es_error';

export interface Dependencies {
import type { License } from '../../../../src/plugins/es_ui_shared/server';

export interface SetupDependencies {
licensing: LicensingPluginSetup;
indexManagement: IndexManagementPluginSetup;
remoteClusters: RemoteClustersPluginSetup;
features: FeaturesPluginSetup;
}

export interface StartDependencies {
licensing: LicensingPluginStart;
}

export interface RouteDependencies {
router: CcrPluginRouter;
license: License;
Expand Down

0 comments on commit 4ba7a29

Please sign in to comment.