Skip to content

Commit

Permalink
[Index management] Server-side NP ready (elastic#56829)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebelga authored Feb 11, 2020
1 parent bb7e152 commit 7e9d797
Show file tree
Hide file tree
Showing 42 changed files with 1,148 additions and 498 deletions.
11 changes: 8 additions & 3 deletions x-pack/legacy/plugins/cross_cluster_replication/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { PLUGIN } from './common/constants';
import { registerLicenseChecker } from './server/lib/register_license_checker';
import { registerRoutes } from './server/routes/register_routes';
import { ccrDataEnricher } from './cross_cluster_replication_data';
import { addIndexManagementDataEnricher } from '../index_management/server/index_management_data';

export function crossClusterReplication(kibana) {
return new kibana.Plugin({
id: PLUGIN.ID,
Expand Down Expand Up @@ -49,8 +49,13 @@ export function crossClusterReplication(kibana) {
init: function initCcrPlugin(server) {
registerLicenseChecker(server);
registerRoutes(server);
if (server.config().get('xpack.ccr.ui.enabled')) {
addIndexManagementDataEnricher(ccrDataEnricher);

if (
server.config().get('xpack.ccr.ui.enabled') &&
server.plugins.index_management &&
server.plugins.index_management.addIndexManagementDataEnricher
) {
server.plugins.index_management.addIndexManagementDataEnricher(ccrDataEnricher);
}
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { LICENSE_TYPE_BASIC } from '../../../../common/constants';
import { LicenseType } from '../../../../../plugins/licensing/common/types';

const basicLicense: LicenseType = 'basic';

export const PLUGIN = {
ID: 'index_management',
id: 'index_management',
minimumLicenseType: basicLicense,
getI18nName: (i18n: any): string =>
i18n.translate('xpack.idxMgmt.appTitle', {
defaultMessage: 'Index Management',
}),
MINIMUM_LICENSE_REQUIRED: LICENSE_TYPE_BASIC,
};
7 changes: 7 additions & 0 deletions x-pack/legacy/plugins/index_management/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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.
*/

export { PLUGIN, API_BASE_PATH } from './constants';
39 changes: 9 additions & 30 deletions x-pack/legacy/plugins/index_management/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,15 @@
*/

import { resolve } from 'path';
import { i18n } from '@kbn/i18n';
import { Legacy } from 'kibana';
import { createRouter } from '../../server/lib/create_router';
import { registerLicenseChecker } from '../../server/lib/register_license_checker';
import { PLUGIN, API_BASE_PATH } from './common/constants';
import { LegacySetup } from './server/plugin';
import { plugin as initServerPlugin } from './server';
import { PLUGIN } from './common/constants';
import { plugin as initServerPlugin, Dependencies } from './server';

export type ServerFacade = Legacy.Server;

export function indexManagement(kibana: any) {
return new kibana.Plugin({
id: PLUGIN.ID,
id: PLUGIN.id,
configPrefix: 'xpack.index_management',
publicDir: resolve(__dirname, 'public'),
require: ['kibana', 'elasticsearch', 'xpack_main'],
Expand All @@ -29,32 +25,15 @@ export function indexManagement(kibana: any) {

init(server: ServerFacade) {
const coreSetup = server.newPlatform.setup.core;

const pluginsSetup = {};

const __LEGACY: LegacySetup = {
router: createRouter(server, PLUGIN.ID, `${API_BASE_PATH}/`),
plugins: {
license: {
registerLicenseChecker: registerLicenseChecker.bind(
null,
server,
PLUGIN.ID,
PLUGIN.getI18nName(i18n),
PLUGIN.MINIMUM_LICENSE_REQUIRED as 'basic'
),
},
elasticsearch: server.plugins.elasticsearch,
},
const coreInitializerContext = server.newPlatform.coreContext;
const pluginsSetup: Dependencies = {
licensing: server.newPlatform.setup.plugins.licensing as any,
};

const serverPlugin = initServerPlugin();
const indexMgmtSetup = serverPlugin.setup(coreSetup, pluginsSetup, __LEGACY);
const serverPlugin = initServerPlugin(coreInitializerContext as any);
const serverPublicApi = serverPlugin.setup(coreSetup, pluginsSetup);

server.expose(
'addIndexManagementDataEnricher',
indexMgmtSetup.addIndexManagementDataEnricher
);
server.expose('addIndexManagementDataEnricher', serverPublicApi.indexDataEnricher.add);
},
});
}
10 changes: 6 additions & 4 deletions x-pack/legacy/plugins/index_management/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { IndexMgmtPlugin } from './plugin';

export function plugin() {
return new IndexMgmtPlugin();
}
import { PluginInitializerContext } from 'src/core/server';
import { IndexMgmtServerPlugin } from './plugin';

export const plugin = (ctx: PluginInitializerContext) => new IndexMgmtServerPlugin(ctx);

export { Dependencies } from './types';

This file was deleted.

41 changes: 16 additions & 25 deletions x-pack/legacy/plugins/index_management/server/lib/fetch_indices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { IndexDataEnricher } from '../services';
import { Index, CallAsCurrentUser } from '../types';
import { fetchAliases } from './fetch_aliases';
import { getIndexManagementDataEnrichers } from '../index_management_data';

interface Hit {
health: string;
status: string;
Expand All @@ -27,22 +29,7 @@ interface Params {
index?: string[];
}

const enrichResponse = async (response: any, callWithRequest: any) => {
let enrichedResponse = response;
const dataEnrichers = getIndexManagementDataEnrichers();
for (let i = 0; i < dataEnrichers.length; i++) {
const dataEnricher = dataEnrichers[i];
try {
const dataEnricherResponse = await dataEnricher(enrichedResponse, callWithRequest);
enrichedResponse = dataEnricherResponse;
} catch (e) {
// silently swallow enricher response errors
}
}
return enrichedResponse;
};

function formatHits(hits: Hit[], aliases: Aliases) {
function formatHits(hits: Hit[], aliases: Aliases): Index[] {
return hits.map((hit: Hit) => {
return {
health: hit.health,
Expand All @@ -59,7 +46,7 @@ function formatHits(hits: Hit[], aliases: Aliases) {
});
}

async function fetchIndicesCall(callWithRequest: any, indexNames?: string[]) {
async function fetchIndicesCall(callAsCurrentUser: CallAsCurrentUser, indexNames?: string[]) {
const params: Params = {
format: 'json',
h: 'health,status,index,uuid,pri,rep,docs.count,sth,store.size',
Expand All @@ -69,13 +56,17 @@ async function fetchIndicesCall(callWithRequest: any, indexNames?: string[]) {
params.index = indexNames;
}

return await callWithRequest('cat.indices', params);
return await callAsCurrentUser('cat.indices', params);
}

export const fetchIndices = async (callWithRequest: any, indexNames?: string[]) => {
const aliases = await fetchAliases(callWithRequest);
const hits = await fetchIndicesCall(callWithRequest, indexNames);
let response = formatHits(hits, aliases);
response = await enrichResponse(response, callWithRequest);
return response;
export const fetchIndices = async (
callAsCurrentUser: CallAsCurrentUser,
indexDataEnricher: IndexDataEnricher,
indexNames?: string[]
) => {
const aliases = await fetchAliases(callAsCurrentUser);
const hits = await fetchIndicesCall(callAsCurrentUser, indexNames);
const indices = formatHits(hits, aliases);

return await indexDataEnricher.enrichIndices(indices, callAsCurrentUser);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
// Cloud has its own system for managing templates and we want to make
// this clear in the UI when a template is used in a Cloud deployment.
export const getManagedTemplatePrefix = async (
callWithInternalUser: any
callAsCurrentUser: any
): Promise<string | undefined> => {
try {
const { persistent, transient, defaults } = await callWithInternalUser('cluster.getSettings', {
const { persistent, transient, defaults } = await callAsCurrentUser('cluster.getSettings', {
filterPath: '*.*managed_index_templates',
flatSettings: true,
includeDefaults: true,
Expand Down
13 changes: 13 additions & 0 deletions x-pack/legacy/plugins/index_management/server/lib/is_es_error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* 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 * as legacyElasticsearch from 'elasticsearch';

const esErrorsParent = legacyElasticsearch.errors._Abstract;

export function isEsError(err: Error) {
return err instanceof esErrorsParent;
}
87 changes: 53 additions & 34 deletions x-pack/legacy/plugins/index_management/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,67 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import { CoreSetup } from 'src/core/server';
import { ElasticsearchPlugin } from 'src/legacy/core_plugins/elasticsearch';
import { Router } from '../../../server/lib/create_router';
import { addIndexManagementDataEnricher } from './index_management_data';
import { registerIndicesRoutes } from './routes/api/indices';
import { registerTemplateRoutes } from './routes/api/templates';
import { registerMappingRoute } from './routes/api/mapping';
import { registerSettingsRoutes } from './routes/api/settings';
import { registerStatsRoute } from './routes/api/stats';

export interface LegacySetup {
router: Router;
plugins: {
elasticsearch: ElasticsearchPlugin;
license: {
registerLicenseChecker: () => void;
};
};
}
import { i18n } from '@kbn/i18n';
import { CoreSetup, Plugin, Logger, PluginInitializerContext } from 'src/core/server';

import { PLUGIN } from '../common';
import { Dependencies } from './types';
import { ApiRoutes } from './routes';
import { License, IndexDataEnricher } from './services';
import { isEsError } from './lib/is_es_error';

export interface IndexMgmtSetup {
addIndexManagementDataEnricher: (enricher: any) => void;
indexDataEnricher: {
add: IndexDataEnricher['add'];
};
}

export class IndexMgmtPlugin {
public setup(core: CoreSetup, plugins: {}, __LEGACY: LegacySetup): IndexMgmtSetup {
const serverFacade = {
plugins: {
elasticsearch: __LEGACY.plugins.elasticsearch,
},
};
export class IndexMgmtServerPlugin implements Plugin<IndexMgmtSetup, void, any, any> {
private readonly apiRoutes: ApiRoutes;
private readonly license: License;
private readonly logger: Logger;
private readonly indexDataEnricher: IndexDataEnricher;

__LEGACY.plugins.license.registerLicenseChecker();
constructor({ logger }: PluginInitializerContext) {
this.logger = logger.get();
this.apiRoutes = new ApiRoutes();
this.license = new License();
this.indexDataEnricher = new IndexDataEnricher();
}

setup({ http }: CoreSetup, { licensing }: Dependencies): IndexMgmtSetup {
const router = http.createRouter();

registerIndicesRoutes(__LEGACY.router);
registerTemplateRoutes(__LEGACY.router, serverFacade);
registerSettingsRoutes(__LEGACY.router);
registerStatsRoute(__LEGACY.router);
registerMappingRoute(__LEGACY.router);
this.license.setup(
{
pluginId: PLUGIN.id,
minimumLicenseType: PLUGIN.minimumLicenseType,
defaultErrorMessage: i18n.translate('xpack.idxMgmt.licenseCheckErrorMessage', {
defaultMessage: 'License check failed',
}),
},
{
licensing,
logger: this.logger,
}
);

this.apiRoutes.setup({
router,
license: this.license,
indexDataEnricher: this.indexDataEnricher,
lib: {
isEsError,
},
});

return {
addIndexManagementDataEnricher,
indexDataEnricher: {
add: this.indexDataEnricher.add.bind(this.indexDataEnricher),
},
};
}

start() {}
stop() {}
}
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;
* you may not use this file except in compliance with the Elastic License.
*/

import { API_BASE_PATH } from '../../../common';

export const addBasePath = (uri: string): string => API_BASE_PATH + uri;
Loading

0 comments on commit 7e9d797

Please sign in to comment.