From f6a7a100769c5ab7af53664eb12f07e28f9ae973 Mon Sep 17 00:00:00 2001 From: Janki Salvi Date: Tue, 23 Dec 2025 15:45:33 +0000 Subject: [PATCH] initial commit --- .../plugins/shared/alerting/server/plugin.ts | 6 ++-- .../maintenance_windows_service.test.ts | 18 +++++----- .../maintenance_windows_service.ts | 6 ++-- .../maintenance_window_client_factory.test.ts | 22 +++++++++++- .../maintenance_window_client_factory.ts | 31 ++++++++++------- .../maintenance_windows/server/mocks.ts | 3 ++ .../maintenance_windows/server/plugin.test.ts | 34 +++++++++++++++++++ .../maintenance_windows/server/plugin.ts | 12 +++++-- .../maintenance_windows/server/types.ts | 6 ++-- .../plugins/synthetics/server/plugin.ts | 5 +-- 10 files changed, 103 insertions(+), 40 deletions(-) diff --git a/x-pack/platform/plugins/shared/alerting/server/plugin.ts b/x-pack/platform/plugins/shared/alerting/server/plugin.ts index bf7674d6dfd3f..ca344fbf128da 100644 --- a/x-pack/platform/plugins/shared/alerting/server/plugin.ts +++ b/x-pack/platform/plugins/shared/alerting/server/plugin.ts @@ -671,11 +671,11 @@ export class AlertingPlugin { return rulesSettingsClientFactory!.create(request); }; - const getMaintenanceWindowClientInternal = (request: KibanaRequest) => { + const getMaintenanceWindowClient = (request: KibanaRequest) => { if (!plugins.maintenanceWindows) { return; } - return plugins.maintenanceWindows.getMaintenanceWindowClientInternal(request); + return plugins.maintenanceWindows.getMaintenanceWindowClientWithoutAuth(request); }; taskRunnerFactory.initialize({ @@ -697,7 +697,7 @@ export class AlertingPlugin { maintenanceWindowsService: new MaintenanceWindowsService({ cacheInterval: this.config.rulesSettings.cacheInterval, logger, - getMaintenanceWindowClientInternal, + getMaintenanceWindowClient, }), maxAlerts: this.config.rules.run.alerts.max, ruleTypeRegistry: this.ruleTypeRegistry!, diff --git a/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.test.ts b/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.test.ts index 0d59a8d667643..aecbc57fdc2c8 100644 --- a/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.test.ts @@ -69,7 +69,7 @@ describe('MaintenanceWindowsService', () => { test('should load maintenance windows if none in cache', async () => { maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(maintenanceWindows); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); // @ts-ignore - accessing private variable @@ -103,7 +103,7 @@ describe('MaintenanceWindowsService', () => { throw new Error('Test error'); }); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); // @ts-ignore - accessing private variable @@ -139,7 +139,7 @@ describe('MaintenanceWindowsService', () => { maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(maintenanceWindows); maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(newSpaceMW); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); // @ts-ignore - accessing private variable @@ -190,7 +190,7 @@ describe('MaintenanceWindowsService', () => { test('should use cached windows if cache has not expired', async () => { maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(maintenanceWindows); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); @@ -226,7 +226,7 @@ describe('MaintenanceWindowsService', () => { maintenanceWindows[0], ]); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); @@ -263,7 +263,7 @@ describe('MaintenanceWindowsService', () => { throw new Error('Test error'); }); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); @@ -303,7 +303,7 @@ describe('MaintenanceWindowsService', () => { ]; maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(mw); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); @@ -353,7 +353,7 @@ describe('MaintenanceWindowsService', () => { })); maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(mw); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); @@ -407,7 +407,7 @@ describe('MaintenanceWindowsService', () => { ]; maintenanceWindowClient.getActiveMaintenanceWindows.mockResolvedValueOnce(mw); const maintenanceWindowsService = new MaintenanceWindowsService({ - getMaintenanceWindowClientInternal: jest.fn().mockReturnValue(maintenanceWindowClient), + getMaintenanceWindowClient: jest.fn().mockReturnValue(maintenanceWindowClient), logger, }); diff --git a/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.ts b/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.ts index 293975d18ee08..a7f978aebfdbe 100644 --- a/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.ts +++ b/x-pack/platform/plugins/shared/alerting/server/task_runner/maintenance_windows/maintenance_windows_service.ts @@ -16,9 +16,7 @@ export const DEFAULT_CACHE_INTERVAL_MS = 60000; // 1 minute cache interface MaintenanceWindowServiceOpts { cacheInterval?: number; - getMaintenanceWindowClientInternal: ( - request: KibanaRequest - ) => MaintenanceWindowClient | undefined; + getMaintenanceWindowClient: (request: KibanaRequest) => MaintenanceWindowClient | undefined; logger: Logger; } @@ -135,7 +133,7 @@ export class MaintenanceWindowsService { now: number ): Promise { return await withAlertingSpan('alerting:load-maintenance-windows', async () => { - const maintenanceWindowClient = this.options.getMaintenanceWindowClientInternal(request); + const maintenanceWindowClient = this.options.getMaintenanceWindowClient(request); const activeMaintenanceWindows = maintenanceWindowClient ? await maintenanceWindowClient.getActiveMaintenanceWindows(this.cacheIntervalMs) : []; diff --git a/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.test.ts b/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.test.ts index 378b72ed0ae1a..a03e0c4bb695e 100644 --- a/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.test.ts +++ b/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.test.ts @@ -87,7 +87,7 @@ test('creates an unauthorized maintenance window client', async () => { savedObjectsService.getScopedClient.mockReturnValue(savedObjectsClient); - factory.create(request); + factory.createWithoutAuthorization(request); expect(savedObjectsService.getScopedClient).toHaveBeenCalledWith(request, { excludedExtensions: [SECURITY_EXTENSION_ID], @@ -103,6 +103,26 @@ test('creates an unauthorized maintenance window client', async () => { }); }); +test('creates an internal maintenance window client', async () => { + const factory = new MaintenanceWindowClientFactory(); + factory.initialize(maintenanceWindowClientFactoryParams); + const request = mockRouter.createKibanaRequest(); + const mockRepository = savedObjectsService.createInternalRepository(); + savedObjectsService.createInternalRepository.mockReturnValue(mockRepository); + + factory.createInternal(request); + + expect(savedObjectsService.createInternalRepository).toHaveBeenCalledWith(); + + const { MaintenanceWindowClient } = jest.requireMock('./client'); + + expect(MaintenanceWindowClient).toHaveBeenCalledWith({ + logger: maintenanceWindowClientFactoryParams.logger, + savedObjectsClient: mockRepository, + getUserName: expect.any(Function), + }); +}); + test('getUserName() returns null when security is disabled', async () => { const factory = new MaintenanceWindowClientFactory(); factory.initialize(maintenanceWindowClientFactoryParams); diff --git a/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.ts b/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.ts index 205ba2cbcaf8a..3ccd426bd771d 100644 --- a/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.ts +++ b/x-pack/platform/plugins/shared/maintenance_windows/server/maintenance_window_client_factory.ts @@ -8,6 +8,7 @@ import type { KibanaRequest, Logger, + SavedObjectsClientContract, SavedObjectsServiceStart, SecurityServiceStart, UiSettingsServiceStart, @@ -41,19 +42,18 @@ export class MaintenanceWindowClientFactory { this.uiSettings = options.uiSettings; } + private getSoClient(request: KibanaRequest, withAuth: boolean): SavedObjectsClientContract { + return this.savedObjectsService.getScopedClient(request, { + includedHiddenTypes: [MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE], + ...(withAuth ? {} : { excludedExtensions: [SECURITY_EXTENSION_ID] }), + }); + } + private createMaintenanceWindowClient( request: KibanaRequest, - withAuth: boolean, - excludedExtensions?: ['spaces'] + savedObjectsClient: SavedObjectsClientContract ) { const { securityService } = this; - const savedObjectsClient = this.savedObjectsService.getScopedClient(request, { - includedHiddenTypes: [MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE], - ...(withAuth - ? {} - : { excludedExtensions: [...(excludedExtensions ?? []), SECURITY_EXTENSION_ID] }), - }); - const uiSettingClient = this.uiSettings.asScopedToClient(savedObjectsClient); return new MaintenanceWindowClient({ @@ -68,10 +68,17 @@ export class MaintenanceWindowClientFactory { } public createWithAuthorization(request: KibanaRequest) { - return this.createMaintenanceWindowClient(request, true); + const soClient = this.getSoClient(request, true); + return this.createMaintenanceWindowClient(request, soClient); + } + + public createWithoutAuthorization(request: KibanaRequest) { + const soClient = this.getSoClient(request, false); + return this.createMaintenanceWindowClient(request, soClient); } - public create(request: KibanaRequest, excludedExtension?: ['spaces']) { - return this.createMaintenanceWindowClient(request, false, excludedExtension); + public createInternal(request: KibanaRequest) { + const savedObjectsInternalClient = this.savedObjectsService.createInternalRepository(); + return this.createMaintenanceWindowClient(request, savedObjectsInternalClient); } } diff --git a/x-pack/platform/plugins/shared/maintenance_windows/server/mocks.ts b/x-pack/platform/plugins/shared/maintenance_windows/server/mocks.ts index 9ee3bb324d4d7..451f8eb4c26e4 100644 --- a/x-pack/platform/plugins/shared/maintenance_windows/server/mocks.ts +++ b/x-pack/platform/plugins/shared/maintenance_windows/server/mocks.ts @@ -17,6 +17,9 @@ const createStartMock = () => { getMaintenanceWindowClientWithAuth: jest .fn() .mockResolvedValue(maintenanceWindowClientMock.create()), + getMaintenanceWindowClientWithoutAuth: jest + .fn() + .mockResolvedValue(maintenanceWindowClientMock.create()), }); return mock; diff --git a/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.test.ts b/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.test.ts index dfc849bb3aa4f..af147aa321947 100644 --- a/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.test.ts +++ b/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.test.ts @@ -92,6 +92,40 @@ describe('Maintenance Windows Plugin', () => { expect(client).toBeDefined(); }); + test(`exposes getMaintenanceWindowClientWithoutAuth()`, async () => { + const context = coreMock.createPluginInitializerContext(); + const plugin = new MaintenanceWindowsPlugin(context); + + plugin.setup(coreMock.createSetup(), { + licensing: licensingMock.createSetup(), + taskManager: taskManagerMock.createSetup(), + features: featuresPluginMock.createSetup(), + }); + + const startContract = plugin.start(coreMock.createStart(), { + taskManager: taskManagerMock.createStart(), + }); + + const fakeRequest = { + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + getSavedObjectsClient: jest.fn(), + } as unknown as KibanaRequest; + + const client = startContract.getMaintenanceWindowClientWithoutAuth(fakeRequest); + expect(client).toBeDefined(); + }); + test(`exposes getMaintenanceWindowClientInternal()`, async () => { const context = coreMock.createPluginInitializerContext(); const plugin = new MaintenanceWindowsPlugin(context); diff --git a/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.ts b/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.ts index c74bdf1f23adf..28f66f1fbd4b1 100644 --- a/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.ts +++ b/x-pack/platform/plugins/shared/maintenance_windows/server/plugin.ts @@ -107,17 +107,23 @@ export class MaintenanceWindowsPlugin return maintenanceWindowClientFactory.createWithAuthorization(request); }; + const getMaintenanceWindowClientWithoutAuth = ( + request: KibanaRequest + ): MaintenanceWindowClientApi => { + return maintenanceWindowClientFactory.createWithoutAuthorization(request); + }; + const getMaintenanceWindowClientInternal = ( - request: KibanaRequest, - excludedExtension?: ['spaces'] + request: KibanaRequest ): MaintenanceWindowClientApi => { - return maintenanceWindowClientFactory.create(request, excludedExtension); + return maintenanceWindowClientFactory.createInternal(request); }; scheduleMaintenanceWindowEventsGenerator(this.logger, plugins.taskManager).catch(() => {}); return { getMaintenanceWindowClientWithAuth, + getMaintenanceWindowClientWithoutAuth, getMaintenanceWindowClientInternal, }; } diff --git a/x-pack/platform/plugins/shared/maintenance_windows/server/types.ts b/x-pack/platform/plugins/shared/maintenance_windows/server/types.ts index 1f20a3bf54456..0c6e7734d30f5 100644 --- a/x-pack/platform/plugins/shared/maintenance_windows/server/types.ts +++ b/x-pack/platform/plugins/shared/maintenance_windows/server/types.ts @@ -38,9 +38,7 @@ export interface MaintenanceWindowsServerStartDependencies { } export interface MaintenanceWindowsServerStart { - getMaintenanceWindowClientInternal( - request: KibanaRequest, - excludedExtension?: string[] - ): MaintenanceWindowClientApi; + getMaintenanceWindowClientInternal(request: KibanaRequest): MaintenanceWindowClientApi; getMaintenanceWindowClientWithAuth(request: KibanaRequest): MaintenanceWindowClientApi; + getMaintenanceWindowClientWithoutAuth(request: KibanaRequest): MaintenanceWindowClientApi; } diff --git a/x-pack/solutions/observability/plugins/synthetics/server/plugin.ts b/x-pack/solutions/observability/plugins/synthetics/server/plugin.ts index 446301a6c9e11..4f6b95ac67b0a 100644 --- a/x-pack/solutions/observability/plugins/synthetics/server/plugin.ts +++ b/x-pack/solutions/observability/plugins/synthetics/server/plugin.ts @@ -13,7 +13,6 @@ import type { SavedObjectsClientContract, KibanaRequest, } from '@kbn/core/server'; -import { SPACES_EXTENSION_ID } from '@kbn/core/server'; import { SavedObjectsClient } from '@kbn/core/server'; import { mappingFromFieldMap } from '@kbn/alerting-plugin/common'; import { Dataset } from '@kbn/rule-registry-plugin/server'; @@ -130,9 +129,7 @@ export class Plugin implements PluginType { return; } - return pluginsStart.maintenanceWindows?.getMaintenanceWindowClientInternal(request, [ - SPACES_EXTENSION_ID, - ]); + return pluginsStart.maintenanceWindows?.getMaintenanceWindowClientInternal(request); }; if (this.server) {