"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.FleetPlugin = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _rxjs = require("rxjs"); var _operators = require("rxjs/operators"); var _common = require("@kbn/spaces-plugin/common"); var _i18n = require("@kbn/i18n"); var _server = require("@kbn/core/server"); var _coreSavedObjectsServer = require("@kbn/core-saved-objects-server"); var _common2 = require("../common"); var _experimental_features = require("../common/experimental_features"); var _get_files_client_factory = require("./services/files/get_files_client_factory"); var _security = require("./services/security"); var _constants = require("./constants"); var _saved_objects = require("./saved_objects"); var _routes = require("./routes"); var _services = require("./services"); var _register = require("./collectors/register"); var _artifacts = require("./services/artifacts"); var _sender = require("./telemetry/sender"); var _setup = require("./services/setup"); var _agents = require("./services/agents"); var _package_policy = require("./services/package_policy"); var _fleet_usage_logger = require("./services/fleet_usage_logger"); var _check_deleted_files_task = require("./tasks/check_deleted_files_task"); var _uninstall_token_service = require("./services/security/uninstall_token_service"); var _actions = require("./services/actions"); var _agent_policy_watch = require("./services/agent_policy_watch"); var _tag_assets = require("./services/epm/kibana/assets/tag_assets"); /* * 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. */ const allSavedObjectTypes = [_constants.OUTPUT_SAVED_OBJECT_TYPE, _constants.AGENT_POLICY_SAVED_OBJECT_TYPE, _constants.PACKAGE_POLICY_SAVED_OBJECT_TYPE, _constants.PACKAGES_SAVED_OBJECT_TYPE, _constants.ASSETS_SAVED_OBJECT_TYPE, _constants.PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, _constants.DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, _constants.FLEET_SERVER_HOST_SAVED_OBJECT_TYPE]; /** * Describes public Fleet plugin contract returned at the `startup` stage. */ class FleetPlugin { constructor(initializerContext) { (0, _defineProperty2.default)(this, "config$", void 0); (0, _defineProperty2.default)(this, "configInitialValue", void 0); (0, _defineProperty2.default)(this, "cloud", void 0); (0, _defineProperty2.default)(this, "logger", void 0); (0, _defineProperty2.default)(this, "isProductionMode", void 0); (0, _defineProperty2.default)(this, "kibanaVersion", void 0); (0, _defineProperty2.default)(this, "kibanaBranch", void 0); (0, _defineProperty2.default)(this, "httpSetup", void 0); (0, _defineProperty2.default)(this, "securitySetup", void 0); (0, _defineProperty2.default)(this, "encryptedSavedObjectsSetup", void 0); (0, _defineProperty2.default)(this, "telemetryEventsSender", void 0); (0, _defineProperty2.default)(this, "fleetStatus$", void 0); (0, _defineProperty2.default)(this, "bulkActionsResolver", void 0); (0, _defineProperty2.default)(this, "fleetUsageSender", void 0); (0, _defineProperty2.default)(this, "checkDeletedFilesTask", void 0); (0, _defineProperty2.default)(this, "agentService", void 0); (0, _defineProperty2.default)(this, "packageService", void 0); (0, _defineProperty2.default)(this, "packagePolicyService", void 0); (0, _defineProperty2.default)(this, "policyWatcher", void 0); this.initializerContext = initializerContext; this.config$ = this.initializerContext.config.create(); this.isProductionMode = this.initializerContext.env.mode.prod; this.kibanaVersion = this.initializerContext.env.packageInfo.version; this.kibanaBranch = this.initializerContext.env.packageInfo.branch; this.logger = this.initializerContext.logger.get(); this.configInitialValue = this.initializerContext.config.get(); this.telemetryEventsSender = new _sender.TelemetryEventsSender(this.logger.get('telemetry_events')); this.fleetStatus$ = new _rxjs.BehaviorSubject({ level: _server.ServiceStatusLevels.unavailable, summary: 'Fleet is unavailable' }); } setup(core, deps) { this.httpSetup = core.http; this.encryptedSavedObjectsSetup = deps.encryptedSavedObjects; this.cloud = deps.cloud; this.securitySetup = deps.security; const config = this.configInitialValue; core.status.set(this.fleetStatus$.asObservable()); (0, _saved_objects.registerSavedObjects)(core.savedObjects); (0, _saved_objects.registerEncryptedSavedObjects)(deps.encryptedSavedObjects); // Register feature if (deps.features) { deps.features.registerKibanaFeature({ id: `fleetv2`, name: 'Fleet', category: _server.DEFAULT_APP_CATEGORIES.management, app: [_constants.PLUGIN_ID], catalogue: ['fleet'], privilegesTooltip: _i18n.i18n.translate('xpack.fleet.serverPlugin.privilegesTooltip', { defaultMessage: 'All Spaces is required for Fleet access.' }), reserved: { description: 'Privilege to setup Fleet packages and configured policies. Intended for use by the elastic/fleet-server service account only.', privileges: [{ id: 'fleet-setup', privilege: { excludeFromBasePrivileges: true, api: ['fleet-setup'], savedObject: { all: [], read: [] }, ui: [] } }] }, privileges: { all: { api: [`${_constants.PLUGIN_ID}-read`, `${_constants.PLUGIN_ID}-all`], app: [_constants.PLUGIN_ID], requireAllSpaces: true, catalogue: ['fleet'], savedObject: { all: allSavedObjectTypes, read: [] }, ui: ['read', 'all'] }, read: { api: [`${_constants.PLUGIN_ID}-read`], app: [_constants.PLUGIN_ID], catalogue: ['fleet'], requireAllSpaces: true, savedObject: { all: [], read: allSavedObjectTypes }, ui: ['read'], disabled: true } } }); deps.features.registerKibanaFeature({ id: 'fleet', // for BWC name: 'Integrations', category: _server.DEFAULT_APP_CATEGORIES.management, app: [_common2.INTEGRATIONS_PLUGIN_ID], catalogue: ['fleet'], privileges: { all: { api: [`${_common2.INTEGRATIONS_PLUGIN_ID}-read`, `${_common2.INTEGRATIONS_PLUGIN_ID}-all`], app: [_common2.INTEGRATIONS_PLUGIN_ID], catalogue: ['fleet'], savedObject: { all: allSavedObjectTypes, read: [] }, ui: ['read', 'all'] }, read: { api: [`${_common2.INTEGRATIONS_PLUGIN_ID}-read`], app: [_common2.INTEGRATIONS_PLUGIN_ID], catalogue: ['fleet'], savedObject: { all: [], read: allSavedObjectTypes }, ui: ['read'] } }, subFeatures: [] }); } core.http.registerRouteHandlerContext(_constants.PLUGIN_ID, async (context, request) => { const plugin = this; const coreContext = await context.core; const authz = await (0, _security.getAuthzFromRequest)(request); const esClient = coreContext.elasticsearch.client; const soClient = coreContext.savedObjects.getClient(); const routeRequiredAuthz = (0, _security.getRouteRequiredAuthz)(request.route.method, request.route.path); const routeAuthz = routeRequiredAuthz ? (0, _security.calculateRouteAuthz)(authz, routeRequiredAuthz) : undefined; const getInternalSoClient = () => _services.appContextService.getSavedObjects().getScopedClient(request, { excludedExtensions: [_coreSavedObjectsServer.SECURITY_EXTENSION_ID] }); return { get agentClient() { const agentService = plugin.setupAgentService(esClient.asInternalUser, soClient); return { asCurrentUser: agentService.asScoped(request), asInternalUser: agentService.asInternalUser }; }, get packagePolicyService() { const service = plugin.setupPackagePolicyService(); return { asCurrentUser: service.asScoped(request), asInternalUser: service.asInternalUser }; }, authz, get internalSoClient() { // Use a lazy getter to avoid constructing this client when not used by a request handler return getInternalSoClient(); }, get spaceId() { var _deps$spaces$spacesSe, _deps$spaces, _deps$spaces$spacesSe2; return (_deps$spaces$spacesSe = (_deps$spaces = deps.spaces) === null || _deps$spaces === void 0 ? void 0 : (_deps$spaces$spacesSe2 = _deps$spaces.spacesService) === null || _deps$spaces$spacesSe2 === void 0 ? void 0 : _deps$spaces$spacesSe2.getSpaceId(request)) !== null && _deps$spaces$spacesSe !== void 0 ? _deps$spaces$spacesSe : _common.DEFAULT_SPACE_ID; }, get limitedToPackages() { if (routeAuthz && routeAuthz.granted) { return routeAuthz.scopeDataToPackages; } } }; }); // Register usage collection (0, _register.registerFleetUsageCollector)(core, config, deps.usageCollection); const fetch = async abortController => await (0, _register.fetchFleetUsage)(core, config, abortController); this.fleetUsageSender = new _services.FleetUsageSender(deps.taskManager, core, fetch); (0, _fleet_usage_logger.registerFleetUsageLogger)(deps.taskManager, async () => (0, _register.fetchAgentsUsage)(core, config)); const router = core.http.createRouter(); // Allow read-only users access to endpoints necessary for Integrations UI // Only some endpoints require superuser so we pass a raw IRouter here // For all the routes we enforce the user to have role superuser const fleetAuthzRouter = (0, _security.makeRouterWithFleetAuthz)(router, this.initializerContext.logger.get('fleet_authz_router')); (0, _routes.registerRoutes)(fleetAuthzRouter, config); this.telemetryEventsSender.setup(deps.telemetry); this.bulkActionsResolver = new _agents.BulkActionsResolver(deps.taskManager, core); this.checkDeletedFilesTask = new _check_deleted_files_task.CheckDeletedFilesTask({ core, taskManager: deps.taskManager, logFactory: this.initializerContext.logger }); } start(core, plugins) { var _this$bulkActionsReso, _this$fleetUsageSende, _this$checkDeletedFil; const messageSigningService = new _security.MessageSigningService(plugins.encryptedSavedObjects.getClient({ includedHiddenTypes: [_common2.MESSAGE_SIGNING_KEYS_SAVED_OBJECT_TYPE] })); const uninstallTokenService = new _uninstall_token_service.UninstallTokenService(plugins.encryptedSavedObjects.getClient({ includedHiddenTypes: [_common2.UNINSTALL_TOKENS_SAVED_OBJECT_TYPE] })); _services.appContextService.start({ elasticsearch: core.elasticsearch, data: plugins.data, encryptedSavedObjectsStart: plugins.encryptedSavedObjects, encryptedSavedObjectsSetup: this.encryptedSavedObjectsSetup, securitySetup: this.securitySetup, securityStart: plugins.security, configInitialValue: this.configInitialValue, config$: this.config$, experimentalFeatures: (0, _experimental_features.parseExperimentalConfigValue)(this.configInitialValue.enableExperimental || []), savedObjects: core.savedObjects, savedObjectsTagging: plugins.savedObjectsTagging, isProductionMode: this.isProductionMode, kibanaVersion: this.kibanaVersion, kibanaBranch: this.kibanaBranch, httpSetup: this.httpSetup, cloud: this.cloud, logger: this.logger, telemetryEventsSender: this.telemetryEventsSender, bulkActionsResolver: this.bulkActionsResolver, messageSigningService, uninstallTokenService }); _services.licenseService.start(plugins.licensing.license$); this.telemetryEventsSender.start(plugins.telemetry, core); (_this$bulkActionsReso = this.bulkActionsResolver) === null || _this$bulkActionsReso === void 0 ? void 0 : _this$bulkActionsReso.start(plugins.taskManager); (_this$fleetUsageSende = this.fleetUsageSender) === null || _this$fleetUsageSende === void 0 ? void 0 : _this$fleetUsageSende.start(plugins.taskManager); (_this$checkDeletedFil = this.checkDeletedFilesTask) === null || _this$checkDeletedFil === void 0 ? void 0 : _this$checkDeletedFil.start({ taskManager: plugins.taskManager }); (0, _fleet_usage_logger.startFleetUsageLogger)(plugins.taskManager); const logger = _services.appContextService.getLogger(); this.policyWatcher = new _agent_policy_watch.PolicyWatcher(core.savedObjects, core.elasticsearch, logger); this.policyWatcher.start(_services.licenseService); const fleetSetupPromise = (async () => { try { // Fleet remains `available` during setup as to excessively delay Kibana's boot process. // This should be reevaluated as Fleet's setup process is optimized and stabilized. this.fleetStatus$.next({ level: _server.ServiceStatusLevels.available, summary: 'Fleet is setting up' }); // We need to wait for the licence feature to be available, // to have our internal saved object client with encrypted saved object working properly await plugins.licensing.license$.pipe((0, _operators.filter)(licence => licence.getFeature('security').isEnabled && licence.getFeature('security').isAvailable), (0, _operators.take)(1)).toPromise(); await (0, _setup.setupFleet)(new _server.SavedObjectsClient(core.savedObjects.createInternalRepository()), core.elasticsearch.client.asInternalUser); this.fleetStatus$.next({ level: _server.ServiceStatusLevels.available, summary: 'Fleet is available' }); } catch (error) { logger.warn('Fleet setup failed'); logger.warn(error); this.fleetStatus$.next({ // As long as Fleet has a dependency on EPR, we can't reliably set Kibana status to `unavailable` here. // See https://github.com/elastic/kibana/issues/120237 level: _server.ServiceStatusLevels.available, summary: 'Fleet setup failed', meta: { error: error.message } }); } })(); const internalSoClient = new _server.SavedObjectsClient(core.savedObjects.createInternalRepository()); return { authz: { fromRequest: _security.getAuthzFromRequest }, fleetSetupCompleted: () => fleetSetupPromise, esIndexPatternService: new _services.ESIndexPatternSavedObjectService(), packageService: this.setupPackageService(core.elasticsearch.client.asInternalUser, internalSoClient), agentService: this.setupAgentService(core.elasticsearch.client.asInternalUser, internalSoClient), agentPolicyService: { get: _services.agentPolicyService.get, list: _services.agentPolicyService.list, getFullAgentPolicy: _services.agentPolicyService.getFullAgentPolicy, getByIds: _services.agentPolicyService.getByIDs }, packagePolicyService: _services.packagePolicyService, registerExternalCallback: (type, callback) => { return _services.appContextService.addExternalCallback(type, callback); }, createArtifactsClient(packageName) { return new _artifacts.FleetArtifactsClient(core.elasticsearch.client.asInternalUser, packageName); }, createFilesClient: Object.freeze((0, _get_files_client_factory.getFilesClientFactory)({ esClient: core.elasticsearch.client.asInternalUser, logger: this.initializerContext.logger })), messageSigningService, uninstallTokenService, createFleetActionsClient(packageName) { return new _actions.FleetActionsClient(core.elasticsearch.client.asInternalUser, packageName); }, getPackageSpecTagId: _tag_assets.getPackageSpecTagId }; } async stop() { var _this$policyWatcher; _services.appContextService.stop(); (_this$policyWatcher = this.policyWatcher) === null || _this$policyWatcher === void 0 ? void 0 : _this$policyWatcher.stop(); _services.licenseService.stop(); this.telemetryEventsSender.stop(); this.fleetStatus$.complete(); } setupAgentService(internalEsClient, internalSoClient) { if (this.agentService) { return this.agentService; } this.agentService = new _services.AgentServiceImpl(internalEsClient, internalSoClient); return this.agentService; } setupPackagePolicyService() { if (this.packagePolicyService) { return this.packagePolicyService; } this.packagePolicyService = new _package_policy.PackagePolicyServiceImpl(); return this.packagePolicyService; } setupPackageService(internalEsClient, internalSoClient) { if (this.packageService) { return this.packageService; } this.packageService = new _services.PackageServiceImpl(internalEsClient, internalSoClient, this.getLogger()); return this.packageService; } getLogger() { if (!this.logger) { this.logger = this.initializerContext.logger.get(); } return this.logger; } } exports.FleetPlugin = FleetPlugin;