Refactor Plugins to access elasticsearch from CoreStart (#59915)

* x-pack/watcher: use Elasticsearch from CoreStart

* x-pack/upgrade_assistant: use Elasticsearch from CoreStart

* x-pack/actions: use Elasticsearch from CoreStart

* x-pack/alerting: use Elasticsearch from CoreStart

* x-pack/lens: use Elasticsearch from CoreStart

* expressions: use Elasticsearch from CoreStart

* x-pack/remote_clusters: remove unused Elasticsearch dependency on CoreSetup

* x-pack/oss_telemetry: use Elasticsearch from CoreStart

* Cleanup after #59886

* x-pack/watcher: create custom client only once

* Revert "x-pack/watcher: create custom client only once"

This reverts commit 78fc4d2e93.

* Revert "x-pack/watcher: use Elasticsearch from CoreStart"

This reverts commit b621af9388.

* x-pack/task_manager: use Elasticsearch from CoreStart

* x-pack/event_log: use Elasticsearch from CoreStart

* x-pack/alerting: use Elasticsearch from CoreStart

* x-pack/apm: use Elasticsearch from CoreStart

* x-pack/actions: use Elasticsearch from CoreStart

* PR Feedback

* APM review nits

* Remove unused variable

* Remove unused variable

* x-pack/apm: better typesafety

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Rudolf Meijering 2020-04-15 17:07:57 +02:00 committed by GitHub
parent afb48bceca
commit 00a1144ae2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 148 additions and 125 deletions

View file

@ -33,7 +33,12 @@ import { CoreService } from '../../types';
import { merge } from '../../utils'; import { merge } from '../../utils';
import { CoreContext } from '../core_context'; import { CoreContext } from '../core_context';
import { Logger } from '../logging'; import { Logger } from '../logging';
import { ClusterClient, ScopeableRequest } from './cluster_client'; import {
ClusterClient,
ScopeableRequest,
IClusterClient,
ICustomClusterClient,
} from './cluster_client';
import { ElasticsearchClientConfig } from './elasticsearch_client_config'; import { ElasticsearchClientConfig } from './elasticsearch_client_config';
import { ElasticsearchConfig, ElasticsearchConfigType } from './elasticsearch_config'; import { ElasticsearchConfig, ElasticsearchConfigType } from './elasticsearch_config';
import { InternalHttpServiceSetup, GetAuthHeaders } from '../http/'; import { InternalHttpServiceSetup, GetAuthHeaders } from '../http/';
@ -58,12 +63,14 @@ export class ElasticsearchService
implements CoreService<InternalElasticsearchServiceSetup, ElasticsearchServiceStart> { implements CoreService<InternalElasticsearchServiceSetup, ElasticsearchServiceStart> {
private readonly log: Logger; private readonly log: Logger;
private readonly config$: Observable<ElasticsearchConfig>; private readonly config$: Observable<ElasticsearchConfig>;
private subscription: Subscription | undefined; private subscription?: Subscription;
private stop$ = new Subject(); private stop$ = new Subject();
private kibanaVersion: string; private kibanaVersion: string;
createClient: InternalElasticsearchServiceSetup['createClient'] | undefined; private createClient?: (
dataClient: InternalElasticsearchServiceSetup['dataClient'] | undefined; type: string,
adminClient: InternalElasticsearchServiceSetup['adminClient'] | undefined; clientConfig?: Partial<ElasticsearchClientConfig>
) => ICustomClusterClient;
private adminClient?: IClusterClient;
constructor(private readonly coreContext: CoreContext) { constructor(private readonly coreContext: CoreContext) {
this.kibanaVersion = coreContext.env.packageInfo.version; this.kibanaVersion = coreContext.env.packageInfo.version;

View file

@ -201,7 +201,7 @@ export class Server {
uiSettings: uiSettingsStart, uiSettings: uiSettingsStart,
}; };
const pluginsStart = await this.plugins.start(this.coreStart!); const pluginsStart = await this.plugins.start(this.coreStart);
await this.legacy.start({ await this.legacy.start({
core: { core: {

View file

@ -26,7 +26,7 @@ import { register, registryFactory, Registry, Fn } from '@kbn/interpreter/common
import Boom from 'boom'; import Boom from 'boom';
import { schema } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema';
import { CoreSetup, Logger } from 'src/core/server'; import { CoreSetup, Logger, APICaller } from 'src/core/server';
import { ExpressionsServerSetupDependencies } from './plugin'; import { ExpressionsServerSetupDependencies } from './plugin';
import { typeSpecs, ExpressionType } from '../common'; import { typeSpecs, ExpressionType } from '../common';
import { serializeProvider } from '../common'; import { serializeProvider } from '../common';
@ -97,7 +97,10 @@ export const createLegacyServerEndpoints = (
* @param {*} handlers - The Canvas handlers * @param {*} handlers - The Canvas handlers
* @param {*} fnCall - Describes the function being run `{ functionName, args, context }` * @param {*} fnCall - Describes the function being run `{ functionName, args, context }`
*/ */
async function runFunction(handlers: any, fnCall: any) { async function runFunction(
handlers: { environment: string; elasticsearchClient: APICaller },
fnCall: any
) {
const { functionName, args, context } = fnCall; const { functionName, args, context } = fnCall;
const { deserialize } = serializeProvider(registries.types.toJS()); const { deserialize } = serializeProvider(registries.types.toJS());
const fnDef = registries.serverFunctions.toJS()[functionName]; const fnDef = registries.serverFunctions.toJS()[functionName];
@ -112,18 +115,14 @@ export const createLegacyServerEndpoints = (
* results back using ND-JSON. * results back using ND-JSON.
*/ */
plugins.bfetch.addBatchProcessingRoute(`/api/interpreter/fns`, request => { plugins.bfetch.addBatchProcessingRoute(`/api/interpreter/fns`, request => {
const scopedClient = core.elasticsearch.dataClient.asScoped(request);
const handlers = {
environment: 'server',
elasticsearchClient: async (
endpoint: string,
clientParams: Record<string, any> = {},
options?: any
) => scopedClient.callAsCurrentUser(endpoint, clientParams, options),
};
return { return {
onBatchItem: async (fnCall: any) => { onBatchItem: async (fnCall: any) => {
const [coreStart] = await core.getStartServices();
const handlers = {
environment: 'server',
elasticsearchClient: coreStart.elasticsearch.legacy.client.asScoped(request)
.callAsCurrentUser,
};
const result = await runFunction(handlers, fnCall); const result = await runFunction(handlers, fnCall);
if (typeof result === 'undefined') { if (typeof result === 'undefined') {
throw new Error(`Function ${fnCall.functionName} did not return anything.`); throw new Error(`Function ${fnCall.functionName} did not return anything.`);

View file

@ -99,6 +99,9 @@ describe('Actions Plugin', () => {
savedObjects: { savedObjects: {
client: {}, client: {},
}, },
elasticsearch: {
adminClient: jest.fn(),
},
}, },
} as any, } as any,
httpServerMock.createKibanaRequest(), httpServerMock.createKibanaRequest(),

View file

@ -11,13 +11,13 @@ import {
Plugin, Plugin,
CoreSetup, CoreSetup,
CoreStart, CoreStart,
IClusterClient,
KibanaRequest, KibanaRequest,
Logger, Logger,
SharedGlobalConfig, SharedGlobalConfig,
RequestHandler, RequestHandler,
IContextProvider, IContextProvider,
SavedObjectsServiceStart, SavedObjectsServiceStart,
ElasticsearchServiceStart,
} from '../../../../src/core/server'; } from '../../../../src/core/server';
import { import {
@ -89,7 +89,6 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
private readonly logger: Logger; private readonly logger: Logger;
private serverBasePath?: string; private serverBasePath?: string;
private adminClient?: IClusterClient;
private taskRunnerFactory?: TaskRunnerFactory; private taskRunnerFactory?: TaskRunnerFactory;
private actionTypeRegistry?: ActionTypeRegistry; private actionTypeRegistry?: ActionTypeRegistry;
private actionExecutor?: ActionExecutor; private actionExecutor?: ActionExecutor;
@ -173,7 +172,6 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
this.actionTypeRegistry = actionTypeRegistry; this.actionTypeRegistry = actionTypeRegistry;
this.serverBasePath = core.http.basePath.serverBasePath; this.serverBasePath = core.http.basePath.serverBasePath;
this.actionExecutor = actionExecutor; this.actionExecutor = actionExecutor;
this.adminClient = core.elasticsearch.adminClient;
this.spaces = plugins.spaces?.spacesService; this.spaces = plugins.spaces?.spacesService;
registerBuiltInActionTypes({ registerBuiltInActionTypes({
@ -233,7 +231,6 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
actionTypeRegistry, actionTypeRegistry,
taskRunnerFactory, taskRunnerFactory,
kibanaIndex, kibanaIndex,
adminClient,
isESOUsingEphemeralEncryptionKey, isESOUsingEphemeralEncryptionKey,
preconfiguredActions, preconfiguredActions,
} = this; } = this;
@ -242,7 +239,7 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
logger, logger,
eventLogger: this.eventLogger!, eventLogger: this.eventLogger!,
spaces: this.spaces, spaces: this.spaces,
getServices: this.getServicesFactory(core.savedObjects), getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
actionTypeRegistry: actionTypeRegistry!, actionTypeRegistry: actionTypeRegistry!,
preconfiguredActions, preconfiguredActions,
@ -282,7 +279,7 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
savedObjectsClient: core.savedObjects.getScopedClient(request), savedObjectsClient: core.savedObjects.getScopedClient(request),
actionTypeRegistry: actionTypeRegistry!, actionTypeRegistry: actionTypeRegistry!,
defaultKibanaIndex: await kibanaIndex, defaultKibanaIndex: await kibanaIndex,
scopedClusterClient: adminClient!.asScoped(request), scopedClusterClient: core.elasticsearch.legacy.client.asScoped(request),
preconfiguredActions, preconfiguredActions,
}); });
}, },
@ -291,11 +288,11 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
} }
private getServicesFactory( private getServicesFactory(
savedObjects: SavedObjectsServiceStart savedObjects: SavedObjectsServiceStart,
elasticsearch: ElasticsearchServiceStart
): (request: KibanaRequest) => Services { ): (request: KibanaRequest) => Services {
const { adminClient } = this;
return request => ({ return request => ({
callCluster: adminClient!.asScoped(request).callAsCurrentUser, callCluster: elasticsearch.legacy.client.asScoped(request).callAsCurrentUser,
savedObjectsClient: savedObjects.getScopedClient(request), savedObjectsClient: savedObjects.getScopedClient(request),
}); });
} }
@ -303,12 +300,8 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
private createRouteHandlerContext = ( private createRouteHandlerContext = (
defaultKibanaIndex: string defaultKibanaIndex: string
): IContextProvider<RequestHandler<any, any, any>, 'actions'> => { ): IContextProvider<RequestHandler<any, any, any>, 'actions'> => {
const { const { actionTypeRegistry, isESOUsingEphemeralEncryptionKey, preconfiguredActions } = this;
actionTypeRegistry,
adminClient,
isESOUsingEphemeralEncryptionKey,
preconfiguredActions,
} = this;
return async function actionsRouteHandlerContext(context, request) { return async function actionsRouteHandlerContext(context, request) {
return { return {
getActionsClient: () => { getActionsClient: () => {
@ -321,7 +314,7 @@ export class ActionsPlugin implements Plugin<Promise<PluginSetupContract>, Plugi
savedObjectsClient: context.core.savedObjects.client, savedObjectsClient: context.core.savedObjects.client,
actionTypeRegistry: actionTypeRegistry!, actionTypeRegistry: actionTypeRegistry!,
defaultKibanaIndex, defaultKibanaIndex,
scopedClusterClient: adminClient!.asScoped(request), scopedClusterClient: context.core.elasticsearch.adminClient,
preconfiguredActions, preconfiguredActions,
}); });
}, },

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License. * you may not use this file except in compliance with the Elastic License.
*/ */
import { Logger, CoreSetup } from 'kibana/server'; import { Logger, CoreSetup, APICaller } from 'kibana/server';
import moment from 'moment'; import moment from 'moment';
import { import {
RunContext, RunContext,
@ -62,7 +62,11 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra
export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) { export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) {
return ({ taskInstance }: RunContext) => { return ({ taskInstance }: RunContext) => {
const { state } = taskInstance; const { state } = taskInstance;
const callCluster = core.elasticsearch.adminClient.callAsInternalUser; const callCluster = (...args: Parameters<APICaller>) => {
return core.getStartServices().then(([{ elasticsearch: { legacy: { client } } }]) =>
client.callAsInternalUser(...args)
);
};
return { return {
async run() { async run() {
return Promise.all([ return Promise.all([

View file

@ -19,7 +19,6 @@ import { TaskRunnerFactory } from './task_runner';
import { AlertsClientFactory } from './alerts_client_factory'; import { AlertsClientFactory } from './alerts_client_factory';
import { LicenseState } from './lib/license_state'; import { LicenseState } from './lib/license_state';
import { import {
IClusterClient,
KibanaRequest, KibanaRequest,
Logger, Logger,
PluginInitializerContext, PluginInitializerContext,
@ -29,6 +28,7 @@ import {
IContextProvider, IContextProvider,
RequestHandler, RequestHandler,
SharedGlobalConfig, SharedGlobalConfig,
ElasticsearchServiceStart,
} from '../../../../src/core/server'; } from '../../../../src/core/server';
import { import {
@ -94,7 +94,6 @@ export class AlertingPlugin {
private readonly logger: Logger; private readonly logger: Logger;
private alertTypeRegistry?: AlertTypeRegistry; private alertTypeRegistry?: AlertTypeRegistry;
private readonly taskRunnerFactory: TaskRunnerFactory; private readonly taskRunnerFactory: TaskRunnerFactory;
private adminClient?: IClusterClient;
private serverBasePath?: string; private serverBasePath?: string;
private licenseState: LicenseState | null = null; private licenseState: LicenseState | null = null;
private isESOUsingEphemeralEncryptionKey?: boolean; private isESOUsingEphemeralEncryptionKey?: boolean;
@ -119,7 +118,6 @@ export class AlertingPlugin {
} }
public async setup(core: CoreSetup, plugins: AlertingPluginsSetup): Promise<PluginSetupContract> { public async setup(core: CoreSetup, plugins: AlertingPluginsSetup): Promise<PluginSetupContract> {
this.adminClient = core.elasticsearch.adminClient;
this.licenseState = new LicenseState(plugins.licensing.license$); this.licenseState = new LicenseState(plugins.licensing.license$);
this.spaces = plugins.spaces?.spacesService; this.spaces = plugins.spaces?.spacesService;
this.security = plugins.security; this.security = plugins.security;
@ -223,7 +221,7 @@ export class AlertingPlugin {
taskRunnerFactory.initialize({ taskRunnerFactory.initialize({
logger, logger,
getServices: this.getServicesFactory(core.savedObjects), getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
spaceIdToNamespace: this.spaceIdToNamespace, spaceIdToNamespace: this.spaceIdToNamespace,
actionsPlugin: plugins.actions, actionsPlugin: plugins.actions,
encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects,
@ -263,11 +261,11 @@ export class AlertingPlugin {
}; };
private getServicesFactory( private getServicesFactory(
savedObjects: SavedObjectsServiceStart savedObjects: SavedObjectsServiceStart,
elasticsearch: ElasticsearchServiceStart
): (request: KibanaRequest) => Services { ): (request: KibanaRequest) => Services {
const { adminClient } = this;
return request => ({ return request => ({
callCluster: adminClient!.asScoped(request).callAsCurrentUser, callCluster: elasticsearch.legacy.client.asScoped(request).callAsCurrentUser,
savedObjectsClient: savedObjects.getScopedClient(request), savedObjectsClient: savedObjects.getScopedClient(request),
}); });
} }

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License. * you may not use this file except in compliance with the Elastic License.
*/ */
import { Logger, CoreSetup } from 'kibana/server'; import { Logger, CoreSetup, APICaller } from 'kibana/server';
import moment from 'moment'; import moment from 'moment';
import { import {
RunContext, RunContext,
@ -65,7 +65,12 @@ async function scheduleTasks(logger: Logger, taskManager: TaskManagerStartContra
export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) { export function telemetryTaskRunner(logger: Logger, core: CoreSetup, kibanaIndex: string) {
return ({ taskInstance }: RunContext) => { return ({ taskInstance }: RunContext) => {
const { state } = taskInstance; const { state } = taskInstance;
const callCluster = core.elasticsearch.adminClient.callAsInternalUser; const callCluster = (...args: Parameters<APICaller>) => {
return core.getStartServices().then(([{ elasticsearch: { legacy: { client } } }]) =>
client.callAsInternalUser(...args)
);
};
return { return {
async run() { async run() {
return Promise.all([ return Promise.all([

View file

@ -3,7 +3,13 @@
* or more contributor license agreements. Licensed under the Elastic License; * or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License. * you may not use this file except in compliance with the Elastic License.
*/ */
import { PluginInitializerContext, Plugin, CoreSetup } from 'src/core/server'; import {
PluginInitializerContext,
Plugin,
CoreSetup,
CoreStart,
Logger
} from 'src/core/server';
import { Observable, combineLatest, AsyncSubject } from 'rxjs'; import { Observable, combineLatest, AsyncSubject } from 'rxjs';
import { map, take } from 'rxjs/operators'; import { map, take } from 'rxjs/operators';
import { Server } from 'hapi'; import { Server } from 'hapi';
@ -37,6 +43,8 @@ export interface APMPluginContract {
} }
export class APMPlugin implements Plugin<APMPluginContract> { export class APMPlugin implements Plugin<APMPluginContract> {
private currentConfig?: APMConfig;
private logger?: Logger;
legacySetup$: AsyncSubject<LegacySetup>; legacySetup$: AsyncSubject<LegacySetup>;
constructor(private readonly initContext: PluginInitializerContext) { constructor(private readonly initContext: PluginInitializerContext) {
this.initContext = initContext; this.initContext = initContext;
@ -56,7 +64,7 @@ export class APMPlugin implements Plugin<APMPluginContract> {
actions?: ActionsPlugin['setup']; actions?: ActionsPlugin['setup'];
} }
) { ) {
const logger = this.initContext.logger.get(); this.logger = this.initContext.logger.get();
const config$ = this.initContext.config.create<APMXPackConfig>(); const config$ = this.initContext.config.create<APMXPackConfig>();
const mergedConfig$ = combineLatest(plugins.apm_oss.config$, config$).pipe( const mergedConfig$ = combineLatest(plugins.apm_oss.config$, config$).pipe(
map(([apmOssConfig, apmConfig]) => mergeConfigs(apmOssConfig, apmConfig)) map(([apmOssConfig, apmConfig]) => mergeConfigs(apmOssConfig, apmConfig))
@ -71,49 +79,40 @@ export class APMPlugin implements Plugin<APMPluginContract> {
} }
this.legacySetup$.subscribe(__LEGACY => { this.legacySetup$.subscribe(__LEGACY => {
createApmApi().init(core, { config$: mergedConfig$, logger, __LEGACY }); createApmApi().init(core, {
config$: mergedConfig$,
logger: this.logger!,
__LEGACY
});
}); });
const currentConfig = await mergedConfig$.pipe(take(1)).toPromise(); this.currentConfig = await mergedConfig$.pipe(take(1)).toPromise();
if ( if (
plugins.taskManager && plugins.taskManager &&
plugins.usageCollection && plugins.usageCollection &&
currentConfig['xpack.apm.telemetryCollectionEnabled'] this.currentConfig['xpack.apm.telemetryCollectionEnabled']
) { ) {
createApmTelemetry({ createApmTelemetry({
core, core,
config$: mergedConfig$, config$: mergedConfig$,
usageCollector: plugins.usageCollection, usageCollector: plugins.usageCollection,
taskManager: plugins.taskManager, taskManager: plugins.taskManager,
logger logger: this.logger
}); });
} }
// create agent configuration index without blocking setup lifecycle
createApmAgentConfigurationIndex({
esClient: core.elasticsearch.dataClient,
config: currentConfig,
logger
});
// create custom action index without blocking setup lifecycle
createApmCustomLinkIndex({
esClient: core.elasticsearch.dataClient,
config: currentConfig,
logger
});
plugins.home.tutorials.registerTutorial( plugins.home.tutorials.registerTutorial(
tutorialProvider({ tutorialProvider({
isEnabled: currentConfig['xpack.apm.ui.enabled'], isEnabled: this.currentConfig['xpack.apm.ui.enabled'],
indexPatternTitle: currentConfig['apm_oss.indexPattern'], indexPatternTitle: this.currentConfig['apm_oss.indexPattern'],
cloud: plugins.cloud, cloud: plugins.cloud,
indices: { indices: {
errorIndices: currentConfig['apm_oss.errorIndices'], errorIndices: this.currentConfig['apm_oss.errorIndices'],
metricsIndices: currentConfig['apm_oss.metricsIndices'], metricsIndices: this.currentConfig['apm_oss.metricsIndices'],
onboardingIndices: currentConfig['apm_oss.onboardingIndices'], onboardingIndices: this.currentConfig['apm_oss.onboardingIndices'],
sourcemapIndices: currentConfig['apm_oss.sourcemapIndices'], sourcemapIndices: this.currentConfig['apm_oss.sourcemapIndices'],
transactionIndices: currentConfig['apm_oss.transactionIndices'] transactionIndices: this.currentConfig['apm_oss.transactionIndices']
} }
}) })
); );
@ -127,12 +126,29 @@ export class APMPlugin implements Plugin<APMPluginContract> {
getApmIndices: async () => getApmIndices: async () =>
getApmIndices({ getApmIndices({
savedObjectsClient: await getInternalSavedObjectsClient(core), savedObjectsClient: await getInternalSavedObjectsClient(core),
config: currentConfig config: await mergedConfig$.pipe(take(1)).toPromise()
}) })
}; };
} }
public async start() {} public start(core: CoreStart) {
if (this.currentConfig == null || this.logger == null) {
throw new Error('APMPlugin needs to be setup before calling start()');
}
// create agent configuration index without blocking start lifecycle
createApmAgentConfigurationIndex({
esClient: core.elasticsearch.legacy.client,
config: this.currentConfig,
logger: this.logger
});
// create custom action index without blocking start lifecycle
createApmCustomLinkIndex({
esClient: core.elasticsearch.legacy.client,
config: this.currentConfig,
logger: this.logger
});
}
public stop() {} public stop() {}
} }

View file

@ -21,7 +21,7 @@ beforeEach(() => {
clusterClient = elasticsearchServiceMock.createClusterClient(); clusterClient = elasticsearchServiceMock.createClusterClient();
clusterClientAdapter = new ClusterClientAdapter({ clusterClientAdapter = new ClusterClientAdapter({
logger, logger,
clusterClient, clusterClientPromise: Promise.resolve(clusterClient),
}); });
}); });

View file

@ -14,7 +14,7 @@ export type IClusterClientAdapter = PublicMethodsOf<ClusterClientAdapter>;
export interface ConstructorOpts { export interface ConstructorOpts {
logger: Logger; logger: Logger;
clusterClient: EsClusterClient; clusterClientPromise: Promise<EsClusterClient>;
} }
export interface QueryEventsBySavedObjectResult { export interface QueryEventsBySavedObjectResult {
@ -26,11 +26,11 @@ export interface QueryEventsBySavedObjectResult {
export class ClusterClientAdapter { export class ClusterClientAdapter {
private readonly logger: Logger; private readonly logger: Logger;
private readonly clusterClient: EsClusterClient; private readonly clusterClientPromise: Promise<EsClusterClient>;
constructor(opts: ConstructorOpts) { constructor(opts: ConstructorOpts) {
this.logger = opts.logger; this.logger = opts.logger;
this.clusterClient = opts.clusterClient; this.clusterClientPromise = opts.clusterClientPromise;
} }
public async indexDocument(doc: any): Promise<void> { public async indexDocument(doc: any): Promise<void> {
@ -201,7 +201,8 @@ export class ClusterClientAdapter {
private async callEs(operation: string, body?: any): Promise<any> { private async callEs(operation: string, body?: any): Promise<any> {
try { try {
this.debug(`callEs(${operation}) calls:`, body); this.debug(`callEs(${operation}) calls:`, body);
const result = await this.clusterClient.callAsInternalUser(operation, body); const clusterClient = await this.clusterClientPromise;
const result = await clusterClient.callAsInternalUser(operation, body);
this.debug(`callEs(${operation}) result:`, result); this.debug(`callEs(${operation}) result:`, result);
return result; return result;
} catch (err) { } catch (err) {

View file

@ -32,7 +32,7 @@ export function createEsContext(params: EsContextCtorParams): EsContext {
export interface EsContextCtorParams { export interface EsContextCtorParams {
logger: Logger; logger: Logger;
clusterClient: EsClusterClient; clusterClientPromise: Promise<EsClusterClient>;
indexNameRoot: string; indexNameRoot: string;
} }
@ -50,7 +50,7 @@ class EsContextImpl implements EsContext {
this.initialized = false; this.initialized = false;
this.esAdapter = new ClusterClientAdapter({ this.esAdapter = new ClusterClientAdapter({
logger: params.logger, logger: params.logger,
clusterClient: params.clusterClient, clusterClientPromise: params.clusterClientPromise,
}); });
} }

View file

@ -66,7 +66,9 @@ export class Plugin implements CorePlugin<IEventLogService, IEventLogClientServi
logger: this.systemLogger, logger: this.systemLogger,
// TODO: get index prefix from config.get(kibana.index) // TODO: get index prefix from config.get(kibana.index)
indexNameRoot: kibanaIndex, indexNameRoot: kibanaIndex,
clusterClient: core.elasticsearch.adminClient, clusterClientPromise: core
.getStartServices()
.then(([{ elasticsearch }]) => elasticsearch.legacy.client),
}); });
this.eventLogService = new EventLogService({ this.eventLogService = new EventLogService({

View file

@ -184,7 +184,10 @@ export function telemetryTaskRunner(
) { ) {
return ({ taskInstance }: RunContext) => { return ({ taskInstance }: RunContext) => {
const { state } = taskInstance; const { state } = taskInstance;
const callCluster = core.elasticsearch.adminClient.callAsInternalUser; const callCluster = async (...args: Parameters<APICaller>) => {
const [coreStart] = await core.getStartServices();
return coreStart.elasticsearch.legacy.client.callAsInternalUser(...args);
};
return { return {
async run() { async run() {

View file

@ -17,12 +17,12 @@ import {
export function registerTasks({ export function registerTasks({
taskManager, taskManager,
logger, logger,
elasticsearch, getStartServices,
config, config,
}: { }: {
taskManager?: TaskManagerSetupContract; taskManager?: TaskManagerSetupContract;
logger: Logger; logger: Logger;
elasticsearch: CoreSetup['elasticsearch']; getStartServices: CoreSetup['getStartServices'];
config: Observable<{ kibana: { index: string } }>; config: Observable<{ kibana: { index: string } }>;
}) { }) {
if (!taskManager) { if (!taskManager) {
@ -30,13 +30,17 @@ export function registerTasks({
return; return;
} }
const esClientPromise = getStartServices().then(
([{ elasticsearch }]) => elasticsearch.legacy.client
);
taskManager.registerTaskDefinitions({ taskManager.registerTaskDefinitions({
[VIS_TELEMETRY_TASK]: { [VIS_TELEMETRY_TASK]: {
title: 'X-Pack telemetry calculator for Visualizations', title: 'X-Pack telemetry calculator for Visualizations',
type: VIS_TELEMETRY_TASK, type: VIS_TELEMETRY_TASK,
createTaskRunner({ taskInstance }: { taskInstance: TaskInstance }) { createTaskRunner({ taskInstance }: { taskInstance: TaskInstance }) {
return { return {
run: visualizationsTaskRunner(taskInstance, config, elasticsearch), run: visualizationsTaskRunner(taskInstance, config, esClientPromise),
}; };
}, },
}, },

View file

@ -6,7 +6,7 @@
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import _, { countBy, groupBy, mapValues } from 'lodash'; import _, { countBy, groupBy, mapValues } from 'lodash';
import { APICaller, CoreSetup } from 'kibana/server'; import { APICaller, IClusterClient } from 'src/core/server';
import { getNextMidnight } from '../../get_next_midnight'; import { getNextMidnight } from '../../get_next_midnight';
import { TaskInstance } from '../../../../../task_manager/server'; import { TaskInstance } from '../../../../../task_manager/server';
import { ESSearchHit } from '../../../../../apm/typings/elasticsearch'; import { ESSearchHit } from '../../../../../apm/typings/elasticsearch';
@ -73,17 +73,15 @@ async function getStats(callCluster: APICaller, index: string) {
export function visualizationsTaskRunner( export function visualizationsTaskRunner(
taskInstance: TaskInstance, taskInstance: TaskInstance,
config: Observable<{ kibana: { index: string } }>, config: Observable<{ kibana: { index: string } }>,
es: CoreSetup['elasticsearch'] esClientPromise: Promise<IClusterClient>
) { ) {
const { callAsInternalUser: callCluster } = es.createClient('data');
return async () => { return async () => {
let stats; let stats;
let error; let error;
try { try {
const index = (await config.toPromise()).kibana.index; const index = (await config.toPromise()).kibana.index;
stats = await getStats(callCluster, index); stats = await getStats((await esClientPromise).callAsInternalUser, index);
} catch (err) { } catch (err) {
if (err.constructor === Error) { if (err.constructor === Error) {
error = err.message; error = err.message;

View file

@ -35,7 +35,7 @@ export class OssTelemetryPlugin implements Plugin {
registerTasks({ registerTasks({
taskManager: deps.taskManager, taskManager: deps.taskManager,
logger: this.logger, logger: this.logger,
elasticsearch: core.elasticsearch, getStartServices: core.getStartServices,
config: this.config, config: this.config,
}); });
registerCollectors( registerCollectors(

View file

@ -4,9 +4,10 @@
* you may not use this file except in compliance with the Elastic License. * you may not use this file except in compliance with the Elastic License.
*/ */
import { APICaller, CoreSetup } from 'kibana/server'; import { APICaller } from 'kibana/server';
import { of } from 'rxjs'; import { of } from 'rxjs';
import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks';
import { import {
ConcreteTaskInstance, ConcreteTaskInstance,
TaskStatus, TaskStatus,
@ -43,10 +44,11 @@ const defaultMockSavedObjects = [
const defaultMockTaskDocs = [getMockTaskInstance()]; const defaultMockTaskDocs = [getMockTaskInstance()];
export const getMockEs = (mockCallWithInternal: APICaller = getMockCallWithInternal()) => export const getMockEs = async (mockCallWithInternal: APICaller = getMockCallWithInternal()) => {
(({ const client = elasticsearchServiceMock.createClusterClient();
createClient: () => ({ callAsInternalUser: mockCallWithInternal }), (client.callAsInternalUser as any) = mockCallWithInternal;
} as unknown) as CoreSetup['elasticsearch']); return client;
};
export const getMockCallWithInternal = (hits: unknown[] = defaultMockSavedObjects): APICaller => { export const getMockCallWithInternal = (hits: unknown[] = defaultMockSavedObjects): APICaller => {
return ((() => { return ((() => {

View file

@ -29,15 +29,9 @@ export class RemoteClustersServerPlugin implements Plugin<void, void, any, any>
this.licenseStatus = { valid: false }; this.licenseStatus = { valid: false };
} }
async setup( async setup({ http }: CoreSetup, { licensing, cloud }: Dependencies) {
{ http, elasticsearch: elasticsearchService }: CoreSetup,
{ licensing, cloud }: Dependencies
) {
const elasticsearch = await elasticsearchService.adminClient;
const router = http.createRouter(); const router = http.createRouter();
const routeDependencies: RouteDependencies = { const routeDependencies: RouteDependencies = {
elasticsearch,
elasticsearchService,
router, router,
getLicenseStatus: () => this.licenseStatus, getLicenseStatus: () => this.licenseStatus,
config: { config: {

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License. * you may not use this file except in compliance with the Elastic License.
*/ */
import { IRouter, ElasticsearchServiceSetup, IClusterClient } from 'kibana/server'; import { IRouter } from 'kibana/server';
import { LicensingPluginSetup } from '../../licensing/server'; import { LicensingPluginSetup } from '../../licensing/server';
import { CloudSetup } from '../../cloud/server'; import { CloudSetup } from '../../cloud/server';
@ -16,8 +16,6 @@ export interface Dependencies {
export interface RouteDependencies { export interface RouteDependencies {
router: IRouter; router: IRouter;
getLicenseStatus: () => LicenseStatus; getLicenseStatus: () => LicenseStatus;
elasticsearchService: ElasticsearchServiceSetup;
elasticsearch: IClusterClient;
config: { config: {
isCloudEnabled: boolean; isCloudEnabled: boolean;
}; };

View file

@ -38,17 +38,16 @@ export class TaskManagerPlugin
public setup(core: CoreSetup, plugins: any): TaskManagerSetupContract { public setup(core: CoreSetup, plugins: any): TaskManagerSetupContract {
const logger = this.initContext.logger.get('taskManager'); const logger = this.initContext.logger.get('taskManager');
const config$ = this.initContext.config.create<TaskManagerConfig>(); const config$ = this.initContext.config.create<TaskManagerConfig>();
const elasticsearch = core.elasticsearch.adminClient;
return { return {
registerLegacyAPI: once((__LEGACY: PluginLegacyDependencies) => { registerLegacyAPI: once((__LEGACY: PluginLegacyDependencies) => {
config$.subscribe(async config => { config$.subscribe(async config => {
const [{ savedObjects }] = await core.getStartServices(); const [{ savedObjects, elasticsearch }] = await core.getStartServices();
const savedObjectsRepository = savedObjects.createInternalRepository(['task']); const savedObjectsRepository = savedObjects.createInternalRepository(['task']);
this.legacyTaskManager$.next( this.legacyTaskManager$.next(
createTaskManager(core, { createTaskManager(core, {
logger, logger,
config, config,
elasticsearch, elasticsearch: elasticsearch.legacy.client,
savedObjectsRepository, savedObjectsRepository,
savedObjectsSerializer: savedObjects.createSerializer(), savedObjectsSerializer: savedObjects.createSerializer(),
}) })

View file

@ -58,7 +58,7 @@ describe('Upgrade Assistant Usage Collector', () => {
}), }),
}, },
elasticsearch: { elasticsearch: {
adminClient: clusterClient, legacy: { client: clusterClient },
}, },
}; };
}); });

View file

@ -7,7 +7,7 @@
import { set } from 'lodash'; import { set } from 'lodash';
import { import {
APICaller, APICaller,
ElasticsearchServiceSetup, ElasticsearchServiceStart,
ISavedObjectsRepository, ISavedObjectsRepository,
SavedObjectsServiceStart, SavedObjectsServiceStart,
} from 'src/core/server'; } from 'src/core/server';
@ -51,7 +51,7 @@ async function getDeprecationLoggingStatusValue(callAsCurrentUser: APICaller): P
} }
export async function fetchUpgradeAssistantMetrics( export async function fetchUpgradeAssistantMetrics(
{ adminClient }: ElasticsearchServiceSetup, { legacy: { client: esClient } }: ElasticsearchServiceStart,
savedObjects: SavedObjectsServiceStart savedObjects: SavedObjectsServiceStart
): Promise<UpgradeAssistantTelemetry> { ): Promise<UpgradeAssistantTelemetry> {
const savedObjectsRepository = savedObjects.createInternalRepository(); const savedObjectsRepository = savedObjects.createInternalRepository();
@ -60,7 +60,7 @@ export async function fetchUpgradeAssistantMetrics(
UPGRADE_ASSISTANT_TYPE, UPGRADE_ASSISTANT_TYPE,
UPGRADE_ASSISTANT_DOC_ID UPGRADE_ASSISTANT_DOC_ID
); );
const callAsInternalUser = adminClient.callAsInternalUser.bind(adminClient); const callAsInternalUser = esClient.callAsInternalUser.bind(esClient);
const deprecationLoggingStatusValue = await getDeprecationLoggingStatusValue(callAsInternalUser); const deprecationLoggingStatusValue = await getDeprecationLoggingStatusValue(callAsInternalUser);
const getTelemetrySavedObject = ( const getTelemetrySavedObject = (
@ -107,7 +107,7 @@ export async function fetchUpgradeAssistantMetrics(
} }
interface Dependencies { interface Dependencies {
elasticsearch: ElasticsearchServiceSetup; elasticsearch: ElasticsearchServiceStart;
savedObjects: SavedObjectsServiceStart; savedObjects: SavedObjectsServiceStart;
usageCollection: UsageCollectionSetup; usageCollection: UsageCollectionSetup;
} }

View file

@ -11,7 +11,6 @@ import {
CoreStart, CoreStart,
PluginInitializerContext, PluginInitializerContext,
Logger, Logger,
ElasticsearchServiceSetup,
SavedObjectsClient, SavedObjectsClient,
SavedObjectsServiceStart, SavedObjectsServiceStart,
} from '../../../../src/core/server'; } from '../../../../src/core/server';
@ -40,7 +39,6 @@ export class UpgradeAssistantServerPlugin implements Plugin {
// Properties set at setup // Properties set at setup
private licensing?: LicensingPluginSetup; private licensing?: LicensingPluginSetup;
private elasticSearchService?: ElasticsearchServiceSetup;
// Properties set at start // Properties set at start
private savedObjectsServiceStart?: SavedObjectsServiceStart; private savedObjectsServiceStart?: SavedObjectsServiceStart;
@ -59,10 +57,9 @@ export class UpgradeAssistantServerPlugin implements Plugin {
} }
setup( setup(
{ http, elasticsearch, getStartServices, capabilities }: CoreSetup, { http, getStartServices, capabilities }: CoreSetup,
{ usageCollection, cloud, licensing }: PluginsSetup { usageCollection, cloud, licensing }: PluginsSetup
) { ) {
this.elasticSearchService = elasticsearch;
this.licensing = licensing; this.licensing = licensing;
const router = http.createRouter(); const router = http.createRouter();
@ -88,13 +85,13 @@ export class UpgradeAssistantServerPlugin implements Plugin {
registerTelemetryRoutes(dependencies); registerTelemetryRoutes(dependencies);
if (usageCollection) { if (usageCollection) {
getStartServices().then(([{ savedObjects }]) => { getStartServices().then(([{ savedObjects, elasticsearch }]) => {
registerUpgradeAssistantUsageCollector({ elasticsearch, usageCollection, savedObjects }); registerUpgradeAssistantUsageCollector({ elasticsearch, usageCollection, savedObjects });
}); });
} }
} }
start({ savedObjects }: CoreStart) { start({ savedObjects, elasticsearch }: CoreStart) {
this.savedObjectsServiceStart = savedObjects; this.savedObjectsServiceStart = savedObjects;
// The ReindexWorker uses a map of request headers that contain the authentication credentials // The ReindexWorker uses a map of request headers that contain the authentication credentials
@ -107,7 +104,7 @@ export class UpgradeAssistantServerPlugin implements Plugin {
this.worker = createReindexWorker({ this.worker = createReindexWorker({
credentialStore: this.credentialStore, credentialStore: this.credentialStore,
licensing: this.licensing!, licensing: this.licensing!,
elasticsearchService: this.elasticSearchService!, elasticsearchService: elasticsearch,
logger: this.logger, logger: this.logger,
savedObjects: new SavedObjectsClient( savedObjects: new SavedObjectsClient(
this.savedObjectsServiceStart.createInternalRepository() this.savedObjectsServiceStart.createInternalRepository()

View file

@ -5,7 +5,7 @@
*/ */
import { schema } from '@kbn/config-schema'; import { schema } from '@kbn/config-schema';
import { import {
ElasticsearchServiceSetup, ElasticsearchServiceStart,
kibanaResponseFactory, kibanaResponseFactory,
Logger, Logger,
SavedObjectsClient, SavedObjectsClient,
@ -38,7 +38,7 @@ import { GetBatchQueueResponse, PostBatchResponse } from './types';
interface CreateReindexWorker { interface CreateReindexWorker {
logger: Logger; logger: Logger;
elasticsearchService: ElasticsearchServiceSetup; elasticsearchService: ElasticsearchServiceStart;
credentialStore: CredentialStore; credentialStore: CredentialStore;
savedObjects: SavedObjectsClient; savedObjects: SavedObjectsClient;
licensing: LicensingPluginSetup; licensing: LicensingPluginSetup;
@ -51,8 +51,8 @@ export function createReindexWorker({
savedObjects, savedObjects,
licensing, licensing,
}: CreateReindexWorker) { }: CreateReindexWorker) {
const { adminClient } = elasticsearchService; const esClient = elasticsearchService.legacy.client;
return new ReindexWorker(savedObjects, credentialStore, adminClient, logger, licensing); return new ReindexWorker(savedObjects, credentialStore, esClient, logger, licensing);
} }
const mapAnyErrorToKibanaHttpResponse = (e: any) => { const mapAnyErrorToKibanaHttpResponse = (e: any) => {