diff --git a/x-pack/plugins/ingest_manager/common/types/rest_spec/fleet_setup.ts b/x-pack/plugins/ingest_manager/common/types/rest_spec/fleet_setup.ts index ae4cb4e3fce49..50f275bd59137 100644 --- a/x-pack/plugins/ingest_manager/common/types/rest_spec/fleet_setup.ts +++ b/x-pack/plugins/ingest_manager/common/types/rest_spec/fleet_setup.ts @@ -10,5 +10,10 @@ export interface CreateFleetSetupResponse { export interface GetFleetStatusResponse { isReady: boolean; - missing_requirements: Array<'tls_required' | 'api_keys' | 'fleet_admin_user'>; + missing_requirements: Array< + | 'tls_required' + | 'api_keys' + | 'fleet_admin_user' + | 'encrypted_saved_object_encryption_key_required' + >; } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx index ffab5866f3b6f..e9c9ce0c513d2 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/fleet/setup_page/index.tsx @@ -39,7 +39,9 @@ export const SetupPage: React.FunctionComponent<{ }; const content = - missingRequirements.includes('tls_required') || missingRequirements.includes('api_keys') ? ( + missingRequirements.includes('tls_required') || + missingRequirements.includes('api_keys') || + missingRequirements.includes('encrypted_saved_object_encryption_key_required') ? ( <> @@ -53,12 +55,13 @@ export const SetupPage: React.FunctionComponent<{ - + , diff --git a/x-pack/plugins/ingest_manager/server/plugin.ts b/x-pack/plugins/ingest_manager/server/plugin.ts index cd44b61974b03..0d53092a0a8ff 100644 --- a/x-pack/plugins/ingest_manager/server/plugin.ts +++ b/x-pack/plugins/ingest_manager/server/plugin.ts @@ -67,7 +67,8 @@ export interface IngestManagerSetupDeps { export type IngestManagerStartDeps = object; export interface IngestManagerAppContext { - encryptedSavedObjects: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsStart: EncryptedSavedObjectsPluginStart; + encryptedSavedObjectsSetup?: EncryptedSavedObjectsPluginSetup; security?: SecurityPluginSetup; config$?: Observable; savedObjects: SavedObjectsServiceStart; @@ -115,6 +116,7 @@ export class IngestManagerPlugin private isProductionMode: boolean; private kibanaVersion: string; private httpSetup: HttpServiceSetup | undefined; + private encryptedSavedObjectsSetup: EncryptedSavedObjectsPluginSetup | undefined; constructor(private readonly initializerContext: PluginInitializerContext) { this.config$ = this.initializerContext.config.create(); @@ -129,6 +131,7 @@ export class IngestManagerPlugin if (deps.security) { this.security = deps.security; } + this.encryptedSavedObjectsSetup = deps.encryptedSavedObjects; this.cloud = deps.cloud; registerSavedObjects(core.savedObjects); @@ -187,12 +190,22 @@ export class IngestManagerPlugin } if (config.fleet.enabled) { - registerAgentRoutes(router); - registerEnrollmentApiKeyRoutes(router); - registerInstallScriptRoutes({ - router, - basePath: core.http.basePath, - }); + const isESOUsingEphemeralEncryptionKey = + deps.encryptedSavedObjects.usingEphemeralEncryptionKey; + if (isESOUsingEphemeralEncryptionKey) { + if (this.logger) { + this.logger.warn( + 'Fleet APIs are disabled due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml.' + ); + } + } else { + registerAgentRoutes(router); + registerEnrollmentApiKeyRoutes(router); + registerInstallScriptRoutes({ + router, + basePath: core.http.basePath, + }); + } } } } @@ -204,7 +217,8 @@ export class IngestManagerPlugin } ) { appContextService.start({ - encryptedSavedObjects: plugins.encryptedSavedObjects, + encryptedSavedObjectsStart: plugins.encryptedSavedObjects, + encryptedSavedObjectsSetup: this.encryptedSavedObjectsSetup, security: this.security, config$: this.config$, savedObjects: core.savedObjects, diff --git a/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts b/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts index 30eb6c0ae8caa..9808343417390 100644 --- a/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts +++ b/x-pack/plugins/ingest_manager/server/routes/setup/handlers.ts @@ -20,6 +20,8 @@ export const getFleetStatusHandler: RequestHandler = async (context, request, re const isProductionMode = appContextService.getIsProductionMode(); const isCloud = appContextService.getCloud()?.isCloudEnabled ?? false; const isTLSCheckDisabled = appContextService.getConfig()?.fleet?.tlsCheckDisabled ?? false; + const isUsingEphemeralEncryptionKey = appContextService.getEncryptedSavedObjectsSetup() + .usingEphemeralEncryptionKey; const missingRequirements: GetFleetStatusResponse['missing_requirements'] = []; if (!isAdminUserSetup) { @@ -32,6 +34,10 @@ export const getFleetStatusHandler: RequestHandler = async (context, request, re missingRequirements.push('tls_required'); } + if (isUsingEphemeralEncryptionKey) { + missingRequirements.push('encrypted_saved_object_encryption_key_required'); + } + const body: GetFleetStatusResponse = { isReady: missingRequirements.length === 0, missing_requirements: missingRequirements, diff --git a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts index 0d22529fdb031..efdcbdb5c36bb 100644 --- a/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts +++ b/x-pack/plugins/ingest_manager/server/services/agents/acks.test.ts @@ -24,7 +24,7 @@ describe('test agent acks services', () => { const mockSavedObjectsClient = savedObjectsClientMock.create(); const mockStartEncryptedSOPlugin = encryptedSavedObjectsMock.createStart(); appContextService.start(({ - encryptedSavedObjects: mockStartEncryptedSOPlugin, + encryptedSavedObjectsStart: mockStartEncryptedSOPlugin, } as unknown) as IngestManagerAppContext); const [ diff --git a/x-pack/plugins/ingest_manager/server/services/app_context.ts b/x-pack/plugins/ingest_manager/server/services/app_context.ts index 9e6220b6958f1..81a16caa8ce9e 100644 --- a/x-pack/plugins/ingest_manager/server/services/app_context.ts +++ b/x-pack/plugins/ingest_manager/server/services/app_context.ts @@ -6,7 +6,10 @@ import { BehaviorSubject, Observable } from 'rxjs'; import { first } from 'rxjs/operators'; import { SavedObjectsServiceStart, HttpServiceSetup, Logger } from 'src/core/server'; -import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server'; +import { + EncryptedSavedObjectsClient, + EncryptedSavedObjectsPluginSetup, +} from '../../../encrypted_saved_objects/server'; import { SecurityPluginSetup } from '../../../security/server'; import { IngestManagerConfigType } from '../../common'; import { IngestManagerAppContext } from '../plugin'; @@ -14,6 +17,7 @@ import { CloudSetup } from '../../../cloud/server'; class AppContextService { private encryptedSavedObjects: EncryptedSavedObjectsClient | undefined; + private encryptedSavedObjectsSetup: EncryptedSavedObjectsPluginSetup | undefined; private security: SecurityPluginSetup | undefined; private config$?: Observable; private configSubject$?: BehaviorSubject; @@ -25,7 +29,8 @@ class AppContextService { private httpSetup?: HttpServiceSetup; public async start(appContext: IngestManagerAppContext) { - this.encryptedSavedObjects = appContext.encryptedSavedObjects?.getClient(); + this.encryptedSavedObjects = appContext.encryptedSavedObjectsStart?.getClient(); + this.encryptedSavedObjectsSetup = appContext.encryptedSavedObjectsSetup; this.security = appContext.security; this.savedObjects = appContext.savedObjects; this.isProductionMode = appContext.isProductionMode; @@ -95,6 +100,14 @@ class AppContextService { return this.httpSetup; } + public getEncryptedSavedObjectsSetup() { + if (!this.encryptedSavedObjectsSetup) { + throw new Error('encryptedSavedObjectsSetup is not set'); + } + + return this.encryptedSavedObjectsSetup; + } + public getKibanaVersion() { if (!this.kibanaVersion) { throw new Error('Kibana version is not set.');