[esArchiver] only load uiExports for xpack when necessary (#30474) (#30718)

* [esArchiver] only load uiExports for xpack when necessary

* [esArchiver/kibanaIndex] remove caches, node caches modules so uiExports shouldn't be too bad

* [esArchiver/cli] include command name in error

* [esArchiver/kibana] include error in new message

* remove comment about caching
This commit is contained in:
Spencer 2019-02-11 18:52:32 -08:00 committed by GitHub
parent df07f97450
commit 870c8b3fb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 19 deletions

View file

@ -18,9 +18,9 @@
*/
import { migrateKibanaIndex, deleteKibanaIndices, createStats } from '../lib';
export async function emptyKibanaIndexAction({ client, log }) {
export async function emptyKibanaIndexAction({ client, log, kibanaUrl }) {
const stats = createStats('emptyKibanaIndex', log);
await deleteKibanaIndices({ client, stats });
await migrateKibanaIndex({ client, log, stats });
await migrateKibanaIndex({ client, log, stats, kibanaUrl });
return stats;
}

View file

@ -88,7 +88,7 @@ export async function loadAction({ name, skipExisting, client, dataDir, log, kib
// If we affected the Kibana index, we need to ensure it's migrated...
if (Object.keys(result).some(k => k.startsWith('.kibana'))) {
await migrateKibanaIndex({ client, log });
await migrateKibanaIndex({ client, log, kibanaUrl });
}
return result;

View file

@ -64,6 +64,10 @@ cmd.command('unload <name>')
.description('remove indices created by the archive in --dir with <name>')
.action(name => execute(archiver => archiver.unload(name)));
cmd.command('empty-kibana-index')
.description('[internal] Delete any Kibana indices, and initialize the Kibana index as Kibana would do on startup.')
.action(() => execute(archiver => archiver.emptyKibanaIndex()));
cmd.command('rebuild-all')
.description('[internal] read and write all archives in --dir to remove any inconsistencies')
.action(() => execute(archiver => archiver.rebuildAll()));
@ -97,6 +101,10 @@ async function execute(fn) {
log.error(msg);
};
if (!fn) {
error(`Unknown command "${cmd.args[0]}"`);
}
if (!cmd.esUrl) {
error('You must specify either --es-url or --config flags');
}

View file

@ -126,6 +126,7 @@ export class EsArchiver {
await emptyKibanaIndexAction({
client: this.client,
log: this.log,
kibanaUrl: this.kibanaUrl,
});
}
}

View file

@ -30,19 +30,25 @@ import { KibanaMigrator } from '../../../legacy/server/saved_objects/migrations'
import { findPluginSpecs } from '../../../legacy/plugin_discovery';
/**
* This is an expensive operation, so we'll ensure it only happens once
* Load the uiExports for a Kibana instance, only load uiExports from xpack if
* it is enabled in the Kibana server.
*/
const buildUiExports = _.once(async () => {
const getUiExports = async (kibanaUrl) => {
const xpackEnabled = await getKibanaPluginEnabled({
kibanaUrl,
pluginId: 'xpack_main'
});
const { spec$ } = await findPluginSpecs({
plugins: {
scanDirs: [path.resolve(__dirname, '../../../legacy/core_plugins')],
paths: [path.resolve(__dirname, '../../../../x-pack')],
paths: xpackEnabled ? [path.resolve(__dirname, '../../../../x-pack')] : [],
},
});
const specs = await spec$.pipe(toArray()).toPromise();
return collectUiExports(specs);
});
};
/**
* Deletes all indices that start with `.kibana`
@ -73,8 +79,8 @@ export async function deleteKibanaIndices({ client, stats, log }) {
* builds up an object that implements just enough of the kbnMigrations interface
* as is required by migrations.
*/
export async function migrateKibanaIndex({ client, log }) {
const uiExports = await buildUiExports();
export async function migrateKibanaIndex({ client, log, kibanaUrl }) {
const uiExports = await getUiExports(kibanaUrl);
const version = await loadElasticVersion();
const config = {
'kibana.index': '.kibana',
@ -112,25 +118,24 @@ async function loadElasticVersion() {
return JSON.parse(packageJson).version;
}
const spacesEnabledCache = new Map();
export async function isSpacesEnabled({ kibanaUrl }) {
if (!spacesEnabledCache.has(kibanaUrl)) {
const statuses = await getKibanaStatuses({ kibanaUrl });
spacesEnabledCache.set(kibanaUrl, !!statuses.find(({ id }) => id.startsWith('plugin:spaces@')));
}
return spacesEnabledCache.get(kibanaUrl);
return await getKibanaPluginEnabled({
kibanaUrl,
pluginId: 'spaces'
});
}
async function getKibanaStatuses({ kibanaUrl }) {
async function getKibanaPluginEnabled({ pluginId, kibanaUrl }) {
try {
const { payload } = await wreck.get('/api/status', {
baseUrl: kibanaUrl,
json: true
});
return payload.status.statuses;
return payload.status.statuses
.some(({ id }) => id.includes(`plugin:${pluginId}@`));
} catch (error) {
throw new Error(`Unable to fetch Kibana status API response from Kibana at ${kibanaUrl}`);
throw new Error(`Unable to fetch Kibana status API response from Kibana at ${kibanaUrl}: ${error}`);
}
}