kibana/x-pack/plugins/fleet/public/plugin.ts
2021-04-15 01:22:32 -04:00

201 lines
6.8 KiB
TypeScript

/*
* 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 {
AppMountParameters,
CoreSetup,
Plugin,
PluginInitializerContext,
CoreStart,
} from 'src/core/public';
import { i18n } from '@kbn/i18n';
import { DEFAULT_APP_CATEGORIES, AppNavLinkStatus } from '../../../../src/core/public';
import type {
DataPublicPluginSetup,
DataPublicPluginStart,
} from '../../../../src/plugins/data/public';
import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public';
import type { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
import { Storage } from '../../../../src/plugins/kibana_utils/public';
import type { LicensingPluginSetup } from '../../licensing/public';
import type { CloudSetup } from '../../cloud/public';
import { PLUGIN_ID, setupRouteService, appRoutesService } from '../common';
import type { CheckPermissionsResponse, PostIngestSetupResponse } from '../common';
import type { FleetConfigType } from '../common/types';
import { BASE_PATH } from './applications/fleet/constants';
import { licenseService } from './applications/fleet/hooks/use_license';
import { setHttpClient } from './applications/fleet/hooks/use_request/use_request';
import {
TutorialDirectoryNotice,
TutorialDirectoryHeaderLink,
TutorialModuleNotice,
} from './applications/fleet/components/home_integration';
import { createExtensionRegistrationCallback } from './applications/fleet/services/ui_extensions';
import type {
UIExtensionRegistrationCallback,
UIExtensionsStorage,
} from './applications/fleet/types';
export { FleetConfigType } from '../common/types';
// We need to provide an object instead of void so that dependent plugins know when Fleet
// is disabled.
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface FleetSetup {}
/**
* Describes public Fleet plugin contract returned at the `start` stage.
*/
export interface FleetStart {
registerExtension: UIExtensionRegistrationCallback;
isInitialized: () => Promise<true>;
}
export interface FleetSetupDeps {
licensing: LicensingPluginSetup;
data: DataPublicPluginSetup;
home?: HomePublicPluginSetup;
cloud?: CloudSetup;
}
export interface FleetStartDeps {
data: DataPublicPluginStart;
}
export interface FleetStartServices extends CoreStart, FleetStartDeps {
storage: Storage;
cloud?: CloudSetup;
}
export class FleetPlugin implements Plugin<FleetSetup, FleetStart, FleetSetupDeps, FleetStartDeps> {
private config: FleetConfigType;
private kibanaVersion: string;
private extensions: UIExtensionsStorage = {};
private storage = new Storage(localStorage);
constructor(private readonly initializerContext: PluginInitializerContext) {
this.config = this.initializerContext.config.get<FleetConfigType>();
this.kibanaVersion = initializerContext.env.packageInfo.version;
}
public setup(core: CoreSetup, deps: FleetSetupDeps) {
const config = this.config;
const kibanaVersion = this.kibanaVersion;
const extensions = this.extensions;
// Set up http client
setHttpClient(core.http);
// Set up license service
licenseService.start(deps.licensing.license$);
// Register main Fleet app
core.application.register({
id: PLUGIN_ID,
category: DEFAULT_APP_CATEGORIES.management,
title: i18n.translate('xpack.fleet.appTitle', { defaultMessage: 'Fleet' }),
order: 9020,
euiIconType: 'logoElastic',
mount: async (params: AppMountParameters) => {
const [coreStartServices, startDepsServices] = (await core.getStartServices()) as [
CoreStart,
FleetStartDeps,
FleetStart
];
const startServices: FleetStartServices = {
...coreStartServices,
...startDepsServices,
storage: this.storage,
cloud: deps.cloud,
};
const { renderApp, teardownFleet } = await import('./applications/fleet');
const unmount = renderApp(startServices, params, config, kibanaVersion, extensions);
return () => {
unmount();
teardownFleet(startServices);
};
},
});
// BWC < 7.11 redirect /app/ingestManager to /app/fleet
core.application.register({
id: 'ingestManager',
category: DEFAULT_APP_CATEGORIES.management,
navLinkStatus: AppNavLinkStatus.hidden,
title: i18n.translate('xpack.fleet.oldAppTitle', { defaultMessage: 'Ingest Manager' }),
async mount(params: AppMountParameters) {
const [coreStart] = await core.getStartServices();
coreStart.application.navigateToApp('fleet', {
path: params.history.location.hash,
});
return () => {};
},
});
// Register components for home/add data integration
if (deps.home) {
deps.home.tutorials.registerDirectoryNotice(PLUGIN_ID, TutorialDirectoryNotice);
deps.home.tutorials.registerDirectoryHeaderLink(PLUGIN_ID, TutorialDirectoryHeaderLink);
deps.home.tutorials.registerModuleNotice(PLUGIN_ID, TutorialModuleNotice);
deps.home.featureCatalogue.register({
id: 'fleet',
title: i18n.translate('xpack.fleet.featureCatalogueTitle', {
defaultMessage: 'Add Elastic Agent',
}),
description: i18n.translate('xpack.fleet.featureCatalogueDescription', {
defaultMessage: 'Add and manage your fleet of Elastic Agents and integrations.',
}),
icon: 'indexManagementApp',
showOnHomePage: true,
path: BASE_PATH,
category: FeatureCatalogueCategory.DATA,
order: 510,
});
}
return {};
}
public start(core: CoreStart): FleetStart {
let successPromise: ReturnType<FleetStart['isInitialized']>;
return {
isInitialized: () => {
if (!successPromise) {
successPromise = Promise.resolve().then(async () => {
const permissionsResponse = await core.http.get<CheckPermissionsResponse>(
appRoutesService.getCheckPermissionsPath()
);
if (permissionsResponse?.success) {
return core.http
.post<PostIngestSetupResponse>(setupRouteService.getSetupPath())
.then(({ isInitialized }) =>
isInitialized
? Promise.resolve(true)
: Promise.reject(new Error('Unknown setup error'))
);
} else {
throw new Error(permissionsResponse?.error || 'Unknown permissions error');
}
});
}
return successPromise;
},
registerExtension: createExtensionRegistrationCallback(this.extensions),
};
}
public stop() {}
}