diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e54b7b56707e88..50d157a1da3dc1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -149,6 +149,7 @@ # Kibana Alerting Services /x-pack/legacy/plugins/alerting/ @elastic/kibana-alerting-services /x-pack/legacy/plugins/actions/ @elastic/kibana-alerting-services +/x-pack/plugins/alerting/ @elastic/kibana-alerting-services /x-pack/plugins/actions/ @elastic/kibana-alerting-services /x-pack/plugins/event_log/ @elastic/kibana-alerting-services /x-pack/plugins/task_manager/ @elastic/kibana-alerting-services @@ -156,6 +157,7 @@ /x-pack/test/plugin_api_integration/plugins/task_manager/ @elastic/kibana-alerting-services /x-pack/test/plugin_api_integration/test_suites/task_manager/ @elastic/kibana-alerting-services /x-pack/legacy/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services +/x-pack/plugins/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/ @elastic/kibana-alerting-services /x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/ @elastic/kibana-alerting-services diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index 032efcee20afd0..99882a6e235e22 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -3,7 +3,7 @@ "paths": { "xpack.actions": "plugins/actions", "xpack.advancedUiActions": "plugins/advanced_ui_actions", - "xpack.alerting": "legacy/plugins/alerting", + "xpack.alerting": "plugins/alerting", "xpack.triggersActionsUI": "plugins/triggers_actions_ui", "xpack.apm": ["legacy/plugins/apm", "plugins/apm"], "xpack.beatsManagement": "legacy/plugins/beats_management", diff --git a/x-pack/legacy/plugins/alerting/index.ts b/x-pack/legacy/plugins/alerting/index.ts index 5baec07fa1182a..0d0a698841269f 100644 --- a/x-pack/legacy/plugins/alerting/index.ts +++ b/x-pack/legacy/plugins/alerting/index.ts @@ -4,43 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Legacy } from 'kibana'; -import { Root } from 'joi'; -import { init } from './server'; -import mappings from './mappings.json'; - -export { - AlertingPlugin, - AlertsClient, - AlertType, - AlertExecutorOptions, - PluginSetupContract, - PluginStartContract, -} from './server'; - -export function alerting(kibana: any) { - return new kibana.Plugin({ - id: 'alerting', - configPrefix: 'xpack.alerting', - require: ['kibana', 'elasticsearch', 'actions', 'task_manager', 'encryptedSavedObjects'], - isEnabled(config: Legacy.KibanaConfig) { - return ( - config.get('xpack.alerting.enabled') === true && - config.get('xpack.actions.enabled') === true && - config.get('xpack.encryptedSavedObjects.enabled') === true && - config.get('xpack.task_manager.enabled') === true - ); - }, - config(Joi: Root) { - return Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - }) - .default(); - }, - init, - uiExports: { - mappings, - }, - }); -} +export * from './server'; diff --git a/x-pack/legacy/plugins/alerting/server/extend_route_with_license_check.test.ts b/x-pack/legacy/plugins/alerting/server/extend_route_with_license_check.test.ts deleted file mode 100644 index 05c8424881625a..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/extend_route_with_license_check.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { extendRouteWithLicenseCheck } from './extend_route_with_license_check'; -import { LicenseState } from './lib/license_state'; -jest.mock('./lib/license_state', () => ({ - verifyApiAccessFactory: () => {}, -})); - -describe('extendRouteWithLicenseCheck', () => { - describe('#actionsextendRouteWithLicenseCheck', () => { - let licenseState: jest.Mocked; - - test('extends route object with license, if config property already exists', () => { - const newRoute = extendRouteWithLicenseCheck( - { config: { someTestProperty: 'test' } }, - licenseState - ); - expect(newRoute.config.pre.length > 0); - }); - test('extends route object with license check under options.pre', () => { - const newRoute = extendRouteWithLicenseCheck( - { options: { someProperty: 'test' } }, - licenseState - ); - expect(newRoute.options.pre.length > 0); - }); - }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/extend_route_with_license_check.ts b/x-pack/legacy/plugins/alerting/server/extend_route_with_license_check.ts deleted file mode 100644 index f39dc125071b4d..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/extend_route_with_license_check.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ -import { LicenseState, verifyApiAccessFactory } from './lib/license_state'; - -export function extendRouteWithLicenseCheck(route: any, licenseState: LicenseState) { - const verifyApiAccessPreRouting = verifyApiAccessFactory(licenseState); - - const key = route.options ? 'options' : 'config'; - return { - ...route, - [key]: { - ...route[key], - pre: [verifyApiAccessPreRouting], - }, - }; -} diff --git a/x-pack/legacy/plugins/alerting/server/index.ts b/x-pack/legacy/plugins/alerting/server/index.ts index 44ae1964ec98a3..5bf7cda51bda66 100644 --- a/x-pack/legacy/plugins/alerting/server/index.ts +++ b/x-pack/legacy/plugins/alerting/server/index.ts @@ -4,10 +4,32 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertsClient as AlertsClientClass } from './alerts_client'; +import { Legacy } from 'kibana'; +import { Root } from 'joi'; +import mappings from './mappings.json'; -export type AlertsClient = PublicMethodsOf; - -export { init } from './init'; -export { AlertType, AlertingPlugin, AlertExecutorOptions } from './types'; -export { PluginSetupContract, PluginStartContract } from './plugin'; +export function alerting(kibana: any) { + return new kibana.Plugin({ + id: 'alerting', + configPrefix: 'xpack.alerting', + require: ['kibana', 'elasticsearch', 'actions', 'task_manager', 'encryptedSavedObjects'], + isEnabled(config: Legacy.KibanaConfig) { + return ( + config.get('xpack.alerting.enabled') === true && + config.get('xpack.actions.enabled') === true && + config.get('xpack.encryptedSavedObjects.enabled') === true && + config.get('xpack.task_manager.enabled') === true + ); + }, + config(Joi: Root) { + return Joi.object() + .keys({ + enabled: Joi.boolean().default(true), + }) + .default(); + }, + uiExports: { + mappings, + }, + }); +} diff --git a/x-pack/legacy/plugins/alerting/server/init.ts b/x-pack/legacy/plugins/alerting/server/init.ts deleted file mode 100644 index d76bc33f3fa0a3..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/init.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { Server, shim } from './shim'; -import { Plugin } from './plugin'; -import { AlertingPlugin } from './types'; - -export async function init(server: Server) { - const { initializerContext, coreSetup, coreStart, pluginsSetup, pluginsStart } = shim(server); - - const plugin = new Plugin(initializerContext); - - const setupContract = await plugin.setup(coreSetup, pluginsSetup); - const startContract = plugin.start(coreStart, pluginsStart); - - server.decorate('request', 'getAlertsClient', function() { - return startContract.getAlertsClientWithRequest(this); - }); - - const exposedFunctions: AlertingPlugin = { - setup: setupContract, - start: startContract, - }; - server.expose(exposedFunctions); -} diff --git a/x-pack/legacy/plugins/alerting/mappings.json b/x-pack/legacy/plugins/alerting/server/mappings.json similarity index 100% rename from x-pack/legacy/plugins/alerting/mappings.json rename to x-pack/legacy/plugins/alerting/server/mappings.json diff --git a/x-pack/legacy/plugins/alerting/server/plugin.ts b/x-pack/legacy/plugins/alerting/server/plugin.ts deleted file mode 100644 index 2567e470d2e798..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/plugin.ts +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -import { Services } from './types'; -import { AlertsClient } from './alerts_client'; -import { AlertTypeRegistry } from './alert_type_registry'; -import { TaskRunnerFactory } from './task_runner'; -import { AlertsClientFactory } from './alerts_client_factory'; -import { LicenseState } from './lib/license_state'; -import { IClusterClient, KibanaRequest, Logger } from '../../../../../src/core/server'; -import { - AlertingPluginInitializerContext, - AlertingCoreSetup, - AlertingCoreStart, - AlertingPluginsSetup, - AlertingPluginsStart, -} from './shim'; -import { - createAlertRoute, - deleteAlertRoute, - findAlertRoute, - getAlertRoute, - getAlertStateRoute, - listAlertTypesRoute, - updateAlertRoute, - enableAlertRoute, - disableAlertRoute, - updateApiKeyRoute, - muteAllAlertRoute, - unmuteAllAlertRoute, - muteAlertInstanceRoute, - unmuteAlertInstanceRoute, -} from './routes'; -import { extendRouteWithLicenseCheck } from './extend_route_with_license_check'; - -export interface PluginSetupContract { - registerType: AlertTypeRegistry['register']; -} -export interface PluginStartContract { - listTypes: AlertTypeRegistry['list']; - getAlertsClientWithRequest(request: Hapi.Request): PublicMethodsOf; -} - -export class Plugin { - private readonly logger: Logger; - private alertTypeRegistry?: AlertTypeRegistry; - private readonly taskRunnerFactory: TaskRunnerFactory; - private adminClient?: IClusterClient; - private serverBasePath?: string; - private licenseState: LicenseState | null = null; - private isESOUsingEphemeralEncryptionKey?: boolean; - - constructor(initializerContext: AlertingPluginInitializerContext) { - this.logger = initializerContext.logger.get('plugins', 'alerting'); - this.taskRunnerFactory = new TaskRunnerFactory(); - } - - public async setup( - core: AlertingCoreSetup, - plugins: AlertingPluginsSetup - ): Promise { - this.adminClient = core.elasticsearch.adminClient; - this.licenseState = new LicenseState(plugins.licensing.license$); - this.isESOUsingEphemeralEncryptionKey = - plugins.encryptedSavedObjects.usingEphemeralEncryptionKey; - - if (this.isESOUsingEphemeralEncryptionKey) { - this.logger.warn( - 'APIs are disabled due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml.' - ); - } - - // Encrypted attributes - plugins.encryptedSavedObjects.registerType({ - type: 'alert', - attributesToEncrypt: new Set(['apiKey']), - attributesToExcludeFromAAD: new Set([ - 'scheduledTaskId', - 'muteAll', - 'mutedInstanceIds', - 'updatedBy', - ]), - }); - - const alertTypeRegistry = new AlertTypeRegistry({ - taskManager: plugins.taskManager, - taskRunnerFactory: this.taskRunnerFactory, - }); - this.alertTypeRegistry = alertTypeRegistry; - this.serverBasePath = core.http.basePath.serverBasePath; - - // Register routes - core.http.route(extendRouteWithLicenseCheck(createAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(deleteAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(findAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(getAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(getAlertStateRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(listAlertTypesRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(updateAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(enableAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(disableAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(updateApiKeyRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(muteAllAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(unmuteAllAlertRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(muteAlertInstanceRoute, this.licenseState)); - core.http.route(extendRouteWithLicenseCheck(unmuteAlertInstanceRoute, this.licenseState)); - - return { - registerType: alertTypeRegistry.register.bind(alertTypeRegistry), - }; - } - - public start(core: AlertingCoreStart, plugins: AlertingPluginsStart): PluginStartContract { - const { adminClient, serverBasePath, isESOUsingEphemeralEncryptionKey } = this; - - function spaceIdToNamespace(spaceId?: string): string | undefined { - const spacesPlugin = plugins.spaces(); - return spacesPlugin && spaceId ? spacesPlugin.spaceIdToNamespace(spaceId) : undefined; - } - - const alertsClientFactory = new AlertsClientFactory({ - alertTypeRegistry: this.alertTypeRegistry!, - logger: this.logger, - taskManager: plugins.taskManager, - securityPluginSetup: plugins.security, - encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, - spaceIdToNamespace, - getSpaceId(request: Hapi.Request) { - const spacesPlugin = plugins.spaces(); - return spacesPlugin ? spacesPlugin.getSpaceId(request) : undefined; - }, - }); - - this.taskRunnerFactory.initialize({ - logger: this.logger, - getServices(rawRequest: Hapi.Request): Services { - const request = KibanaRequest.from(rawRequest); - return { - callCluster: (...args) => adminClient!.asScoped(request).callAsCurrentUser(...args), - // rawRequest is actually a fake request, converting it to KibanaRequest causes issue in SO access - savedObjectsClient: core.savedObjects.getScopedSavedObjectsClient(rawRequest as any), - }; - }, - spaceIdToNamespace, - executeAction: plugins.actions.execute, - encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, - getBasePath(spaceId?: string): string { - const spacesPlugin = plugins.spaces(); - return spacesPlugin && spaceId ? spacesPlugin.getBasePath(spaceId) : serverBasePath!; - }, - }); - - return { - listTypes: this.alertTypeRegistry!.list.bind(this.alertTypeRegistry!), - getAlertsClientWithRequest: (request: Hapi.Request) => { - if (isESOUsingEphemeralEncryptionKey === true) { - throw new Error( - `Unable to create alerts client due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml` - ); - } - return alertsClientFactory!.create(KibanaRequest.from(request), request); - }, - }; - } - - public stop() { - if (this.licenseState) { - this.licenseState.clean(); - } - } -} diff --git a/x-pack/legacy/plugins/alerting/server/routes/_mock_server.ts b/x-pack/legacy/plugins/alerting/server/routes/_mock_server.ts deleted file mode 100644 index 0f865a12067ad0..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/_mock_server.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; -import { alertsClientMock } from '../alerts_client.mock'; -import { alertTypeRegistryMock } from '../alert_type_registry.mock'; - -const defaultConfig = { - 'kibana.index': '.kibana', -}; - -export function createMockServer(config: Record = defaultConfig) { - const server = new Hapi.Server({ - port: 0, - }); - - const alertsClient = alertsClientMock.create(); - const alertTypeRegistry = alertTypeRegistryMock.create(); - - server.config = () => { - return { - get(key: string) { - return config[key]; - }, - has(key: string) { - return config.hasOwnProperty(key); - }, - }; - }; - - server.register({ - name: 'alerting', - register(pluginServer: Hapi.Server) { - pluginServer.expose({ - setup: { - registerType: alertTypeRegistry.register, - }, - start: { - listTypes: alertTypeRegistry.list, - }, - }); - }, - }); - - server.decorate('request', 'getAlertsClient', () => alertsClient); - server.decorate('request', 'getBasePath', () => '/s/default'); - - return { server, alertsClient, alertTypeRegistry }; -} diff --git a/x-pack/legacy/plugins/alerting/server/routes/create.test.ts b/x-pack/legacy/plugins/alerting/server/routes/create.test.ts deleted file mode 100644 index 2a0ae78fd78b22..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/create.test.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { omit } from 'lodash'; -import { createMockServer } from './_mock_server'; -import { createAlertRoute } from './create'; - -const { server, alertsClient } = createMockServer(); -server.route(createAlertRoute); - -const mockedAlert = { - alertTypeId: '1', - consumer: 'bar', - name: 'abc', - schedule: { interval: '10s' }, - tags: ['foo'], - params: { - bar: true, - }, - throttle: '30s', - actions: [ - { - group: 'default', - id: '2', - params: { - foo: true, - }, - }, - ], -}; - -beforeEach(() => jest.resetAllMocks()); - -test('creates an alert with proper parameters', async () => { - const request = { - method: 'POST', - url: '/api/alert', - payload: mockedAlert, - }; - - const createdAt = new Date(); - const updatedAt = new Date(); - alertsClient.create.mockResolvedValueOnce({ - ...mockedAlert, - enabled: true, - muteAll: false, - createdBy: '', - updatedBy: '', - apiKey: '', - apiKeyOwner: '', - mutedInstanceIds: [], - createdAt, - updatedAt, - id: '123', - actions: [ - { - ...mockedAlert.actions[0], - actionTypeId: 'test', - }, - ], - }); - const { payload, statusCode } = await server.inject(request); - expect(statusCode).toBe(200); - const response = JSON.parse(payload); - expect(new Date(response.createdAt)).toEqual(createdAt); - expect(omit(response, 'createdAt', 'updatedAt')).toMatchInlineSnapshot(` - Object { - "actions": Array [ - Object { - "actionTypeId": "test", - "group": "default", - "id": "2", - "params": Object { - "foo": true, - }, - }, - ], - "alertTypeId": "1", - "apiKey": "", - "apiKeyOwner": "", - "consumer": "bar", - "createdBy": "", - "enabled": true, - "id": "123", - "muteAll": false, - "mutedInstanceIds": Array [], - "name": "abc", - "params": Object { - "bar": true, - }, - "schedule": Object { - "interval": "10s", - }, - "tags": Array [ - "foo", - ], - "throttle": "30s", - "updatedBy": "", - } - `); - expect(alertsClient.create).toHaveBeenCalledTimes(1); - expect(alertsClient.create.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Object { - "data": Object { - "actions": Array [ - Object { - "group": "default", - "id": "2", - "params": Object { - "foo": true, - }, - }, - ], - "alertTypeId": "1", - "consumer": "bar", - "enabled": true, - "name": "abc", - "params": Object { - "bar": true, - }, - "schedule": Object { - "interval": "10s", - }, - "tags": Array [ - "foo", - ], - "throttle": "30s", - }, - }, - ] - `); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/create.ts b/x-pack/legacy/plugins/alerting/server/routes/create.ts deleted file mode 100644 index 362a23a3fa910c..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/create.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; -import Joi from 'joi'; -import { getDurationSchema } from '../lib'; -import { IntervalSchedule } from '../types'; - -interface ScheduleRequest extends Hapi.Request { - payload: { - enabled: boolean; - name: string; - tags: string[]; - alertTypeId: string; - consumer: string; - schedule: IntervalSchedule; - actions: Array<{ - group: string; - id: string; - params: Record; - }>; - params: Record; - throttle: string | null; - }; -} - -export const createAlertRoute = { - method: 'POST', - path: '/api/alert', - options: { - tags: ['access:alerting-all'], - validate: { - options: { - abortEarly: false, - }, - payload: Joi.object() - .keys({ - enabled: Joi.boolean().default(true), - name: Joi.string().required(), - tags: Joi.array() - .items(Joi.string()) - .default([]), - alertTypeId: Joi.string().required(), - consumer: Joi.string().required(), - throttle: getDurationSchema().default(null), - schedule: Joi.object() - .keys({ - interval: getDurationSchema().required(), - }) - .required(), - params: Joi.object().required(), - actions: Joi.array() - .items( - Joi.object().keys({ - group: Joi.string().required(), - id: Joi.string().required(), - params: Joi.object().required(), - }) - ) - .required(), - }) - .required(), - }, - }, - async handler(request: ScheduleRequest) { - const alertsClient = request.getAlertsClient!(); - return await alertsClient.create({ data: request.payload }); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/delete.test.ts b/x-pack/legacy/plugins/alerting/server/routes/delete.test.ts deleted file mode 100644 index b7b25538847fac..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/delete.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { deleteAlertRoute } from './delete'; - -const { server, alertsClient } = createMockServer(); -server.route(deleteAlertRoute); - -beforeEach(() => jest.resetAllMocks()); - -test('deletes an alert with proper parameters', async () => { - const request = { - method: 'DELETE', - url: '/api/alert/1', - }; - - alertsClient.delete.mockResolvedValueOnce({}); - const { payload, statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(payload).toEqual(''); - expect(alertsClient.delete).toHaveBeenCalledTimes(1); - expect(alertsClient.delete.mock.calls[0]).toMatchInlineSnapshot(` -Array [ - Object { - "id": "1", - }, -] -`); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/delete.ts b/x-pack/legacy/plugins/alerting/server/routes/delete.ts deleted file mode 100644 index 24a1f6777b17b7..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/delete.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; -import Joi from 'joi'; - -interface DeleteRequest extends Hapi.Request { - params: { - id: string; - }; -} - -export const deleteAlertRoute = { - method: 'DELETE', - path: '/api/alert/{id}', - config: { - tags: ['access:alerting-all'], - validate: { - params: Joi.object() - .keys({ - id: Joi.string().required(), - }) - .required(), - }, - }, - async handler(request: DeleteRequest, h: Hapi.ResponseToolkit) { - const { id } = request.params; - const alertsClient = request.getAlertsClient!(); - await alertsClient.delete({ id }); - return h.response().code(204); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/disable.test.ts b/x-pack/legacy/plugins/alerting/server/routes/disable.test.ts deleted file mode 100644 index d2214f5c7c175e..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/disable.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { disableAlertRoute } from './disable'; - -const { server, alertsClient } = createMockServer(); -server.route(disableAlertRoute); - -test('disables an alert', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/_disable', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.disable).toHaveBeenCalledWith({ id: '1' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/disable.ts b/x-pack/legacy/plugins/alerting/server/routes/disable.ts deleted file mode 100644 index 2e88d3b5b96da0..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/disable.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -export const disableAlertRoute = { - method: 'POST', - path: '/api/alert/{id}/_disable', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: Hapi.Request, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.disable({ id: request.params.id }); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/enable.test.ts b/x-pack/legacy/plugins/alerting/server/routes/enable.test.ts deleted file mode 100644 index bc5498af619893..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/enable.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { enableAlertRoute } from './enable'; - -const { server, alertsClient } = createMockServer(); -server.route(enableAlertRoute); - -test('enables an alert', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/_enable', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.enable).toHaveBeenCalledWith({ id: '1' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/enable.ts b/x-pack/legacy/plugins/alerting/server/routes/enable.ts deleted file mode 100644 index 28080db7b02304..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/enable.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -export const enableAlertRoute = { - method: 'POST', - path: '/api/alert/{id}/_enable', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: Hapi.Request, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.enable({ id: request.params.id }); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/find.test.ts b/x-pack/legacy/plugins/alerting/server/routes/find.test.ts deleted file mode 100644 index 7b86fb3fbd28e9..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/find.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { findAlertRoute } from './find'; - -const { server, alertsClient } = createMockServer(); -server.route(findAlertRoute); - -beforeEach(() => jest.resetAllMocks()); - -test('sends proper arguments to alert find function', async () => { - const request = { - method: 'GET', - url: - '/api/alert/_find?' + - 'per_page=1&' + - 'page=1&' + - 'search=text*&' + - 'default_search_operator=AND&' + - 'search_fields=description&' + - 'sort_field=description&' + - 'fields=description', - }; - - const expectedResult = { - page: 1, - perPage: 1, - total: 0, - data: [], - }; - - alertsClient.find.mockResolvedValueOnce(expectedResult); - const { payload, statusCode } = await server.inject(request); - expect(statusCode).toBe(200); - const response = JSON.parse(payload); - expect(response).toEqual(expectedResult); - expect(alertsClient.find).toHaveBeenCalledTimes(1); - expect(alertsClient.find.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Object { - "options": Object { - "defaultSearchOperator": "AND", - "fields": Array [ - "description", - ], - "filter": undefined, - "hasReference": undefined, - "page": 1, - "perPage": 1, - "search": "text*", - "searchFields": Array [ - "description", - ], - "sortField": "description", - }, - }, - ] - `); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/find.ts b/x-pack/legacy/plugins/alerting/server/routes/find.ts deleted file mode 100644 index 75cf93b18398ff..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/find.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Joi from 'joi'; -import Hapi from 'hapi'; - -import { WithoutQueryAndParams } from '../types'; - -interface FindRequest extends WithoutQueryAndParams { - query: { - per_page: number; - page: number; - search?: string; - default_search_operator: 'AND' | 'OR'; - search_fields?: string[]; - sort_field?: string; - has_reference?: { - type: string; - id: string; - }; - fields?: string[]; - filter?: string; - }; -} - -export const findAlertRoute = { - method: 'GET', - path: '/api/alert/_find', - config: { - tags: ['access:alerting-read'], - validate: { - query: Joi.object() - .keys({ - per_page: Joi.number() - .min(0) - .default(20), - page: Joi.number() - .min(1) - .default(1), - search: Joi.string() - .allow('') - .optional(), - default_search_operator: Joi.string() - .valid('OR', 'AND') - .default('OR'), - search_fields: Joi.array() - .items(Joi.string()) - .single(), - sort_field: Joi.string(), - has_reference: Joi.object() - .keys({ - type: Joi.string().required(), - id: Joi.string().required(), - }) - .optional(), - fields: Joi.array() - .items(Joi.string()) - .single(), - filter: Joi.string() - .allow('') - .optional(), - }) - .default(), - }, - }, - async handler(request: FindRequest) { - const { query } = request; - const alertsClient = request.getAlertsClient!(); - return await alertsClient.find({ - options: { - perPage: query.per_page, - page: query.page, - search: query.search, - defaultSearchOperator: query.default_search_operator, - searchFields: query.search_fields, - sortField: query.sort_field, - hasReference: query.has_reference, - fields: query.fields, - filter: query.filter, - }, - }); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/get.test.ts b/x-pack/legacy/plugins/alerting/server/routes/get.test.ts deleted file mode 100644 index 320e9042d87c59..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/get.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { getAlertRoute } from './get'; - -const { server, alertsClient } = createMockServer(); -server.route(getAlertRoute); - -const mockedAlert = { - id: '1', - alertTypeId: '1', - schedule: { interval: '10s' }, - params: { - bar: true, - }, - createdAt: new Date(), - updatedAt: new Date(), - actions: [ - { - group: 'default', - id: '2', - actionTypeId: 'test', - params: { - foo: true, - }, - }, - ], - consumer: 'bar', - name: 'abc', - tags: ['foo'], - enabled: true, - muteAll: false, - createdBy: '', - updatedBy: '', - apiKey: '', - apiKeyOwner: '', - throttle: '30s', - mutedInstanceIds: [], -}; - -beforeEach(() => jest.resetAllMocks()); - -test('calls get with proper parameters', async () => { - const request = { - method: 'GET', - url: '/api/alert/1', - }; - - alertsClient.get.mockResolvedValueOnce(mockedAlert); - const { payload, statusCode } = await server.inject(request); - expect(statusCode).toBe(200); - const { createdAt, updatedAt, ...response } = JSON.parse(payload); - expect({ createdAt: new Date(createdAt), updatedAt: new Date(updatedAt), ...response }).toEqual( - mockedAlert - ); - expect(alertsClient.get).toHaveBeenCalledTimes(1); - expect(alertsClient.get.mock.calls[0]).toMatchInlineSnapshot(` -Array [ - Object { - "id": "1", - }, -] -`); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/get.ts b/x-pack/legacy/plugins/alerting/server/routes/get.ts deleted file mode 100644 index 67991aa575a218..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/get.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Joi from 'joi'; -import Hapi from 'hapi'; - -interface GetRequest extends Hapi.Request { - params: { - id: string; - }; -} - -export const getAlertRoute = { - method: 'GET', - path: `/api/alert/{id}`, - options: { - tags: ['access:alerting-read'], - validate: { - params: Joi.object() - .keys({ - id: Joi.string().required(), - }) - .required(), - }, - }, - async handler(request: GetRequest) { - const { id } = request.params; - const alertsClient = request.getAlertsClient!(); - return await alertsClient.get({ id }); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/get_alert_state.test.ts b/x-pack/legacy/plugins/alerting/server/routes/get_alert_state.test.ts deleted file mode 100644 index 9e3b3b6579eadc..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/get_alert_state.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { getAlertStateRoute } from './get_alert_state'; -import { SavedObjectsErrorHelpers } from 'src/core/server'; - -const { server, alertsClient } = createMockServer(); -server.route(getAlertStateRoute); - -const mockedAlertState = { - alertTypeState: { - some: 'value', - }, - alertInstances: { - first_instance: { - state: {}, - meta: { - lastScheduledActions: { - group: 'first_group', - date: new Date(), - }, - }, - }, - second_instance: {}, - }, -}; - -beforeEach(() => jest.resetAllMocks()); - -test('gets alert state', async () => { - const request = { - method: 'GET', - url: '/api/alert/1/state', - }; - - alertsClient.getAlertState.mockResolvedValueOnce(mockedAlertState); - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(200); - expect(alertsClient.getAlertState).toHaveBeenCalledWith({ id: '1' }); -}); - -test('returns NO-CONTENT when alert exists but has no task state yet', async () => { - const request = { - method: 'GET', - url: '/api/alert/1/state', - }; - - alertsClient.getAlertState.mockResolvedValueOnce(undefined); - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.getAlertState).toHaveBeenCalledWith({ id: '1' }); -}); - -test('returns NOT-FOUND when alert is not found', async () => { - const request = { - method: 'GET', - url: '/api/alert/1/state', - }; - - alertsClient.getAlertState.mockRejectedValue( - SavedObjectsErrorHelpers.createGenericNotFoundError('alert', '1') - ); - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(404); - expect(alertsClient.getAlertState).toHaveBeenCalledWith({ id: '1' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/get_alert_state.ts b/x-pack/legacy/plugins/alerting/server/routes/get_alert_state.ts deleted file mode 100644 index 12136a975bb19c..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/get_alert_state.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Joi from 'joi'; -import Hapi from 'hapi'; - -interface GetAlertStateRequest extends Hapi.Request { - params: { - id: string; - }; -} - -export const getAlertStateRoute = { - method: 'GET', - path: '/api/alert/{id}/state', - options: { - tags: ['access:alerting-read'], - validate: { - params: Joi.object() - .keys({ - id: Joi.string().required(), - }) - .required(), - }, - }, - async handler(request: GetAlertStateRequest, h: Hapi.ResponseToolkit) { - const { id } = request.params; - const alertsClient = request.getAlertsClient!(); - const state = await alertsClient.getAlertState({ id }); - return state ? state : h.response().code(204); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/list_alert_types.test.ts b/x-pack/legacy/plugins/alerting/server/routes/list_alert_types.test.ts deleted file mode 100644 index 46f02812e0f6c5..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/list_alert_types.test.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { listAlertTypesRoute } from './list_alert_types'; - -const { server, alertTypeRegistry } = createMockServer(); -server.route(listAlertTypesRoute); - -beforeEach(() => jest.resetAllMocks()); - -test('calls the list function', async () => { - const request = { - method: 'GET', - url: '/api/alert/types', - }; - - alertTypeRegistry.list.mockReturnValueOnce([]); - const { payload, statusCode } = await server.inject(request); - expect(statusCode).toBe(200); - const response = JSON.parse(payload); - expect(response).toEqual([]); - expect(alertTypeRegistry.list).toHaveBeenCalledTimes(1); - expect(alertTypeRegistry.list.mock.calls[0]).toMatchInlineSnapshot(`Array []`); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/list_alert_types.ts b/x-pack/legacy/plugins/alerting/server/routes/list_alert_types.ts deleted file mode 100644 index 13aaf6bfe452e3..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/list_alert_types.ts +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -export const listAlertTypesRoute = { - method: 'GET', - path: `/api/alert/types`, - config: { - tags: ['access:alerting-read'], - }, - async handler(request: Hapi.Request) { - return request.server.plugins.alerting!.start.listTypes(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/mute_all.test.ts b/x-pack/legacy/plugins/alerting/server/routes/mute_all.test.ts deleted file mode 100644 index 408a037edc345c..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/mute_all.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { muteAllAlertRoute } from './mute_all'; - -const { server, alertsClient } = createMockServer(); -server.route(muteAllAlertRoute); - -test('mutes an alert', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/_mute_all', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.muteAll).toHaveBeenCalledWith({ id: '1' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/mute_all.ts b/x-pack/legacy/plugins/alerting/server/routes/mute_all.ts deleted file mode 100644 index 90ae9b11b2f430..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/mute_all.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -interface MuteAllRequest extends Hapi.Request { - params: { - id: string; - }; -} - -export const muteAllAlertRoute = { - method: 'POST', - path: '/api/alert/{id}/_mute_all', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: MuteAllRequest, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.muteAll(request.params); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/mute_instance.test.ts b/x-pack/legacy/plugins/alerting/server/routes/mute_instance.test.ts deleted file mode 100644 index 697a68763adf6f..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/mute_instance.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { muteAlertInstanceRoute } from './mute_instance'; - -const { server, alertsClient } = createMockServer(); -server.route(muteAlertInstanceRoute); - -test('mutes an alert instance', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/alert_instance/2/_mute', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.muteInstance).toHaveBeenCalledWith({ alertId: '1', alertInstanceId: '2' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/mute_instance.ts b/x-pack/legacy/plugins/alerting/server/routes/mute_instance.ts deleted file mode 100644 index 503a07af88bca3..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/mute_instance.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -interface MuteInstanceRequest extends Hapi.Request { - params: { - alertId: string; - alertInstanceId: string; - }; -} - -export const muteAlertInstanceRoute = { - method: 'POST', - path: '/api/alert/{alertId}/alert_instance/{alertInstanceId}/_mute', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: MuteInstanceRequest, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.muteInstance(request.params); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/unmute_all.test.ts b/x-pack/legacy/plugins/alerting/server/routes/unmute_all.test.ts deleted file mode 100644 index c28f51b405a3e0..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/unmute_all.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { unmuteAllAlertRoute } from './unmute_all'; - -const { server, alertsClient } = createMockServer(); -server.route(unmuteAllAlertRoute); - -test('unmutes an alert', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/_unmute_all', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.unmuteAll).toHaveBeenCalledWith({ id: '1' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/unmute_all.ts b/x-pack/legacy/plugins/alerting/server/routes/unmute_all.ts deleted file mode 100644 index 8bb119c6000965..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/unmute_all.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -interface UnmuteAllRequest extends Hapi.Request { - params: { - id: string; - }; -} - -export const unmuteAllAlertRoute = { - method: 'POST', - path: '/api/alert/{id}/_unmute_all', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: UnmuteAllRequest, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.unmuteAll(request.params); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/unmute_instance.test.ts b/x-pack/legacy/plugins/alerting/server/routes/unmute_instance.test.ts deleted file mode 100644 index 5c8f23236e2b04..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/unmute_instance.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { unmuteAlertInstanceRoute } from './unmute_instance'; - -const { server, alertsClient } = createMockServer(); -server.route(unmuteAlertInstanceRoute); - -test('unmutes an alert instance', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/alert_instance/2/_unmute', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.unmuteInstance).toHaveBeenCalledWith({ alertId: '1', alertInstanceId: '2' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/unmute_instance.ts b/x-pack/legacy/plugins/alerting/server/routes/unmute_instance.ts deleted file mode 100644 index 1d1145e010741e..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/unmute_instance.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -interface UnmuteInstanceRequest extends Hapi.Request { - params: { - alertId: string; - alertInstanceId: string; - }; -} - -export const unmuteAlertInstanceRoute = { - method: 'POST', - path: '/api/alert/{alertId}/alert_instance/{alertInstanceId}/_unmute', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: UnmuteInstanceRequest, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.unmuteInstance(request.params); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/update.test.ts b/x-pack/legacy/plugins/alerting/server/routes/update.test.ts deleted file mode 100644 index 83b70b505234f9..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/update.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { updateAlertRoute } from './update'; - -const { server, alertsClient } = createMockServer(); -server.route(updateAlertRoute); - -beforeEach(() => jest.resetAllMocks()); - -const mockedResponse = { - id: '1', - alertTypeId: '1', - tags: ['foo'], - schedule: { interval: '12s' }, - params: { - otherField: false, - }, - createdAt: new Date(), - updatedAt: new Date(), - actions: [ - { - group: 'default', - id: '2', - actionTypeId: 'test', - params: { - baz: true, - }, - }, - ], -}; - -test('calls the update function with proper parameters', async () => { - const request = { - method: 'PUT', - url: '/api/alert/1', - payload: { - throttle: null, - name: 'abc', - tags: ['bar'], - schedule: { interval: '12s' }, - params: { - otherField: false, - }, - actions: [ - { - group: 'default', - id: '2', - params: { - baz: true, - }, - }, - ], - }, - }; - - alertsClient.update.mockResolvedValueOnce(mockedResponse); - const { payload, statusCode } = await server.inject(request); - expect(statusCode).toBe(200); - const { createdAt, updatedAt, ...response } = JSON.parse(payload); - expect({ createdAt: new Date(createdAt), updatedAt: new Date(updatedAt), ...response }).toEqual( - mockedResponse - ); - expect(alertsClient.update).toHaveBeenCalledTimes(1); - expect(alertsClient.update.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Object { - "data": Object { - "actions": Array [ - Object { - "group": "default", - "id": "2", - "params": Object { - "baz": true, - }, - }, - ], - "name": "abc", - "params": Object { - "otherField": false, - }, - "schedule": Object { - "interval": "12s", - }, - "tags": Array [ - "bar", - ], - "throttle": null, - }, - "id": "1", - }, - ] - `); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/update.ts b/x-pack/legacy/plugins/alerting/server/routes/update.ts deleted file mode 100644 index bc55d484656023..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/update.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Joi from 'joi'; -import Hapi from 'hapi'; -import { getDurationSchema } from '../lib'; -import { IntervalSchedule } from '../types'; - -interface UpdateRequest extends Hapi.Request { - params: { - id: string; - }; - payload: { - alertTypeId: string; - name: string; - tags: string[]; - schedule: IntervalSchedule; - actions: Array<{ - group: string; - id: string; - params: Record; - }>; - params: Record; - throttle: string | null; - }; -} - -export const updateAlertRoute = { - method: 'PUT', - path: '/api/alert/{id}', - options: { - tags: ['access:alerting-all'], - validate: { - options: { - abortEarly: false, - }, - payload: Joi.object() - .keys({ - throttle: getDurationSchema() - .required() - .allow(null), - name: Joi.string().required(), - tags: Joi.array() - .items(Joi.string()) - .required(), - schedule: Joi.object() - .keys({ - interval: getDurationSchema().required(), - }) - .required(), - params: Joi.object().required(), - actions: Joi.array() - .items( - Joi.object().keys({ - group: Joi.string().required(), - id: Joi.string().required(), - params: Joi.object().required(), - }) - ) - .required(), - }) - .required(), - }, - }, - async handler(request: UpdateRequest) { - const { id } = request.params; - const alertsClient = request.getAlertsClient!(); - return await alertsClient.update({ id, data: request.payload }); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/update_api_key.test.ts b/x-pack/legacy/plugins/alerting/server/routes/update_api_key.test.ts deleted file mode 100644 index 9bfe26d56dabf8..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/update_api_key.test.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createMockServer } from './_mock_server'; -import { updateApiKeyRoute } from './update_api_key'; - -const { server, alertsClient } = createMockServer(); -server.route(updateApiKeyRoute); - -test('updates api key for an alert', async () => { - const request = { - method: 'POST', - url: '/api/alert/1/_update_api_key', - }; - - const { statusCode } = await server.inject(request); - expect(statusCode).toBe(204); - expect(alertsClient.updateApiKey).toHaveBeenCalledWith({ id: '1' }); -}); diff --git a/x-pack/legacy/plugins/alerting/server/routes/update_api_key.ts b/x-pack/legacy/plugins/alerting/server/routes/update_api_key.ts deleted file mode 100644 index 754ea453a27cb0..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/routes/update_api_key.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; - -export const updateApiKeyRoute = { - method: 'POST', - path: '/api/alert/{id}/_update_api_key', - config: { - tags: ['access:alerting-all'], - response: { - emptyStatusCode: 204, - }, - }, - async handler(request: Hapi.Request, h: Hapi.ResponseToolkit) { - const alertsClient = request.getAlertsClient!(); - await alertsClient.updateApiKey({ id: request.params.id }); - return h.response(); - }, -}; diff --git a/x-pack/legacy/plugins/alerting/server/shim.ts b/x-pack/legacy/plugins/alerting/server/shim.ts deleted file mode 100644 index bc8b0eb863634c..00000000000000 --- a/x-pack/legacy/plugins/alerting/server/shim.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import Hapi from 'hapi'; -import { Legacy } from 'kibana'; -import { LegacySpacesPlugin as SpacesPluginStartContract } from '../../spaces'; -import { - TaskManagerStartContract, - TaskManagerSetupContract, -} from '../../../../plugins/task_manager/server'; -import { getTaskManagerSetup, getTaskManagerStart } from '../../task_manager/server'; -import { XPackMainPlugin } from '../../xpack_main/server/xpack_main'; -import KbnServer from '../../../../../src/legacy/server/kbn_server'; -import { - EncryptedSavedObjectsPluginSetup, - EncryptedSavedObjectsPluginStart, -} from '../../../../plugins/encrypted_saved_objects/server'; -import { SecurityPluginSetup } from '../../../../plugins/security/server'; -import { - CoreSetup, - LoggerFactory, - SavedObjectsLegacyService, -} from '../../../../../src/core/server'; -import { - ActionsPlugin, - PluginSetupContract as ActionsPluginSetupContract, - PluginStartContract as ActionsPluginStartContract, -} from '../../../../plugins/actions/server'; -import { LicensingPluginSetup } from '../../../../plugins/licensing/server'; - -// Extend PluginProperties to indicate which plugins are guaranteed to exist -// due to being marked as dependencies -interface Plugins extends Hapi.PluginProperties { - actions: ActionsPlugin; -} - -export interface Server extends Legacy.Server { - plugins: Plugins; -} - -/** - * Shim what we're thinking setup and start contracts will look like - */ -export type SecurityPluginSetupContract = Pick; -export type SecurityPluginStartContract = Pick; -export type XPackMainPluginSetupContract = Pick; - -/** - * New platform interfaces - */ -export interface AlertingPluginInitializerContext { - logger: LoggerFactory; -} -export interface AlertingCoreSetup { - elasticsearch: CoreSetup['elasticsearch']; - http: { - route: (route: Hapi.ServerRoute) => void; - basePath: { - serverBasePath: string; - }; - }; -} -export interface AlertingCoreStart { - savedObjects: SavedObjectsLegacyService; -} -export interface AlertingPluginsSetup { - security?: SecurityPluginSetupContract; - taskManager: TaskManagerSetupContract; - actions: ActionsPluginSetupContract; - xpack_main: XPackMainPluginSetupContract; - encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; - licensing: LicensingPluginSetup; -} -export interface AlertingPluginsStart { - actions: ActionsPluginStartContract; - security?: SecurityPluginStartContract; - spaces: () => SpacesPluginStartContract | undefined; - encryptedSavedObjects: EncryptedSavedObjectsPluginStart; - taskManager: TaskManagerStartContract; -} - -/** - * Shim - * - * @param server Hapi server instance - */ -export function shim( - server: Server -): { - initializerContext: AlertingPluginInitializerContext; - coreSetup: AlertingCoreSetup; - coreStart: AlertingCoreStart; - pluginsSetup: AlertingPluginsSetup; - pluginsStart: AlertingPluginsStart; -} { - const newPlatform = ((server as unknown) as KbnServer).newPlatform; - - const initializerContext: AlertingPluginInitializerContext = { - logger: newPlatform.coreContext.logger, - }; - - const coreSetup: AlertingCoreSetup = { - elasticsearch: newPlatform.setup.core.elasticsearch, - http: { - route: server.route.bind(server), - basePath: newPlatform.setup.core.http.basePath, - }, - }; - - const coreStart: AlertingCoreStart = { - savedObjects: server.savedObjects, - }; - - const pluginsSetup: AlertingPluginsSetup = { - security: newPlatform.setup.plugins.security as SecurityPluginSetupContract | undefined, - taskManager: getTaskManagerSetup(server)!, - actions: newPlatform.setup.plugins.actions as ActionsPluginSetupContract, - xpack_main: server.plugins.xpack_main, - encryptedSavedObjects: newPlatform.setup.plugins - .encryptedSavedObjects as EncryptedSavedObjectsPluginSetup, - licensing: newPlatform.setup.plugins.licensing as LicensingPluginSetup, - }; - - const pluginsStart: AlertingPluginsStart = { - security: newPlatform.setup.plugins.security as SecurityPluginStartContract | undefined, - actions: newPlatform.start.plugins.actions as ActionsPluginStartContract, - // TODO: Currently a function because it's an optional dependency that - // initializes after this function is called - spaces: () => server.plugins.spaces, - encryptedSavedObjects: newPlatform.start.plugins - .encryptedSavedObjects as EncryptedSavedObjectsPluginStart, - taskManager: getTaskManagerStart(server)!, - }; - - return { - initializerContext, - coreSetup, - coreStart, - pluginsSetup, - pluginsStart, - }; -} diff --git a/x-pack/legacy/plugins/monitoring/index.ts b/x-pack/legacy/plugins/monitoring/index.ts index 1186fde52dc46f..3a23140104e166 100644 --- a/x-pack/legacy/plugins/monitoring/index.ts +++ b/x-pack/legacy/plugins/monitoring/index.ts @@ -108,15 +108,16 @@ export const monitoring = (kibana: LegacyPluginApi): LegacyPluginSpec => { }; const legacyPlugins = plugins as Partial & { infra?: InfraPlugin }; - const { xpack_main, elasticsearch, infra, alerting } = legacyPlugins; + const { xpack_main, elasticsearch, infra } = legacyPlugins; const { core: coreSetup, - plugins: { usageCollection, licensing }, + plugins: { usageCollection, licensing, alerting }, } = server.newPlatform.setup; const pluginsSetup: PluginsSetup = { usageCollection, licensing, + alerting, }; const __LEGACY: LegacySetup = { @@ -125,7 +126,6 @@ export const monitoring = (kibana: LegacyPluginApi): LegacyPluginSpec => { xpack_main, elasticsearch, infra, - alerting, }, }; diff --git a/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx b/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx index 0ee0015ed39a70..c1019cb64be529 100644 --- a/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx +++ b/x-pack/legacy/plugins/monitoring/public/components/alerts/status.tsx @@ -19,7 +19,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION } from 'ui/documentation_links'; -import { Alert } from '../../../../alerting/server/types'; +import { Alert } from '../../../../../../plugins/alerting/common'; import { getSetupModeState, addSetupModeCallback, toggleSetupMode } from '../../lib/setup_mode'; import { NUMBER_OF_MIGRATED_ALERTS, ALERT_TYPE_PREFIX } from '../../../common/constants'; import { AlertsConfiguration } from './configuration'; diff --git a/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.test.ts b/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.test.ts index 38b4e6c60ca485..1d52ab04dcdbdd 100644 --- a/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.test.ts +++ b/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.test.ts @@ -11,9 +11,8 @@ import { MONITORING_CONFIG_ALERTING_EMAIL_ADDRESS, } from '../../common/constants'; import { Logger } from 'src/core/server'; -import { AlertServices } from '../../../alerting/server/types'; +import { AlertServices, AlertInstance } from '../../../../../plugins/alerting/server'; import { savedObjectsClientMock } from 'src/core/server/mocks'; -import { AlertInstance } from '../../../alerting/server/alert_instance'; import { AlertState, AlertClusterState, diff --git a/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.ts b/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.ts index 8688a2b08efc4e..f968e90f70b2da 100644 --- a/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.ts +++ b/x-pack/legacy/plugins/monitoring/server/alerts/license_expiration.ts @@ -10,7 +10,7 @@ import { Legacy } from 'kibana'; import { Logger } from 'src/core/server'; import { i18n } from '@kbn/i18n'; import { ALERT_TYPE_LICENSE_EXPIRATION, INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; -import { AlertType } from '../../../alerting'; +import { AlertType } from '../../../../../plugins/alerting/server'; import { fetchLicenses } from '../lib/alerts/fetch_licenses'; import { fetchDefaultEmailAddress } from '../lib/alerts/fetch_default_email_address'; import { fetchClusters } from '../lib/alerts/fetch_clusters'; diff --git a/x-pack/legacy/plugins/monitoring/server/alerts/types.d.ts b/x-pack/legacy/plugins/monitoring/server/alerts/types.d.ts index 6346ca00dabbd2..76fc7074e411cc 100644 --- a/x-pack/legacy/plugins/monitoring/server/alerts/types.d.ts +++ b/x-pack/legacy/plugins/monitoring/server/alerts/types.d.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { Moment } from 'moment'; -import { AlertExecutorOptions } from '../../../alerting'; +import { AlertExecutorOptions } from '../../../../../plugins/alerting/server'; export interface AlertLicense { status: string; diff --git a/x-pack/legacy/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts b/x-pack/legacy/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts index 8a75fc1fbbd82f..520cb31e151ae7 100644 --- a/x-pack/legacy/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts +++ b/x-pack/legacy/plugins/monitoring/server/lib/alerts/license_expiration.lib.ts @@ -5,7 +5,7 @@ */ import { Moment } from 'moment-timezone'; import { i18n } from '@kbn/i18n'; -import { AlertInstance } from '../../../../alerting/server/alert_instance'; +import { AlertInstance } from '../../../../../../plugins/alerting/server'; import { AlertLicense } from '../../alerts/types'; const RESOLVED_SUBJECT = i18n.translate( diff --git a/x-pack/legacy/plugins/monitoring/server/plugin.js b/x-pack/legacy/plugins/monitoring/server/plugin.js index 304d2c08a16885..3d6d110a019493 100644 --- a/x-pack/legacy/plugins/monitoring/server/plugin.js +++ b/x-pack/legacy/plugins/monitoring/server/plugin.js @@ -34,7 +34,7 @@ export class Plugin { } = __LEGACY; const config = monitoringConfig(); - const { usageCollection, licensing } = pluginsSetup; + const { usageCollection, licensing, alerting } = pluginsSetup; registerMonitoringCollection(); /* * Register collector objects for stats to show up in the APIs @@ -152,7 +152,7 @@ export class Plugin { }; }); - if (KIBANA_ALERTING_ENABLED && plugins.alerting) { + if (KIBANA_ALERTING_ENABLED && alerting) { // this is not ready right away but we need to register alerts right away async function getMonitoringCluster() { const configs = config.get('xpack.monitoring.elasticsearch'); @@ -174,7 +174,7 @@ export class Plugin { function getLogger(contexts) { return logger.get('plugins', LOGGING_TAG, ...contexts); } - plugins.alerting.setup.registerType( + alerting.registerType( getLicenseExpiration( hapiServer, getMonitoringCluster, diff --git a/x-pack/legacy/plugins/siem/index.ts b/x-pack/legacy/plugins/siem/index.ts index c786dad61c09d0..731ef10aa225e1 100644 --- a/x-pack/legacy/plugins/siem/index.ts +++ b/x-pack/legacy/plugins/siem/index.ts @@ -152,7 +152,6 @@ export const siem = (kibana: any) => { const initializerContext = { ...coreContext, env }; const __legacy = { config: server.config, - alerting: server.plugins.alerting, route: server.route.bind(server), }; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md b/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md index 1d33466a458d23..1e8e3d5e3dd754 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/README.md @@ -152,8 +152,8 @@ logging.events: ``` See these two README.md's pages for more references on the alerting and actions API: -https://github.com/elastic/kibana/blob/master/x-pack/legacy/plugins/alerting/README.md -https://github.com/elastic/kibana/tree/master/x-pack/legacy/plugins/actions +https://github.com/elastic/kibana/blob/master/x-pack/plugins/alerting/README.md +https://github.com/elastic/kibana/tree/master/x-pack/plugins/actions ### Signals API diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/clients_service_mock.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/clients_service_mock.ts index f89e938b8a636c..29131429d12cb6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/clients_service_mock.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/routes/__mocks__/clients_service_mock.ts @@ -8,7 +8,7 @@ import { elasticsearchServiceMock, savedObjectsClientMock, } from '../../../../../../../../../src/core/server/mocks'; -import { alertsClientMock } from '../../../../../../alerting/server/alerts_client.mock'; +import { alertsClientMock } from '../../../../../../../../plugins/alerting/server/mocks'; import { ActionsClient } from '../../../../../../../../plugins/actions/server'; import { actionsClientMock } from '../../../../../../../../plugins/actions/server/mocks'; import { GetScopedClients } from '../../../../services'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts index 61f2e878115093..c8205859407c01 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/create_rules.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Alert } from '../../../../../alerting/common'; +import { Alert } from '../../../../../../../plugins/alerting/common'; import { APP_ID, SIGNALS_ID } from '../../../../common/constants'; import { CreateRuleParams } from './types'; import { addTags } from './add_tags'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/find_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/find_rules.ts index e193e123f42817..f333a7c3407058 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/find_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/find_rules.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { FindResult } from '../../../../../alerting/server/alerts_client'; +import { FindResult } from '../../../../../../../plugins/alerting/server'; import { SIGNALS_ID } from '../../../../common/constants'; import { FindRuleParams } from './types'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts index 25bac383ecf721..9774d10a37d6f9 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { alertsClientMock } from '../../../../../alerting/server/alerts_client.mock'; +import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; import { getResult, getFindResultWithSingleHit, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts index a48957da7aa942..b5e826ed42723b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_existing_prepackaged_rules.ts @@ -5,7 +5,7 @@ */ import { INTERNAL_IMMUTABLE_KEY } from '../../../../common/constants'; -import { AlertsClient } from '../../../../../alerting'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; import { RuleAlertType, isAlertTypes } from './types'; import { findRules } from './find_rules'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts index 35d3489dad6fca..304f9a741c6f40 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.test.ts @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { alertsClientMock } from '../../../../../alerting/server/alerts_client.mock'; import { getResult, getFindResultWithSingleHit, FindHit, } from '../routes/__mocks__/request_responses'; +import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; import { getExportAll } from './get_export_all'; describe('getExportAll', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.ts index dca6eba4e65567..434919f80e149b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_all.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertsClient } from '../../../../../alerting'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; import { getNonPackagedRules } from './get_existing_prepackaged_rules'; import { getExportDetailsNdjson } from './get_export_details_ndjson'; import { transformAlertsToRules, transformRulesToNdjson } from '../routes/rules/utils'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts index 4b6ea527a2027b..98f5df48525300 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.test.ts @@ -4,13 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { alertsClientMock } from '../../../../../alerting/server/alerts_client.mock'; import { getExportByObjectIds, getRulesFromObjects, RulesErrors } from './get_export_by_object_ids'; import { getResult, getFindResultWithSingleHit, FindHit, } from '../routes/__mocks__/request_responses'; +import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; describe('get_export_by_object_ids', () => { describe('getExportByObjectIds', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.ts index 7e0d61d040617e..e3b38a879fc3d6 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/get_export_by_object_ids.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertsClient } from '../../../../../alerting'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; import { getExportDetailsNdjson } from './get_export_details_ndjson'; import { isAlertType } from '../rules/types'; import { readRules } from './read_rules'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts index 07e8c6940e7476..3d9ec128963f62 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/install_prepacked_rules.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Alert } from '../../../../../../../plugins/alerting/common'; import { ActionsClient } from '../../../../../../../plugins/actions/server'; -import { AlertsClient } from '../../../../../alerting'; -import { Alert } from '../../../../../alerting/server/types'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; import { createRules } from './create_rules'; import { PrepackagedRules } from '../types'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts index f560b67cdc587e..1d904b2b349ae7 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/patch_rules.ts @@ -5,7 +5,7 @@ */ import { defaults } from 'lodash/fp'; -import { PartialAlert } from '../../../../../alerting/server/types'; +import { PartialAlert } from '../../../../../../../plugins/alerting/server'; import { readRules } from './read_rules'; import { PatchRuleParams, IRuleSavedAttributesSavedObjectAttributes } from './types'; import { addTags } from './add_tags'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts index c637860c5646a9..45507a69f50c2f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.test.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { alertsClientMock } from '../../../../../alerting/server/alerts_client.mock'; import { readRules } from './read_rules'; +import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; import { getResult, getFindResultWithSingleHit } from '../routes/__mocks__/request_responses'; describe('read_rules', () => { diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts index e8e883701c6a94..cbe6dbda8449f7 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/read_rules.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SanitizedAlert } from '../../../../../alerting/common'; +import { SanitizedAlert } from '../../../../../../../plugins/alerting/common'; import { INTERNAL_RULE_ID_KEY } from '../../../../common/constants'; import { findRules } from './find_rules'; import { ReadRuleParams, isAlertType } from './types'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts index 8579447a74c69b..fa22765c143e1b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/types.ts @@ -13,12 +13,12 @@ import { SavedObjectsFindResponse, SavedObjectsClientContract, } from 'kibana/server'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; +import { Alert } from '../../../../../../../plugins/alerting/common'; import { SIGNALS_ID } from '../../../../common/constants'; import { LegacyRequest } from '../../../types'; -import { AlertsClient } from '../../../../../alerting/server'; import { ActionsClient } from '../../../../../../../plugins/actions/server'; import { RuleAlertParams, RuleTypeParams, RuleAlertParamsRest } from '../types'; -import { Alert } from '../../../../../alerting/server/types'; export type PatchRuleAlertParamsRest = Partial & { id: string | undefined; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts index 2fa903f3d713f5..c63237c93daf49 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_prepacked_rules.ts @@ -6,7 +6,7 @@ import { SavedObjectsClientContract } from 'kibana/server'; import { ActionsClient } from '../../../../../../../plugins/actions/server'; -import { AlertsClient } from '../../../../../alerting'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; import { patchRules } from './patch_rules'; import { PrepackagedRules } from '../types'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts index 1dc5d8429fab8f..9ead8313b2c91c 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/rules/update_rules.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PartialAlert } from '../../../../../alerting/server/types'; +import { PartialAlert } from '../../../../../../../plugins/alerting/server'; import { readRules } from './read_rules'; import { IRuleSavedAttributesSavedObjectAttributes, UpdateRuleParams } from './types'; import { addTags } from './add_tags'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_instances.sh b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_instances.sh index f42d4a52594a7b..b5f272d0a8a093 100755 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_instances.sh +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_instances.sh @@ -10,7 +10,7 @@ set -e ./check_env_variables.sh # Example: ./get_alert_instances.sh -# https://github.com/elastic/kibana/blob/master/x-pack/legacy/plugins/alerting/README.md#get-apialert_find-find-alerts +# https://github.com/elastic/kibana/blob/master/x-pack/plugins/alerting/README.md#get-apialert_find-find-alerts curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ -X GET ${KIBANA_URL}${SPACE_URL}/api/alert/_find \ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_types.sh b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_types.sh index a7c6fa567ecdd8..28c250e9368a62 100755 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_types.sh +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/scripts/get_alert_types.sh @@ -10,7 +10,7 @@ set -e ./check_env_variables.sh # Example: ./get_alert_types.sh -# https://github.com/elastic/kibana/blob/master/x-pack/legacy/plugins/alerting/README.md#get-apialerttypes-list-alert-types +# https://github.com/elastic/kibana/blob/master/x-pack/plugins/alerting/README.md#get-apialerttypes-list-alert-types curl -s -k \ -u ${ELASTICSEARCH_USERNAME}:${ELASTICSEARCH_PASSWORD} \ -X GET ${KIBANA_URL}${SPACE_URL}/api/alert/types \ diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.test.ts index 534215f5a12280..b49f43ce9e7acf 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.test.ts @@ -6,8 +6,8 @@ import { getQueryFilter, getFilter } from './get_filter'; import { savedObjectsClientMock } from 'src/core/server/mocks'; -import { AlertServices } from '../../../../../alerting/server/types'; import { PartialFilter } from '../types'; +import { AlertServices } from '../../../../../../../plugins/alerting/server'; describe('get_filter', () => { let savedObjectsClient = savedObjectsClientMock.create(); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.ts index cb6b8fc75f610d..bcf091544e52a3 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_filter.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertServices } from '../../../../../alerting/server/types'; +import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { assertUnreachable } from '../../../utils/build_query'; import { Filter, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.test.ts index bd7ba915af9b00..18286dc7754e0e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.test.ts @@ -6,9 +6,9 @@ import { savedObjectsClientMock } from 'src/core/server/mocks'; import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; -import { AlertServices } from '../../../../../alerting/server/types'; import { getInputIndex } from './get_input_output_index'; import { defaultIndexPattern } from '../../../../default_index_pattern'; +import { AlertServices } from '../../../../../../../plugins/alerting/server'; describe('get_input_output_index', () => { let savedObjectsClient = savedObjectsClientMock.create(); diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.ts index 624e012717820d..29d4d2182bd535 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/get_input_output_index.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { defaultIndexPattern } from '../../../../default_index_pattern'; -import { AlertServices } from '../../../../../alerting/server/types'; import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; export const getInputIndex = async ( diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts index 8c8cef5dd36695..1cfd2f812a195c 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/search_after_bulk_create.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { RuleTypeParams } from '../types'; -import { AlertServices } from '../../../../../alerting/server/types'; import { Logger } from '../../../../../../../../src/core/server'; import { singleSearchAfter } from './single_search_after'; import { singleBulkCreate } from './single_bulk_create'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts index adc7919a09758a..7d6d6d99fa4229 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_bulk_create.ts @@ -6,7 +6,7 @@ import { countBy, isEmpty } from 'lodash'; import { performance } from 'perf_hooks'; -import { AlertServices } from '../../../../../alerting/server/types'; +import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { SignalSearchResponse, BulkResponse } from './types'; import { RuleTypeParams } from '../types'; import { generateId } from './utils'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_search_after.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_search_after.ts index 3a99500cb34330..a0e7047ad1cd6e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_search_after.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/single_search_after.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { AlertServices } from '../../../../../../../plugins/alerting/server'; import { RuleTypeParams } from '../types'; -import { AlertServices } from '../../../../../alerting/server/types'; import { Logger } from '../../../../../../../../src/core/server'; import { SignalSearchResponse } from './types'; import { buildEventsSearchQuery } from './build_events_query'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts index e9159ab87a0c07..d8b7dd72b6a864 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/types.ts @@ -7,7 +7,11 @@ import { RuleAlertParams, OutputRuleAlertRest } from '../types'; import { SearchResponse } from '../../types'; import { LegacyRequest } from '../../../types'; -import { AlertType, State, AlertExecutorOptions } from '../../../../../alerting/server/types'; +import { + AlertType, + State, + AlertExecutorOptions, +} from '../../../../../../../plugins/alerting/server'; export interface SignalsParams { signalIds: string[] | undefined | null; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/utils.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/utils.ts index 940ea8be2ac36a..016aed9fabcd6b 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/utils.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/signals/utils.ts @@ -6,8 +6,7 @@ import { createHash } from 'crypto'; import moment from 'moment'; import dateMath from '@elastic/datemath'; - -import { parseDuration } from '../../../../../alerting/server/lib'; +import { parseDuration } from '../../../../../../../plugins/alerting/server'; export const generateId = ( docIndex: string, diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.test.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.test.ts index 940011924de79d..80c107c991bb75 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { alertsClientMock } from '../../../../../alerting/server/alerts_client.mock'; +import { alertsClientMock } from '../../../../../../../plugins/alerting/server/mocks'; import { getResult, getFindResultWithMultiHits } from '../routes/__mocks__/request_responses'; import { INTERNAL_RULE_ID_KEY, INTERNAL_IDENTIFIER } from '../../../../common/constants'; import { readRawTags, readTags, convertTagsToSet, convertToTags, isTags } from './read_tags'; diff --git a/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.ts b/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.ts index 02456732df3b4e..d343bca8c97bb1 100644 --- a/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.ts +++ b/x-pack/legacy/plugins/siem/server/lib/detection_engine/tags/read_tags.ts @@ -6,7 +6,7 @@ import { has } from 'lodash/fp'; import { INTERNAL_IDENTIFIER } from '../../../../common/constants'; -import { AlertsClient } from '../../../../../alerting'; +import { AlertsClient } from '../../../../../../../plugins/alerting/server'; import { findRules } from '../rules/find_rules'; export interface TagType { diff --git a/x-pack/legacy/plugins/siem/server/plugin.ts b/x-pack/legacy/plugins/siem/server/plugin.ts index e15248e5200eee..6f28fd7d67bd08 100644 --- a/x-pack/legacy/plugins/siem/server/plugin.ts +++ b/x-pack/legacy/plugins/siem/server/plugin.ts @@ -6,6 +6,10 @@ import { i18n } from '@kbn/i18n'; +import { + PluginStartContract as AlertingStart, + PluginSetupContract as AlertingSetup, +} from '../../../../plugins/alerting/server'; import { CoreSetup, CoreStart, @@ -38,10 +42,12 @@ export interface SetupPlugins { features: FeaturesSetup; security: SecuritySetup; spaces?: SpacesSetup; + alerting: AlertingSetup; } export interface StartPlugins { actions: ActionsStart; + alerting: AlertingStart; } export class Plugin { @@ -130,13 +136,13 @@ export class Plugin { }, }); - if (__legacy.alerting != null) { + if (plugins.alerting != null) { const type = signalRulesAlertType({ logger: this.logger, version: this.context.env.packageInfo.version, }); if (isAlertExecutor(type)) { - __legacy.alerting.setup.registerType(type); + plugins.alerting.registerType(type); } } @@ -145,7 +151,7 @@ export class Plugin { } public start(core: CoreStart, plugins: StartPlugins) { - this.clients.start(core.savedObjects, plugins.actions); + this.clients.start(core.savedObjects, plugins.actions, plugins.alerting); this.legacyInitRoutes!(this.clients.createGetScoped()); } diff --git a/x-pack/legacy/plugins/siem/server/services/clients.test.ts b/x-pack/legacy/plugins/siem/server/services/clients.test.ts index 7f63a8f5e949cc..f76494d075f086 100644 --- a/x-pack/legacy/plugins/siem/server/services/clients.test.ts +++ b/x-pack/legacy/plugins/siem/server/services/clients.test.ts @@ -6,6 +6,7 @@ import { coreMock, httpServerMock } from '../../../../../../src/core/server/mocks'; import { actionsMock } from '../../../../../plugins/actions/server/mocks'; +import { alertsMock } from '../../../../../plugins/alerting/server/mocks'; import { ClientsService } from './clients'; @@ -16,13 +17,14 @@ describe('ClientsService', () => { const clients = new ClientsService(); const actions = actionsMock.createStart(); + const alerting = alertsMock.createStart(); const { elasticsearch } = coreMock.createSetup(); const { savedObjects } = coreMock.createStart(); const request = httpServerMock.createRawRequest(); const spacesService = undefined; clients.setup(elasticsearch.dataClient, spacesService); - clients.start(savedObjects, actions); + clients.start(savedObjects, actions, alerting); const { spacesClient } = await clients.createGetScoped()(request); expect(spacesClient.getSpaceId()).toEqual('default'); diff --git a/x-pack/legacy/plugins/siem/server/services/clients.ts b/x-pack/legacy/plugins/siem/server/services/clients.ts index ca50eda4e7a6c7..7ba7230f88493a 100644 --- a/x-pack/legacy/plugins/siem/server/services/clients.ts +++ b/x-pack/legacy/plugins/siem/server/services/clients.ts @@ -12,23 +12,23 @@ import { SavedObjectsClientContract, } from '../../../../../../src/core/server'; import { ActionsClient } from '../../../../../plugins/actions/server'; -import { AlertsClient } from '../../../../../legacy/plugins/alerting/server'; +import { AlertsClient } from '../../../../../plugins/alerting/server'; import { SpacesServiceSetup } from '../../../../../plugins/spaces/server'; import { CoreStart, StartPlugins } from '../plugin'; export interface Clients { actionsClient?: ActionsClient; + alertsClient?: AlertsClient; clusterClient: IScopedClusterClient; spacesClient: { getSpaceId: () => string }; savedObjectsClient: SavedObjectsClientContract; } -interface LegacyClients { - alertsClient?: AlertsClient; -} -export type GetScopedClients = (request: LegacyRequest) => Promise; + +export type GetScopedClients = (request: LegacyRequest) => Promise; export class ClientsService { private actions?: StartPlugins['actions']; + private alerting?: StartPlugins['alerting']; private clusterClient?: IClusterClient; private savedObjects?: CoreStart['savedObjects']; private spacesService?: SpacesServiceSetup; @@ -38,9 +38,14 @@ export class ClientsService { this.spacesService = spacesService; } - public start(savedObjects: CoreStart['savedObjects'], actions: StartPlugins['actions']) { + public start( + savedObjects: CoreStart['savedObjects'], + actions: StartPlugins['actions'], + alerting: StartPlugins['alerting'] + ) { this.savedObjects = savedObjects; this.actions = actions; + this.alerting = alerting; } public createGetScoped(): GetScopedClients { @@ -52,7 +57,7 @@ export class ClientsService { const kibanaRequest = KibanaRequest.from(request); return { - alertsClient: request.getAlertsClient?.(), + alertsClient: await this.alerting?.getAlertsClientWithRequest?.(kibanaRequest), actionsClient: await this.actions?.getActionsClientWithRequest?.(kibanaRequest), clusterClient: this.clusterClient!.asScoped(kibanaRequest), savedObjectsClient: this.savedObjects!.getScopedClient(kibanaRequest), diff --git a/x-pack/plugins/actions/server/routes/find.ts b/x-pack/plugins/actions/server/routes/find.ts index 04656d19bfeb4d..e791aff4fb5983 100644 --- a/x-pack/plugins/actions/server/routes/find.ts +++ b/x-pack/plugins/actions/server/routes/find.ts @@ -12,7 +12,7 @@ import { IKibanaResponse, KibanaResponseFactory, } from 'kibana/server'; -import { FindOptions } from '../../../../legacy/plugins/alerting/server/alerts_client'; +import { FindOptions } from '../../../alerting/server'; import { LicenseState } from '../lib/license_state'; import { verifyApiAccess } from '../lib/license_api_access'; diff --git a/x-pack/legacy/plugins/alerting/README.md b/x-pack/plugins/alerting/README.md similarity index 99% rename from x-pack/legacy/plugins/alerting/README.md rename to x-pack/plugins/alerting/README.md index 2a10c41f12b850..32ca804198ebd4 100644 --- a/x-pack/legacy/plugins/alerting/README.md +++ b/x-pack/plugins/alerting/README.md @@ -77,7 +77,7 @@ Note that the `manage_own_api_key` cluster privilege is not enough - it can be u ### Methods -**server.plugins.alerting.setup.registerType(options)** +**server.newPlatform.setup.plugins.alerting.registerType(options)** The following table describes the properties of the `options` object. @@ -119,7 +119,7 @@ This example receives server and threshold as parameters. It will read the CPU u ``` import { schema } from '@kbn/config-schema'; ... -server.plugins.alerting.setup.registerType({ +server.newPlatform.setup.plugins.alerting.registerType({ id: 'my-alert-type', name: 'My alert type', validate: { @@ -178,7 +178,7 @@ server.plugins.alerting.setup.registerType({ This example only receives threshold as a parameter. It will read the CPU usage of all the servers and schedule individual actions if the reading for a server is greater than the threshold. This is a better implementation than above as only one query is performed for all the servers instead of one query per server. ``` -server.plugins.alerting.setup.registerType({ +server.newPlatform.setup.plugins.alerting.registerType({ id: 'my-alert-type', name: 'My alert type', validate: { diff --git a/x-pack/legacy/plugins/alerting/common/alert.ts b/x-pack/plugins/alerting/common/alert.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/common/alert.ts rename to x-pack/plugins/alerting/common/alert.ts diff --git a/x-pack/legacy/plugins/alerting/common/alert_instance.ts b/x-pack/plugins/alerting/common/alert_instance.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/common/alert_instance.ts rename to x-pack/plugins/alerting/common/alert_instance.ts diff --git a/x-pack/legacy/plugins/alerting/common/alert_task_instance.ts b/x-pack/plugins/alerting/common/alert_task_instance.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/common/alert_task_instance.ts rename to x-pack/plugins/alerting/common/alert_task_instance.ts diff --git a/x-pack/legacy/plugins/alerting/common/date_from_string.test.ts b/x-pack/plugins/alerting/common/date_from_string.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/common/date_from_string.test.ts rename to x-pack/plugins/alerting/common/date_from_string.test.ts diff --git a/x-pack/legacy/plugins/alerting/common/date_from_string.ts b/x-pack/plugins/alerting/common/date_from_string.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/common/date_from_string.ts rename to x-pack/plugins/alerting/common/date_from_string.ts diff --git a/x-pack/legacy/plugins/alerting/common/index.ts b/x-pack/plugins/alerting/common/index.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/common/index.ts rename to x-pack/plugins/alerting/common/index.ts diff --git a/x-pack/plugins/alerting/kibana.json b/x-pack/plugins/alerting/kibana.json new file mode 100644 index 00000000000000..fb5003ede48ce5 --- /dev/null +++ b/x-pack/plugins/alerting/kibana.json @@ -0,0 +1,10 @@ +{ + "id": "alerting", + "server": true, + "version": "8.0.0", + "kibanaVersion": "kibana", + "configPath": ["xpack", "alerting"], + "requiredPlugins": ["licensing", "taskManager", "encryptedSavedObjects", "actions"], + "optionalPlugins": ["spaces", "security"], + "ui": false +} \ No newline at end of file diff --git a/x-pack/legacy/plugins/alerting/server/alert_instance/alert_instance.test.ts b/x-pack/plugins/alerting/server/alert_instance/alert_instance.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alert_instance/alert_instance.test.ts rename to x-pack/plugins/alerting/server/alert_instance/alert_instance.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/alert_instance/alert_instance.ts b/x-pack/plugins/alerting/server/alert_instance/alert_instance.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alert_instance/alert_instance.ts rename to x-pack/plugins/alerting/server/alert_instance/alert_instance.ts diff --git a/x-pack/legacy/plugins/alerting/server/alert_instance/create_alert_instance_factory.test.ts b/x-pack/plugins/alerting/server/alert_instance/create_alert_instance_factory.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alert_instance/create_alert_instance_factory.test.ts rename to x-pack/plugins/alerting/server/alert_instance/create_alert_instance_factory.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/alert_instance/create_alert_instance_factory.ts b/x-pack/plugins/alerting/server/alert_instance/create_alert_instance_factory.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alert_instance/create_alert_instance_factory.ts rename to x-pack/plugins/alerting/server/alert_instance/create_alert_instance_factory.ts diff --git a/x-pack/legacy/plugins/alerting/server/alert_instance/index.ts b/x-pack/plugins/alerting/server/alert_instance/index.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alert_instance/index.ts rename to x-pack/plugins/alerting/server/alert_instance/index.ts diff --git a/x-pack/legacy/plugins/alerting/server/alert_type_registry.mock.ts b/x-pack/plugins/alerting/server/alert_type_registry.mock.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alert_type_registry.mock.ts rename to x-pack/plugins/alerting/server/alert_type_registry.mock.ts diff --git a/x-pack/legacy/plugins/alerting/server/alert_type_registry.test.ts b/x-pack/plugins/alerting/server/alert_type_registry.test.ts similarity index 97% rename from x-pack/legacy/plugins/alerting/server/alert_type_registry.test.ts rename to x-pack/plugins/alerting/server/alert_type_registry.test.ts index 976bed884cd434..1a820d55af8a40 100644 --- a/x-pack/legacy/plugins/alerting/server/alert_type_registry.test.ts +++ b/x-pack/plugins/alerting/server/alert_type_registry.test.ts @@ -6,7 +6,7 @@ import { TaskRunnerFactory } from './task_runner'; import { AlertTypeRegistry } from './alert_type_registry'; -import { taskManagerMock } from '../../../../plugins/task_manager/server/task_manager.mock'; +import { taskManagerMock } from '../../../plugins/task_manager/server/task_manager.mock'; const taskManager = taskManagerMock.setup(); const alertTypeRegistryParams = { diff --git a/x-pack/legacy/plugins/alerting/server/alert_type_registry.ts b/x-pack/plugins/alerting/server/alert_type_registry.ts similarity index 95% rename from x-pack/legacy/plugins/alerting/server/alert_type_registry.ts rename to x-pack/plugins/alerting/server/alert_type_registry.ts index 8c9844d9351634..b0976d67c70a00 100644 --- a/x-pack/legacy/plugins/alerting/server/alert_type_registry.ts +++ b/x-pack/plugins/alerting/server/alert_type_registry.ts @@ -6,7 +6,7 @@ import Boom from 'boom'; import { i18n } from '@kbn/i18n'; -import { RunContext, TaskManagerSetupContract } from '../../../../plugins/task_manager/server'; +import { RunContext, TaskManagerSetupContract } from '../../../plugins/task_manager/server'; import { TaskRunnerFactory } from './task_runner'; import { AlertType } from './types'; diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client.mock.ts b/x-pack/plugins/alerting/server/alerts_client.mock.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/alerts_client.mock.ts rename to x-pack/plugins/alerting/server/alerts_client.mock.ts diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client.test.ts similarity index 99% rename from x-pack/legacy/plugins/alerting/server/alerts_client.test.ts rename to x-pack/plugins/alerting/server/alerts_client.test.ts index 1555a0537158a8..629bd05a8c76ae 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client.test.ts @@ -6,13 +6,13 @@ import uuid from 'uuid'; import { schema } from '@kbn/config-schema'; import { AlertsClient } from './alerts_client'; -import { savedObjectsClientMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; -import { taskManagerMock } from '../../../../plugins/task_manager/server/task_manager.mock'; +import { savedObjectsClientMock, loggingServiceMock } from '../../../../src/core/server/mocks'; +import { taskManagerMock } from '../../../plugins/task_manager/server/task_manager.mock'; import { alertTypeRegistryMock } from './alert_type_registry.mock'; -import { TaskStatus } from '../../../../plugins/task_manager/server'; +import { TaskStatus } from '../../../plugins/task_manager/server'; import { IntervalSchedule } from './types'; import { resolvable } from './test_utils'; -import { encryptedSavedObjectsMock } from '../../../../plugins/encrypted_saved_objects/server/mocks'; +import { encryptedSavedObjectsMock } from '../../../plugins/encrypted_saved_objects/server/mocks'; const taskManager = taskManagerMock.start(); const alertTypeRegistry = alertTypeRegistryMock.create(); diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client.ts similarity index 98% rename from x-pack/legacy/plugins/alerting/server/alerts_client.ts rename to x-pack/plugins/alerting/server/alerts_client.ts index eef6f662a20a2d..ad308f819da340 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client.ts @@ -29,9 +29,9 @@ import { InvalidateAPIKeyParams, CreateAPIKeyResult as SecurityPluginCreateAPIKeyResult, InvalidateAPIKeyResult as SecurityPluginInvalidateAPIKeyResult, -} from '../../../../plugins/security/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../../plugins/encrypted_saved_objects/server'; -import { TaskManagerStartContract } from '../../../../plugins/task_manager/server'; +} from '../../../plugins/security/server'; +import { EncryptedSavedObjectsPluginStart } from '../../../plugins/encrypted_saved_objects/server'; +import { TaskManagerStartContract } from '../../../plugins/task_manager/server'; import { taskInstanceToAlertTaskInstance } from './task_runner/alert_task_instance'; type NormalizedAlertAction = Omit; diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client_factory.test.ts b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts similarity index 72% rename from x-pack/legacy/plugins/alerting/server/alerts_client_factory.test.ts rename to x-pack/plugins/alerting/server/alerts_client_factory.test.ts index 14c685237bf92c..b0558ef1ea98c4 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client_factory.test.ts @@ -5,23 +5,23 @@ */ import { Request } from 'hapi'; -import { AlertsClientFactory, ConstructorOpts } from './alerts_client_factory'; +import { AlertsClientFactory, AlertsClientFactoryOpts } from './alerts_client_factory'; import { alertTypeRegistryMock } from './alert_type_registry.mock'; -import { taskManagerMock } from '../../../../plugins/task_manager/server/task_manager.mock'; -import { KibanaRequest } from '../../../../../src/core/server'; -import { loggingServiceMock } from '../../../../../src/core/server/mocks'; -import { encryptedSavedObjectsMock } from '../../../../plugins/encrypted_saved_objects/server/mocks'; +import { taskManagerMock } from '../../../plugins/task_manager/server/task_manager.mock'; +import { KibanaRequest } from '../../../../src/core/server'; +import { loggingServiceMock, savedObjectsClientMock } from '../../../../src/core/server/mocks'; +import { encryptedSavedObjectsMock } from '../../../plugins/encrypted_saved_objects/server/mocks'; jest.mock('./alerts_client'); -const savedObjectsClient = jest.fn(); +const savedObjectsClient = savedObjectsClientMock.create(); const securityPluginSetup = { authc: { createAPIKey: jest.fn(), getCurrentUser: jest.fn(), }, }; -const alertsClientFactoryParams: jest.Mocked = { +const alertsClientFactoryParams: jest.Mocked = { logger: loggingServiceMock.create().get(), taskManager: taskManagerMock.start(), alertTypeRegistry: alertTypeRegistryMock.create(), @@ -52,8 +52,9 @@ beforeEach(() => { }); test('creates an alerts client with proper constructor arguments', async () => { - const factory = new AlertsClientFactory(alertsClientFactoryParams); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + const factory = new AlertsClientFactory(); + factory.initialize(alertsClientFactoryParams); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); expect(jest.requireMock('./alerts_client').AlertsClient).toHaveBeenCalledWith({ savedObjectsClient, @@ -70,8 +71,9 @@ test('creates an alerts client with proper constructor arguments', async () => { }); test('getUserName() returns null when security is disabled', async () => { - const factory = new AlertsClientFactory(alertsClientFactoryParams); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + const factory = new AlertsClientFactory(); + factory.initialize(alertsClientFactoryParams); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); const constructorCall = jest.requireMock('./alerts_client').AlertsClient.mock.calls[0][0]; const userNameResult = await constructorCall.getUserName(); @@ -79,11 +81,12 @@ test('getUserName() returns null when security is disabled', async () => { }); test('getUserName() returns a name when security is enabled', async () => { - const factory = new AlertsClientFactory({ + const factory = new AlertsClientFactory(); + factory.initialize({ ...alertsClientFactoryParams, securityPluginSetup: securityPluginSetup as any, }); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); const constructorCall = jest.requireMock('./alerts_client').AlertsClient.mock.calls[0][0]; securityPluginSetup.authc.getCurrentUser.mockReturnValueOnce({ username: 'bob' }); @@ -92,8 +95,9 @@ test('getUserName() returns a name when security is enabled', async () => { }); test('createAPIKey() returns { apiKeysEnabled: false } when security is disabled', async () => { - const factory = new AlertsClientFactory(alertsClientFactoryParams); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + const factory = new AlertsClientFactory(); + factory.initialize(alertsClientFactoryParams); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); const constructorCall = jest.requireMock('./alerts_client').AlertsClient.mock.calls[0][0]; const createAPIKeyResult = await constructorCall.createAPIKey(); @@ -101,8 +105,9 @@ test('createAPIKey() returns { apiKeysEnabled: false } when security is disabled }); test('createAPIKey() returns { apiKeysEnabled: false } when security is enabled but ES security is disabled', async () => { - const factory = new AlertsClientFactory(alertsClientFactoryParams); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + const factory = new AlertsClientFactory(); + factory.initialize(alertsClientFactoryParams); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); const constructorCall = jest.requireMock('./alerts_client').AlertsClient.mock.calls[0][0]; securityPluginSetup.authc.createAPIKey.mockResolvedValueOnce(null); @@ -111,11 +116,12 @@ test('createAPIKey() returns { apiKeysEnabled: false } when security is enabled }); test('createAPIKey() returns an API key when security is enabled', async () => { - const factory = new AlertsClientFactory({ + const factory = new AlertsClientFactory(); + factory.initialize({ ...alertsClientFactoryParams, securityPluginSetup: securityPluginSetup as any, }); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); const constructorCall = jest.requireMock('./alerts_client').AlertsClient.mock.calls[0][0]; securityPluginSetup.authc.createAPIKey.mockResolvedValueOnce({ api_key: '123', id: 'abc' }); @@ -127,11 +133,12 @@ test('createAPIKey() returns an API key when security is enabled', async () => { }); test('createAPIKey() throws when security plugin createAPIKey throws an error', async () => { - const factory = new AlertsClientFactory({ + const factory = new AlertsClientFactory(); + factory.initialize({ ...alertsClientFactoryParams, securityPluginSetup: securityPluginSetup as any, }); - factory.create(KibanaRequest.from(fakeRequest), fakeRequest); + factory.create(KibanaRequest.from(fakeRequest), savedObjectsClient); const constructorCall = jest.requireMock('./alerts_client').AlertsClient.mock.calls[0][0]; securityPluginSetup.authc.createAPIKey.mockRejectedValueOnce(new Error('TLS disabled')); diff --git a/x-pack/legacy/plugins/alerting/server/alerts_client_factory.ts b/x-pack/plugins/alerting/server/alerts_client_factory.ts similarity index 66% rename from x-pack/legacy/plugins/alerting/server/alerts_client_factory.ts rename to x-pack/plugins/alerting/server/alerts_client_factory.ts index de789fba0ac388..c502c0e5bf1cf5 100644 --- a/x-pack/legacy/plugins/alerting/server/alerts_client_factory.ts +++ b/x-pack/plugins/alerting/server/alerts_client_factory.ts @@ -4,36 +4,39 @@ * you may not use this file except in compliance with the Elastic License. */ -import Hapi from 'hapi'; import uuid from 'uuid'; import { AlertsClient } from './alerts_client'; import { AlertTypeRegistry, SpaceIdToNamespaceFunction } from './types'; -import { SecurityPluginStartContract } from './shim'; -import { KibanaRequest, Logger } from '../../../../../src/core/server'; -import { InvalidateAPIKeyParams } from '../../../../plugins/security/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../../plugins/encrypted_saved_objects/server'; -import { TaskManagerStartContract } from '../../../../plugins/task_manager/server'; +import { KibanaRequest, Logger, SavedObjectsClientContract } from '../../../../src/core/server'; +import { InvalidateAPIKeyParams, SecurityPluginSetup } from '../../../plugins/security/server'; +import { EncryptedSavedObjectsPluginStart } from '../../../plugins/encrypted_saved_objects/server'; +import { TaskManagerStartContract } from '../../../plugins/task_manager/server'; -export interface ConstructorOpts { +export interface AlertsClientFactoryOpts { logger: Logger; taskManager: TaskManagerStartContract; alertTypeRegistry: AlertTypeRegistry; - securityPluginSetup?: SecurityPluginStartContract; - getSpaceId: (request: Hapi.Request) => string | undefined; + securityPluginSetup?: SecurityPluginSetup; + getSpaceId: (request: KibanaRequest) => string | undefined; spaceIdToNamespace: SpaceIdToNamespaceFunction; encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; } export class AlertsClientFactory { - private readonly logger: Logger; - private readonly taskManager: TaskManagerStartContract; - private readonly alertTypeRegistry: AlertTypeRegistry; - private readonly securityPluginSetup?: SecurityPluginStartContract; - private readonly getSpaceId: (request: Hapi.Request) => string | undefined; - private readonly spaceIdToNamespace: SpaceIdToNamespaceFunction; - private readonly encryptedSavedObjectsPlugin: EncryptedSavedObjectsPluginStart; + private isInitialized = false; + private logger!: Logger; + private taskManager!: TaskManagerStartContract; + private alertTypeRegistry!: AlertTypeRegistry; + private securityPluginSetup?: SecurityPluginSetup; + private getSpaceId!: (request: KibanaRequest) => string | undefined; + private spaceIdToNamespace!: SpaceIdToNamespaceFunction; + private encryptedSavedObjectsPlugin!: EncryptedSavedObjectsPluginStart; - constructor(options: ConstructorOpts) { + public initialize(options: AlertsClientFactoryOpts) { + if (this.isInitialized) { + throw new Error('AlertsClientFactory already initialized'); + } + this.isInitialized = true; this.logger = options.logger; this.getSpaceId = options.getSpaceId; this.taskManager = options.taskManager; @@ -43,15 +46,18 @@ export class AlertsClientFactory { this.encryptedSavedObjectsPlugin = options.encryptedSavedObjectsPlugin; } - public create(request: KibanaRequest, legacyRequest: Hapi.Request): AlertsClient { + public create( + request: KibanaRequest, + savedObjectsClient: SavedObjectsClientContract + ): AlertsClient { const { securityPluginSetup } = this; - const spaceId = this.getSpaceId(legacyRequest); + const spaceId = this.getSpaceId(request); return new AlertsClient({ spaceId, logger: this.logger, taskManager: this.taskManager, alertTypeRegistry: this.alertTypeRegistry, - savedObjectsClient: legacyRequest.getSavedObjectsClient(), + savedObjectsClient, namespace: this.spaceIdToNamespace(spaceId), encryptedSavedObjectsPlugin: this.encryptedSavedObjectsPlugin, async getUserName() { diff --git a/x-pack/legacy/plugins/alerting/server/constants/plugin.ts b/x-pack/plugins/alerting/server/constants/plugin.ts similarity index 85% rename from x-pack/legacy/plugins/alerting/server/constants/plugin.ts rename to x-pack/plugins/alerting/server/constants/plugin.ts index e3435b09829c61..173aa50013b407 100644 --- a/x-pack/legacy/plugins/alerting/server/constants/plugin.ts +++ b/x-pack/plugins/alerting/server/constants/plugin.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LICENSE_TYPE_BASIC, LicenseType } from '../../../../common/constants'; +import { LICENSE_TYPE_BASIC, LicenseType } from '../../../../legacy/common/constants'; export const PLUGIN = { ID: 'alerting', diff --git a/x-pack/plugins/alerting/server/index.ts b/x-pack/plugins/alerting/server/index.ts new file mode 100644 index 00000000000000..58b77f0f510f72 --- /dev/null +++ b/x-pack/plugins/alerting/server/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AlertsClient as AlertsClientClass } from './alerts_client'; +import { PluginInitializerContext } from '../../../../src/core/server'; +import { AlertingPlugin } from './plugin'; + +export type AlertsClient = PublicMethodsOf; + +export { + AlertType, + AlertingPlugin, + AlertExecutorOptions, + AlertActionParams, + AlertServices, + State, + PartialAlert, +} from './types'; +export { PluginSetupContract, PluginStartContract } from './plugin'; +export { FindOptions, FindResult } from './alerts_client'; +export { AlertInstance } from './alert_instance'; +export { parseDuration } from './lib'; + +export const plugin = (initContext: PluginInitializerContext) => new AlertingPlugin(initContext); diff --git a/x-pack/legacy/plugins/alerting/server/lib/index.ts b/x-pack/plugins/alerting/server/lib/index.ts similarity index 83% rename from x-pack/legacy/plugins/alerting/server/lib/index.ts rename to x-pack/plugins/alerting/server/lib/index.ts index c41ea4a5998ff4..c84825cadbd16f 100644 --- a/x-pack/legacy/plugins/alerting/server/lib/index.ts +++ b/x-pack/plugins/alerting/server/lib/index.ts @@ -4,6 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { parseDuration, getDurationSchema } from './parse_duration'; +export { parseDuration, validateDurationSchema } from './parse_duration'; export { LicenseState } from './license_state'; export { validateAlertTypeParams } from './validate_alert_type_params'; diff --git a/x-pack/plugins/alerting/server/lib/license_api_access.ts b/x-pack/plugins/alerting/server/lib/license_api_access.ts new file mode 100644 index 00000000000000..2e650ebf5eb170 --- /dev/null +++ b/x-pack/plugins/alerting/server/lib/license_api_access.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import Boom from 'boom'; +import { LicenseState } from './license_state'; + +export function verifyApiAccess(licenseState: LicenseState) { + const licenseCheckResults = licenseState.getLicenseInformation(); + + if (licenseCheckResults.showAppLink && licenseCheckResults.enableAppLink) { + return null; + } + + throw Boom.forbidden(licenseCheckResults.message); +} diff --git a/x-pack/plugins/alerting/server/lib/license_state.mock.ts b/x-pack/plugins/alerting/server/lib/license_state.mock.ts new file mode 100644 index 00000000000000..f36f3a9eaeadee --- /dev/null +++ b/x-pack/plugins/alerting/server/lib/license_state.mock.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { of } from 'rxjs'; +import { LicenseState } from './license_state'; +import { LICENSE_CHECK_STATE, ILicense } from '../../../licensing/server'; + +export const mockLicenseState = () => { + const license: ILicense = { + uid: '123', + status: 'active', + isActive: true, + signature: 'sig', + isAvailable: true, + toJSON: () => ({ + signature: 'sig', + }), + getUnavailableReason: () => undefined, + hasAtLeast() { + return true; + }, + check() { + return { + state: LICENSE_CHECK_STATE.Valid, + }; + }, + getFeature() { + return { + isAvailable: true, + isEnabled: true, + }; + }, + }; + return new LicenseState(of(license)); +}; diff --git a/x-pack/legacy/plugins/alerting/server/lib/license_state.test.ts b/x-pack/plugins/alerting/server/lib/license_state.test.ts similarity index 91% rename from x-pack/legacy/plugins/alerting/server/lib/license_state.test.ts rename to x-pack/plugins/alerting/server/lib/license_state.test.ts index 484dc49532567d..8feb8d74976fde 100644 --- a/x-pack/legacy/plugins/alerting/server/lib/license_state.test.ts +++ b/x-pack/plugins/alerting/server/lib/license_state.test.ts @@ -6,8 +6,8 @@ import expect from '@kbn/expect'; import { LicenseState } from './license_state'; -import { licensingMock } from '../../../../../plugins/licensing/server/mocks'; -import { LICENSE_CHECK_STATE } from '../../../../../plugins/licensing/server'; +import { licensingMock } from '../../../../plugins/licensing/server/mocks'; +import { LICENSE_CHECK_STATE } from '../../../../plugins/licensing/server'; describe('license_state', () => { let getRawLicense: any; diff --git a/x-pack/legacy/plugins/alerting/server/lib/license_state.ts b/x-pack/plugins/alerting/server/lib/license_state.ts similarity index 94% rename from x-pack/legacy/plugins/alerting/server/lib/license_state.ts rename to x-pack/plugins/alerting/server/lib/license_state.ts index 344bc9c409edf3..690eaed9e2b89d 100644 --- a/x-pack/legacy/plugins/alerting/server/lib/license_state.ts +++ b/x-pack/plugins/alerting/server/lib/license_state.ts @@ -7,8 +7,8 @@ import Boom from 'boom'; import { i18n } from '@kbn/i18n'; import { Observable, Subscription } from 'rxjs'; -import { ILicense, LICENSE_CHECK_STATE } from '../../../../../plugins/licensing/common/types'; -import { assertNever } from '../../../../../../src/core/utils'; +import { ILicense, LICENSE_CHECK_STATE } from '../../../../plugins/licensing/common/types'; +import { assertNever } from '../../../../../src/core/utils'; import { PLUGIN } from '../constants/plugin'; export interface AlertingLicenseInformation { diff --git a/x-pack/legacy/plugins/alerting/server/lib/parse_duration.test.ts b/x-pack/plugins/alerting/server/lib/parse_duration.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/lib/parse_duration.test.ts rename to x-pack/plugins/alerting/server/lib/parse_duration.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/lib/parse_duration.ts b/x-pack/plugins/alerting/server/lib/parse_duration.ts similarity index 75% rename from x-pack/legacy/plugins/alerting/server/lib/parse_duration.ts rename to x-pack/plugins/alerting/server/lib/parse_duration.ts index e343ef6d216847..51f3d746a68693 100644 --- a/x-pack/legacy/plugins/alerting/server/lib/parse_duration.ts +++ b/x-pack/plugins/alerting/server/lib/parse_duration.ts @@ -3,9 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - -import Joi from 'joi'; - const SECONDS_REGEX = /^[1-9][0-9]*s$/; const MINUTES_REGEX = /^[1-9][0-9]*m$/; const HOURS_REGEX = /^[1-9][0-9]*h$/; @@ -27,21 +24,20 @@ export function parseDuration(duration: string): number { ); } -export function getDurationSchema() { - return Joi.alternatives().try( - Joi.string() - .regex(SECONDS_REGEX, 'seconds') - .required(), - Joi.string() - .regex(MINUTES_REGEX, 'minutes') - .required(), - Joi.string() - .regex(HOURS_REGEX, 'hours') - .required(), - Joi.string() - .regex(DAYS_REGEX, 'days') - .required() - ); +export function validateDurationSchema(duration: string) { + if (duration.match(SECONDS_REGEX)) { + return; + } + if (duration.match(MINUTES_REGEX)) { + return; + } + if (duration.match(HOURS_REGEX)) { + return; + } + if (duration.match(DAYS_REGEX)) { + return; + } + return 'string is not a valid duration: ' + duration; } function isSeconds(duration: string) { diff --git a/x-pack/legacy/plugins/alerting/server/lib/result_type.ts b/x-pack/plugins/alerting/server/lib/result_type.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/lib/result_type.ts rename to x-pack/plugins/alerting/server/lib/result_type.ts diff --git a/x-pack/legacy/plugins/alerting/server/lib/types.test.ts b/x-pack/plugins/alerting/server/lib/types.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/lib/types.test.ts rename to x-pack/plugins/alerting/server/lib/types.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/lib/types.ts b/x-pack/plugins/alerting/server/lib/types.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/lib/types.ts rename to x-pack/plugins/alerting/server/lib/types.ts diff --git a/x-pack/legacy/plugins/alerting/server/lib/validate_alert_type_params.test.ts b/x-pack/plugins/alerting/server/lib/validate_alert_type_params.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/lib/validate_alert_type_params.test.ts rename to x-pack/plugins/alerting/server/lib/validate_alert_type_params.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/lib/validate_alert_type_params.ts b/x-pack/plugins/alerting/server/lib/validate_alert_type_params.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/lib/validate_alert_type_params.ts rename to x-pack/plugins/alerting/server/lib/validate_alert_type_params.ts diff --git a/x-pack/plugins/alerting/server/mocks.ts b/x-pack/plugins/alerting/server/mocks.ts new file mode 100644 index 00000000000000..55ad722dcf8814 --- /dev/null +++ b/x-pack/plugins/alerting/server/mocks.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { alertsClientMock } from './alerts_client.mock'; +import { PluginSetupContract, PluginStartContract } from './plugin'; + +export { alertsClientMock }; + +const createSetupMock = () => { + const mock: jest.Mocked = { + registerType: jest.fn(), + }; + return mock; +}; + +const createStartMock = () => { + const mock: jest.Mocked = { + listTypes: jest.fn(), + getAlertsClientWithRequest: jest.fn().mockResolvedValue(alertsClientMock.create()), + }; + return mock; +}; + +export const alertsMock = { + createSetup: createSetupMock, + createStart: createStartMock, +}; diff --git a/x-pack/legacy/plugins/alerting/server/plugin.test.ts b/x-pack/plugins/alerting/server/plugin.test.ts similarity index 91% rename from x-pack/legacy/plugins/alerting/server/plugin.test.ts rename to x-pack/plugins/alerting/server/plugin.test.ts index 872de720243b26..40e620dd92af04 100644 --- a/x-pack/legacy/plugins/alerting/server/plugin.test.ts +++ b/x-pack/plugins/alerting/server/plugin.test.ts @@ -4,16 +4,16 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Plugin } from './plugin'; -import { coreMock } from '../../../../../src/core/server/mocks'; -import { licensingMock } from '../../../../plugins/licensing/server/mocks'; -import { encryptedSavedObjectsMock } from '../../../../plugins/encrypted_saved_objects/server/mocks'; +import { AlertingPlugin } from './plugin'; +import { coreMock } from '../../../../src/core/server/mocks'; +import { licensingMock } from '../../../plugins/licensing/server/mocks'; +import { encryptedSavedObjectsMock } from '../../../plugins/encrypted_saved_objects/server/mocks'; describe('Alerting Plugin', () => { describe('setup()', () => { it('should log warning when Encrypted Saved Objects plugin is using an ephemeral encryption key', async () => { const context = coreMock.createPluginInitializerContext(); - const plugin = new Plugin(context); + const plugin = new AlertingPlugin(context); const coreSetup = coreMock.createSetup(); const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup(); @@ -49,7 +49,7 @@ describe('Alerting Plugin', () => { describe('getAlertsClientWithRequest()', () => { it('throws error when encryptedSavedObjects plugin has usingEphemeralEncryptionKey set to true', async () => { const context = coreMock.createPluginInitializerContext(); - const plugin = new Plugin(context); + const plugin = new AlertingPlugin(context); const coreSetup = coreMock.createSetup(); const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup(); @@ -87,7 +87,7 @@ describe('Alerting Plugin', () => { it(`doesn't throw error when encryptedSavedObjects plugin has usingEphemeralEncryptionKey set to false`, async () => { const context = coreMock.createPluginInitializerContext(); - const plugin = new Plugin(context); + const plugin = new AlertingPlugin(context); const coreSetup = coreMock.createSetup(); const encryptedSavedObjectsSetup = { diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts new file mode 100644 index 00000000000000..bed163878b5ac9 --- /dev/null +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -0,0 +1,236 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SecurityPluginSetup } from '../../security/server'; +import { + EncryptedSavedObjectsPluginSetup, + EncryptedSavedObjectsPluginStart, +} from '../../encrypted_saved_objects/server'; +import { TaskManagerSetupContract, TaskManagerStartContract } from '../../task_manager/server'; +import { SpacesPluginSetup, SpacesServiceSetup } from '../../spaces/server'; +import { AlertsClient } from './alerts_client'; +import { AlertTypeRegistry } from './alert_type_registry'; +import { TaskRunnerFactory } from './task_runner'; +import { AlertsClientFactory } from './alerts_client_factory'; +import { LicenseState } from './lib/license_state'; +import { + IClusterClient, + KibanaRequest, + Logger, + PluginInitializerContext, + CoreSetup, + CoreStart, + SavedObjectsServiceStart, + IContextProvider, + RequestHandler, +} from '../../../../src/core/server'; + +import { + createAlertRoute, + deleteAlertRoute, + findAlertRoute, + getAlertRoute, + getAlertStateRoute, + listAlertTypesRoute, + updateAlertRoute, + enableAlertRoute, + disableAlertRoute, + updateApiKeyRoute, + muteAllAlertRoute, + unmuteAllAlertRoute, + muteAlertInstanceRoute, + unmuteAlertInstanceRoute, +} from './routes'; +import { LicensingPluginSetup } from '../../licensing/server'; +import { + PluginSetupContract as ActionsPluginSetupContract, + PluginStartContract as ActionsPluginStartContract, +} from '../../../plugins/actions/server'; +import { Services } from './types'; + +export interface PluginSetupContract { + registerType: AlertTypeRegistry['register']; +} +export interface PluginStartContract { + listTypes: AlertTypeRegistry['list']; + getAlertsClientWithRequest(request: KibanaRequest): PublicMethodsOf; +} + +export interface AlertingPluginsSetup { + security?: SecurityPluginSetup; + taskManager: TaskManagerSetupContract; + actions: ActionsPluginSetupContract; + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; + licensing: LicensingPluginSetup; + spaces?: SpacesPluginSetup; +} +export interface AlertingPluginsStart { + actions: ActionsPluginStartContract; + encryptedSavedObjects: EncryptedSavedObjectsPluginStart; + taskManager: TaskManagerStartContract; +} + +export class AlertingPlugin { + private readonly logger: Logger; + private alertTypeRegistry?: AlertTypeRegistry; + private readonly taskRunnerFactory: TaskRunnerFactory; + private adminClient?: IClusterClient; + private serverBasePath?: string; + private licenseState: LicenseState | null = null; + private isESOUsingEphemeralEncryptionKey?: boolean; + private spaces?: SpacesServiceSetup; + private security?: SecurityPluginSetup; + private readonly alertsClientFactory: AlertsClientFactory; + + constructor(initializerContext: PluginInitializerContext) { + this.logger = initializerContext.logger.get('plugins', 'alerting'); + this.taskRunnerFactory = new TaskRunnerFactory(); + this.alertsClientFactory = new AlertsClientFactory(); + } + + public async setup(core: CoreSetup, plugins: AlertingPluginsSetup): Promise { + this.adminClient = core.elasticsearch.adminClient; + this.licenseState = new LicenseState(plugins.licensing.license$); + this.spaces = plugins.spaces?.spacesService; + this.security = plugins.security; + this.isESOUsingEphemeralEncryptionKey = + plugins.encryptedSavedObjects.usingEphemeralEncryptionKey; + + if (this.isESOUsingEphemeralEncryptionKey) { + this.logger.warn( + 'APIs are disabled due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml.' + ); + } + + // Encrypted attributes + plugins.encryptedSavedObjects.registerType({ + type: 'alert', + attributesToEncrypt: new Set(['apiKey']), + attributesToExcludeFromAAD: new Set([ + 'scheduledTaskId', + 'muteAll', + 'mutedInstanceIds', + 'updatedBy', + ]), + }); + + const alertTypeRegistry = new AlertTypeRegistry({ + taskManager: plugins.taskManager, + taskRunnerFactory: this.taskRunnerFactory, + }); + this.alertTypeRegistry = alertTypeRegistry; + this.serverBasePath = core.http.basePath.serverBasePath; + + core.http.registerRouteHandlerContext('alerting', this.createRouteHandlerContext()); + + // Routes + const router = core.http.createRouter(); + // Register routes + createAlertRoute(router, this.licenseState); + deleteAlertRoute(router, this.licenseState); + findAlertRoute(router, this.licenseState); + getAlertRoute(router, this.licenseState); + getAlertStateRoute(router, this.licenseState); + listAlertTypesRoute(router, this.licenseState); + updateAlertRoute(router, this.licenseState); + enableAlertRoute(router, this.licenseState); + disableAlertRoute(router, this.licenseState); + updateApiKeyRoute(router, this.licenseState); + muteAllAlertRoute(router, this.licenseState); + unmuteAllAlertRoute(router, this.licenseState); + muteAlertInstanceRoute(router, this.licenseState); + unmuteAlertInstanceRoute(router, this.licenseState); + + return { + registerType: alertTypeRegistry.register.bind(alertTypeRegistry), + }; + } + + public start(core: CoreStart, plugins: AlertingPluginsStart): PluginStartContract { + const { + spaces, + isESOUsingEphemeralEncryptionKey, + logger, + taskRunnerFactory, + alertTypeRegistry, + alertsClientFactory, + security, + } = this; + + alertsClientFactory.initialize({ + alertTypeRegistry: alertTypeRegistry!, + logger, + taskManager: plugins.taskManager, + securityPluginSetup: security, + encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, + spaceIdToNamespace: this.spaceIdToNamespace, + getSpaceId(request: KibanaRequest) { + return spaces?.getSpaceId(request); + }, + }); + + taskRunnerFactory.initialize({ + logger, + getServices: this.getServicesFactory(core.savedObjects), + spaceIdToNamespace: this.spaceIdToNamespace, + executeAction: plugins.actions.execute, + encryptedSavedObjectsPlugin: plugins.encryptedSavedObjects, + getBasePath: this.getBasePath, + }); + + return { + listTypes: alertTypeRegistry!.list.bind(this.alertTypeRegistry!), + // Ability to get an alerts client from legacy code + getAlertsClientWithRequest(request: KibanaRequest) { + if (isESOUsingEphemeralEncryptionKey === true) { + throw new Error( + `Unable to create alerts client due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml` + ); + } + return alertsClientFactory!.create(request, core.savedObjects.getScopedClient(request)); + }, + }; + } + + private createRouteHandlerContext = (): IContextProvider< + RequestHandler, + 'alerting' + > => { + const { alertTypeRegistry, alertsClientFactory } = this; + return async function alertsRouteHandlerContext(context, request) { + return { + getAlertsClient: () => { + return alertsClientFactory!.create(request, context.core!.savedObjects.client); + }, + listTypes: alertTypeRegistry!.list.bind(alertTypeRegistry!), + }; + }; + }; + + private getServicesFactory( + savedObjects: SavedObjectsServiceStart + ): (request: KibanaRequest) => Services { + const { adminClient } = this; + return request => ({ + callCluster: adminClient!.asScoped(request).callAsCurrentUser, + savedObjectsClient: savedObjects.getScopedClient(request), + }); + } + + private spaceIdToNamespace = (spaceId?: string): string | undefined => { + return this.spaces && spaceId ? this.spaces.spaceIdToNamespace(spaceId) : undefined; + }; + + private getBasePath = (spaceId?: string): string => { + return this.spaces && spaceId ? this.spaces.getBasePath(spaceId) : this.serverBasePath!; + }; + + public stop() { + if (this.licenseState) { + this.licenseState.clean(); + } + } +} diff --git a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts new file mode 100644 index 00000000000000..9815ad5194af70 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { RequestHandlerContext, KibanaRequest, KibanaResponseFactory } from 'kibana/server'; +import { identity } from 'lodash'; +import { httpServerMock } from '../../../../../src/core/server/mocks'; +import { alertsClientMock } from '../alerts_client.mock'; + +export function mockHandlerArguments( + { alertsClient, listTypes: listTypesRes = [] }: any, + req: any, + res?: Array> +): [RequestHandlerContext, KibanaRequest, KibanaResponseFactory] { + const listTypes = jest.fn(() => listTypesRes); + return [ + ({ + alerting: { + listTypes, + getAlertsClient() { + return alertsClient || alertsClientMock.create(); + }, + }, + } as unknown) as RequestHandlerContext, + req as KibanaRequest, + mockResponseFactory(res), + ]; +} + +export const mockResponseFactory = (resToMock: Array> = []) => { + const factory: jest.Mocked = httpServerMock.createResponseFactory(); + resToMock.forEach((key: string) => { + if (key in factory) { + Object.defineProperty(factory, key, { + value: jest.fn(identity), + }); + } + }); + return (factory as unknown) as KibanaResponseFactory; +}; diff --git a/x-pack/plugins/alerting/server/routes/create.test.ts b/x-pack/plugins/alerting/server/routes/create.test.ts new file mode 100644 index 00000000000000..c6a0da2bd91916 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/create.test.ts @@ -0,0 +1,172 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { createAlertRoute } from './create'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); + +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('createAlertRoute', () => { + const createdAt = new Date(); + const updatedAt = new Date(); + + const mockedAlert = { + alertTypeId: '1', + consumer: 'bar', + name: 'abc', + schedule: { interval: '10s' }, + tags: ['foo'], + params: { + bar: true, + }, + throttle: '30s', + actions: [ + { + group: 'default', + id: '2', + params: { + foo: true, + }, + }, + ], + }; + + const createResult = { + ...mockedAlert, + enabled: true, + muteAll: false, + createdBy: '', + updatedBy: '', + apiKey: '', + apiKeyOwner: '', + mutedInstanceIds: [], + createdAt, + updatedAt, + id: '123', + actions: [ + { + ...mockedAlert.actions[0], + actionTypeId: 'test', + }, + ], + }; + + it('creates an alert with proper parameters', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + createAlertRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.create.mockResolvedValueOnce(createResult); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + body: mockedAlert, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toEqual({ body: createResult }); + + expect(alertsClient.create).toHaveBeenCalledTimes(1); + expect(alertsClient.create.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "data": Object { + "actions": Array [ + Object { + "group": "default", + "id": "2", + "params": Object { + "foo": true, + }, + }, + ], + "alertTypeId": "1", + "consumer": "bar", + "name": "abc", + "params": Object { + "bar": true, + }, + "schedule": Object { + "interval": "10s", + }, + "tags": Array [ + "foo", + ], + "throttle": "30s", + }, + }, + ] + `); + + expect(res.ok).toHaveBeenCalledWith({ + body: createResult, + }); + }); + + it('ensures the license allows creating alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + createAlertRoute(router, licenseState); + + const [, handler] = router.post.mock.calls[0]; + + alertsClient.create.mockResolvedValueOnce(createResult); + + const [context, req, res] = mockHandlerArguments(alertsClient, {}); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents creating alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + createAlertRoute(router, licenseState); + + const [, handler] = router.post.mock.calls[0]; + + alertsClient.create.mockResolvedValueOnce(createResult); + + const [context, req, res] = mockHandlerArguments(alertsClient, {}); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/create.ts b/x-pack/plugins/alerting/server/routes/create.ts new file mode 100644 index 00000000000000..8d854e0df84670 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/create.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { validateDurationSchema } from '../lib'; +import { Alert } from '../types'; + +export const bodySchema = schema.object({ + name: schema.string(), + alertTypeId: schema.string(), + enabled: schema.boolean({ defaultValue: true }), + consumer: schema.string(), + tags: schema.arrayOf(schema.string(), { defaultValue: [] }), + throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + schedule: schema.object({ + interval: schema.string({ validate: validateDurationSchema }), + }), + actions: schema.arrayOf( + schema.object({ + group: schema.string(), + id: schema.string(), + actionTypeId: schema.maybe(schema.string()), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + }), + { defaultValue: [] } + ), +}); + +export const createAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert', + validate: { + body: bodySchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + + const alertsClient = context.alerting.getAlertsClient(); + const alert = req.body; + const alertRes: Alert = await alertsClient.create({ data: alert }); + return res.ok({ + body: alertRes, + }); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/delete.test.ts b/x-pack/plugins/alerting/server/routes/delete.test.ts new file mode 100644 index 00000000000000..36bb485817c156 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/delete.test.ts @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { deleteAlertRoute } from './delete'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); + +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('deleteAlertRoute', () => { + it('deletes an alert with proper parameters', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + deleteAlertRoute(router, licenseState); + + const [config, handler] = router.delete.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.delete.mockResolvedValueOnce({}); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.delete).toHaveBeenCalledTimes(1); + expect(alertsClient.delete.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); + + it('ensures the license allows deleting alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + deleteAlertRoute(router, licenseState); + + const [, handler] = router.delete.mock.calls[0]; + + alertsClient.delete.mockResolvedValueOnce({}); + + const [context, req, res] = mockHandlerArguments(alertsClient, { + params: { id: '1' }, + }); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents deleting alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + deleteAlertRoute(router, licenseState); + + const [, handler] = router.delete.mock.calls[0]; + + alertsClient.delete.mockResolvedValueOnce({}); + + const [context, req, res] = mockHandlerArguments(alertsClient, { + id: '1', + }); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/delete.ts b/x-pack/plugins/alerting/server/routes/delete.ts new file mode 100644 index 00000000000000..0556ef3d66982c --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/delete.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const deleteAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.delete( + { + path: '/api/alert/{id}', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + await alertsClient.delete({ id }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/disable.test.ts b/x-pack/plugins/alerting/server/routes/disable.test.ts new file mode 100644 index 00000000000000..622b562ec69116 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/disable.test.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { disableAlertRoute } from './disable'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); + +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('disableAlertRoute', () => { + it('disables an alert', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + disableAlertRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/_disable"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.disable.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.disable).toHaveBeenCalledTimes(1); + expect(alertsClient.disable.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/disable.ts b/x-pack/plugins/alerting/server/routes/disable.ts new file mode 100644 index 00000000000000..5c6d977e62c388 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/disable.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const disableAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{id}/_disable', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + await alertsClient.disable({ id }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/enable.test.ts b/x-pack/plugins/alerting/server/routes/enable.test.ts new file mode 100644 index 00000000000000..5a7b027e8ef546 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/enable.test.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { enableAlertRoute } from './enable'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); + +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('enableAlertRoute', () => { + it('enables an alert', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + enableAlertRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/_enable"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.enable.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.enable).toHaveBeenCalledTimes(1); + expect(alertsClient.enable.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/enable.ts b/x-pack/plugins/alerting/server/routes/enable.ts new file mode 100644 index 00000000000000..f75344ad85998a --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/enable.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const enableAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{id}/_enable', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + await alertsClient.enable({ id }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/find.test.ts b/x-pack/plugins/alerting/server/routes/find.test.ts new file mode 100644 index 00000000000000..ba0114c99a9bdd --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/find.test.ts @@ -0,0 +1,150 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { findAlertRoute } from './find'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); + +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('findAlertRoute', () => { + it('finds alerts with proper parameters', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + findAlertRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/_find"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + const findResult = { + page: 1, + perPage: 1, + total: 0, + data: [], + }; + alertsClient.find.mockResolvedValueOnce(findResult); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + query: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Object { + "data": Array [], + "page": 1, + "perPage": 1, + "total": 0, + }, + } + `); + + expect(alertsClient.find).toHaveBeenCalledTimes(1); + expect(alertsClient.find.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "options": Object { + "defaultSearchOperator": "OR", + "fields": undefined, + "filter": undefined, + "page": 1, + "perPage": 1, + "search": undefined, + "sortField": undefined, + }, + }, + ] + `); + + expect(res.ok).toHaveBeenCalledWith({ + body: findResult, + }); + }); + + it('ensures the license allows finding alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + findAlertRoute(router, licenseState); + + const [, handler] = router.get.mock.calls[0]; + + alertsClient.find.mockResolvedValueOnce({ + page: 1, + perPage: 1, + total: 0, + data: [], + }); + + const [context, req, res] = mockHandlerArguments(alertsClient, { + query: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + }, + }); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents finding alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + findAlertRoute(router, licenseState); + + const [, handler] = router.get.mock.calls[0]; + + const [context, req, res] = mockHandlerArguments( + {}, + { + query: { + per_page: 1, + page: 1, + default_search_operator: 'OR', + }, + }, + ['ok'] + ); + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/find.ts b/x-pack/plugins/alerting/server/routes/find.ts new file mode 100644 index 00000000000000..16f53aa218895f --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/find.ts @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { FindOptions } from '../../../alerting/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +// config definition +const querySchema = schema.object({ + per_page: schema.number({ defaultValue: 10, min: 0 }), + page: schema.number({ defaultValue: 1, min: 1 }), + search: schema.maybe(schema.string()), + default_search_operator: schema.oneOf([schema.literal('OR'), schema.literal('AND')], { + defaultValue: 'OR', + }), + search_fields: schema.maybe(schema.oneOf([schema.arrayOf(schema.string()), schema.string()])), + sort_field: schema.maybe(schema.string()), + has_reference: schema.maybe( + // use nullable as maybe is currently broken + // in config-schema + schema.nullable( + schema.object({ + type: schema.string(), + id: schema.string(), + }) + ) + ), + fields: schema.maybe(schema.arrayOf(schema.string())), + filter: schema.maybe(schema.string()), +}); + +export const findAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.get( + { + path: '/api/alert/_find', + validate: { + query: querySchema, + }, + options: { + tags: ['access:alerting-read'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const query = req.query; + const options: FindOptions['options'] = { + perPage: query.per_page, + page: query.page, + search: query.search, + defaultSearchOperator: query.default_search_operator, + sortField: query.sort_field, + fields: query.fields, + filter: query.filter, + }; + + if (query.search_fields) { + options.searchFields = Array.isArray(query.search_fields) + ? query.search_fields + : [query.search_fields]; + } + + if (query.has_reference) { + options.hasReference = query.has_reference; + } + + const findResult = await alertsClient.find({ + options, + }); + return res.ok({ + body: findResult, + }); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/get.test.ts b/x-pack/plugins/alerting/server/routes/get.test.ts new file mode 100644 index 00000000000000..4506700c6d9cc1 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get.test.ts @@ -0,0 +1,140 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getAlertRoute } from './get'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('getAlertRoute', () => { + const mockedAlert = { + id: '1', + alertTypeId: '1', + schedule: { interval: '10s' }, + params: { + bar: true, + }, + createdAt: new Date(), + updatedAt: new Date(), + actions: [ + { + group: 'default', + id: '2', + actionTypeId: 'test', + params: { + foo: true, + }, + }, + ], + consumer: 'bar', + name: 'abc', + tags: ['foo'], + enabled: true, + muteAll: false, + createdBy: '', + updatedBy: '', + apiKey: '', + apiKeyOwner: '', + throttle: '30s', + mutedInstanceIds: [], + }; + + it('gets an alert with proper parameters', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + getAlertRoute(router, licenseState); + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + alertsClient.get.mockResolvedValueOnce(mockedAlert); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { id: '1' }, + }, + ['ok'] + ); + await handler(context, req, res); + + expect(alertsClient.get).toHaveBeenCalledTimes(1); + expect(alertsClient.get.mock.calls[0][0].id).toEqual('1'); + + expect(res.ok).toHaveBeenCalledWith({ + body: mockedAlert, + }); + }); + + it('ensures the license allows getting alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + getAlertRoute(router, licenseState); + + const [, handler] = router.get.mock.calls[0]; + + alertsClient.get.mockResolvedValueOnce(mockedAlert); + + const [context, req, res] = mockHandlerArguments( + alertsClient, + { + params: { id: '1' }, + }, + ['ok'] + ); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents getting alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + getAlertRoute(router, licenseState); + + const [, handler] = router.get.mock.calls[0]; + + alertsClient.get.mockResolvedValueOnce(mockedAlert); + + const [context, req, res] = mockHandlerArguments( + alertsClient, + { + params: { id: '1' }, + }, + ['ok'] + ); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/get.ts b/x-pack/plugins/alerting/server/routes/get.ts new file mode 100644 index 00000000000000..407d80b0f87abf --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const getAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.get( + { + path: `/api/alert/{id}`, + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-read'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + return res.ok({ + body: await alertsClient.get({ id }), + }); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/get_alert_state.test.ts b/x-pack/plugins/alerting/server/routes/get_alert_state.test.ts new file mode 100644 index 00000000000000..eb51c96b88e5ea --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get_alert_state.test.ts @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getAlertStateRoute } from './get_alert_state'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { SavedObjectsErrorHelpers } from 'src/core/server/saved_objects'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('getAlertStateRoute', () => { + const mockedAlertState = { + alertTypeState: { + some: 'value', + }, + alertInstances: { + first_instance: { + state: {}, + meta: { + lastScheduledActions: { + group: 'first_group', + date: new Date(), + }, + }, + }, + second_instance: {}, + }, + }; + + it('gets alert state', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + getAlertStateRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/state"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + alertsClient.getAlertState.mockResolvedValueOnce(mockedAlertState); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['ok'] + ); + + await handler(context, req, res); + + expect(alertsClient.getAlertState).toHaveBeenCalledTimes(1); + expect(alertsClient.getAlertState.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.ok).toHaveBeenCalled(); + }); + + it('returns NO-CONTENT when alert exists but has no task state yet', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + getAlertStateRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/state"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + alertsClient.getAlertState.mockResolvedValueOnce(undefined); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.getAlertState).toHaveBeenCalledTimes(1); + expect(alertsClient.getAlertState.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); + + it('returns NOT-FOUND when alert is not found', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + getAlertStateRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/state"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + alertsClient.getAlertState = jest + .fn() + .mockResolvedValueOnce(SavedObjectsErrorHelpers.createGenericNotFoundError('alert', '1')); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['notFound'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.getAlertState).toHaveBeenCalledTimes(1); + expect(alertsClient.getAlertState.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/get_alert_state.ts b/x-pack/plugins/alerting/server/routes/get_alert_state.ts new file mode 100644 index 00000000000000..b419889eea4225 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/get_alert_state.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const getAlertStateRoute = (router: IRouter, licenseState: LicenseState) => { + router.get( + { + path: '/api/alert/{id}/state', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-read'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + const state = await alertsClient.getAlertState({ id }); + return state ? res.ok({ body: state }) : res.noContent(); + }) + ); +}; diff --git a/x-pack/legacy/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/routes/index.ts rename to x-pack/plugins/alerting/server/routes/index.ts diff --git a/x-pack/plugins/alerting/server/routes/list_alert_types.test.ts b/x-pack/plugins/alerting/server/routes/list_alert_types.test.ts new file mode 100644 index 00000000000000..3e9f57d55122d7 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/list_alert_types.test.ts @@ -0,0 +1,147 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { listAlertTypesRoute } from './list_alert_types'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { mockHandlerArguments } from './_mock_handler_arguments'; + +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('listAlertTypesRoute', () => { + it('lists alert types with proper parameters', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + listAlertTypesRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/types"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + const listTypes = [ + { + id: '1', + name: 'name', + actionGroups: [], + }, + ]; + + const [context, req, res] = mockHandlerArguments({ listTypes }, {}, ['ok']); + + expect(await handler(context, req, res)).toMatchInlineSnapshot(` + Object { + "body": Array [ + Object { + "actionGroups": Array [], + "id": "1", + "name": "name", + }, + ], + } + `); + + expect(context.alerting.listTypes).toHaveBeenCalledTimes(1); + + expect(res.ok).toHaveBeenCalledWith({ + body: listTypes, + }); + }); + + it('ensures the license allows listing alert types', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + listAlertTypesRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/types"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + const listTypes = [ + { + id: '1', + name: 'name', + enabled: true, + }, + ]; + + const [context, req, res] = mockHandlerArguments( + { listTypes }, + { + params: { id: '1' }, + }, + ['ok'] + ); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents listing alert types', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + listAlertTypesRoute(router, licenseState); + + const [config, handler] = router.get.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/types"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-read", + ], + } + `); + + const listTypes = [ + { + id: '1', + name: 'name', + actionGroups: [], + }, + ]; + + const [context, req, res] = mockHandlerArguments( + { listTypes }, + { + params: { id: '1' }, + }, + ['ok'] + ); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/list_alert_types.ts b/x-pack/plugins/alerting/server/routes/list_alert_types.ts new file mode 100644 index 00000000000000..e33bb9a010bf7e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/list_alert_types.ts @@ -0,0 +1,37 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +export const listAlertTypesRoute = (router: IRouter, licenseState: LicenseState) => { + router.get( + { + path: `/api/alert/types`, + validate: {}, + options: { + tags: ['access:alerting-read'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + return res.ok({ + body: context.alerting.listTypes(), + }); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/mute_all.test.ts b/x-pack/plugins/alerting/server/routes/mute_all.test.ts new file mode 100644 index 00000000000000..4c880e176d2df6 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/mute_all.test.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { muteAllAlertRoute } from './mute_all'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('muteAllAlertRoute', () => { + it('mute an alert', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + muteAllAlertRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/_mute_all"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.muteAll.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.muteAll).toHaveBeenCalledTimes(1); + expect(alertsClient.muteAll.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/mute_all.ts b/x-pack/plugins/alerting/server/routes/mute_all.ts new file mode 100644 index 00000000000000..796efd457f4784 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/mute_all.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const muteAllAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{id}/_mute_all', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + await alertsClient.muteAll({ id }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/mute_instance.test.ts b/x-pack/plugins/alerting/server/routes/mute_instance.test.ts new file mode 100644 index 00000000000000..939864972c35df --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/mute_instance.test.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { muteAlertInstanceRoute } from './mute_instance'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('muteAlertInstanceRoute', () => { + it('mutes an alert instance', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + muteAlertInstanceRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot( + `"/api/alert/{alertId}/alert_instance/{alertInstanceId}/_mute"` + ); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.muteInstance.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + alertId: '1', + alertInstanceId: '2', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.muteInstance).toHaveBeenCalledTimes(1); + expect(alertsClient.muteInstance.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "alertId": "1", + "alertInstanceId": "2", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/mute_instance.ts b/x-pack/plugins/alerting/server/routes/mute_instance.ts new file mode 100644 index 00000000000000..bae7b00548a26b --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/mute_instance.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + alertId: schema.string(), + alertInstanceId: schema.string(), +}); + +export const muteAlertInstanceRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{alertId}/alert_instance/{alertInstanceId}/_mute', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { alertId, alertInstanceId } = req.params; + await alertsClient.muteInstance({ alertId, alertInstanceId }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/unmute_all.test.ts b/x-pack/plugins/alerting/server/routes/unmute_all.test.ts new file mode 100644 index 00000000000000..cd14e9b2e71726 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/unmute_all.test.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { unmuteAllAlertRoute } from './unmute_all'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('unmuteAllAlertRoute', () => { + it('unmutes an alert', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + unmuteAllAlertRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/_unmute_all"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.unmuteAll.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.unmuteAll).toHaveBeenCalledTimes(1); + expect(alertsClient.unmuteAll.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/unmute_all.ts b/x-pack/plugins/alerting/server/routes/unmute_all.ts new file mode 100644 index 00000000000000..5483f691b5462b --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/unmute_all.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const unmuteAllAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{id}/_unmute_all', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + await alertsClient.unmuteAll({ id }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/unmute_instance.test.ts b/x-pack/plugins/alerting/server/routes/unmute_instance.test.ts new file mode 100644 index 00000000000000..d74934f6917103 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/unmute_instance.test.ts @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { unmuteAlertInstanceRoute } from './unmute_instance'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('unmuteAlertInstanceRoute', () => { + it('unmutes an alert instance', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + unmuteAlertInstanceRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot( + `"/api/alert/{alertId}/alert_instance/{alertInstanceId}/_unmute"` + ); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.unmuteInstance.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + alertId: '1', + alertInstanceId: '2', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.unmuteInstance).toHaveBeenCalledTimes(1); + expect(alertsClient.unmuteInstance.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "alertId": "1", + "alertInstanceId": "2", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/unmute_instance.ts b/x-pack/plugins/alerting/server/routes/unmute_instance.ts new file mode 100644 index 00000000000000..fc24ea88ddb67e --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/unmute_instance.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + alertId: schema.string(), + alertInstanceId: schema.string(), +}); + +export const unmuteAlertInstanceRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{alertId}/alert_instance/{alertInstanceId}/_unmute', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { alertId, alertInstanceId } = req.params; + await alertsClient.unmuteInstance({ alertId, alertInstanceId }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/update.test.ts b/x-pack/plugins/alerting/server/routes/update.test.ts new file mode 100644 index 00000000000000..005367ef7979c9 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update.test.ts @@ -0,0 +1,217 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { updateAlertRoute } from './update'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('updateAlertRoute', () => { + const mockedResponse = { + id: '1', + alertTypeId: '1', + tags: ['foo'], + schedule: { interval: '12s' }, + params: { + otherField: false, + }, + createdAt: new Date(), + updatedAt: new Date(), + actions: [ + { + group: 'default', + id: '2', + actionTypeId: 'test', + params: { + baz: true, + }, + }, + ], + }; + + it('updates an alert with proper parameters', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + updateAlertRoute(router, licenseState); + + const [config, handler] = router.put.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.update.mockResolvedValueOnce(mockedResponse); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + body: { + throttle: null, + name: 'abc', + tags: ['bar'], + schedule: { interval: '12s' }, + params: { + otherField: false, + }, + actions: [ + { + group: 'default', + id: '2', + params: { + baz: true, + }, + }, + ], + }, + }, + ['ok'] + ); + + expect(await handler(context, req, res)).toEqual({ body: mockedResponse }); + + expect(alertsClient.update).toHaveBeenCalledTimes(1); + expect(alertsClient.update.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "data": Object { + "actions": Array [ + Object { + "group": "default", + "id": "2", + "params": Object { + "baz": true, + }, + }, + ], + "name": "abc", + "params": Object { + "otherField": false, + }, + "schedule": Object { + "interval": "12s", + }, + "tags": Array [ + "bar", + ], + }, + "id": "1", + }, + ] + `); + + expect(res.ok).toHaveBeenCalled(); + }); + + it('ensures the license allows updating alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + updateAlertRoute(router, licenseState); + + const [, handler] = router.put.mock.calls[0]; + + alertsClient.update.mockResolvedValueOnce(mockedResponse); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + body: { + throttle: null, + name: 'abc', + tags: ['bar'], + schedule: { interval: '12s' }, + params: { + otherField: false, + }, + actions: [ + { + group: 'default', + id: '2', + params: { + baz: true, + }, + }, + ], + }, + }, + ['ok'] + ); + + await handler(context, req, res); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); + + it('ensures the license check prevents updating alerts', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + (verifyApiAccess as jest.Mock).mockImplementation(() => { + throw new Error('OMG'); + }); + + updateAlertRoute(router, licenseState); + + const [, handler] = router.put.mock.calls[0]; + + alertsClient.update.mockResolvedValueOnce(mockedResponse); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + body: { + throttle: null, + name: 'abc', + tags: ['bar'], + schedule: { interval: '12s' }, + params: { + otherField: false, + }, + actions: [ + { + group: 'default', + id: '2', + params: { + baz: true, + }, + }, + ], + }, + }, + ['ok'] + ); + + expect(handler(context, req, res)).rejects.toMatchInlineSnapshot(`[Error: OMG]`); + + expect(verifyApiAccess).toHaveBeenCalledWith(licenseState); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/update.ts b/x-pack/plugins/alerting/server/routes/update.ts new file mode 100644 index 00000000000000..a402d13c5fbab1 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; +import { validateDurationSchema } from '../lib'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +const bodySchema = schema.object({ + name: schema.string(), + tags: schema.arrayOf(schema.string(), { defaultValue: [] }), + schedule: schema.object({ + interval: schema.string({ validate: validateDurationSchema }), + }), + throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + actions: schema.arrayOf( + schema.object({ + group: schema.string(), + id: schema.string(), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + actionTypeId: schema.maybe(schema.string()), + }), + { defaultValue: [] } + ), +}); + +export const updateAlertRoute = (router: IRouter, licenseState: LicenseState) => { + router.put( + { + path: '/api/alert/{id}', + validate: { + body: bodySchema, + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, TypeOf, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + const { name, actions, params, schedule, tags } = req.body; + return res.ok({ + body: await alertsClient.update({ + id, + data: { name, actions, params, schedule, tags }, + }), + }); + }) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/update_api_key.test.ts b/x-pack/plugins/alerting/server/routes/update_api_key.test.ts new file mode 100644 index 00000000000000..5e9821ac005e2b --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update_api_key.test.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { updateApiKeyRoute } from './update_api_key'; +import { mockRouter, RouterMock } from '../../../../../src/core/server/http/router/router.mock'; +import { mockLicenseState } from '../lib/license_state.mock'; +import { mockHandlerArguments } from './_mock_handler_arguments'; +import { alertsClientMock } from '../alerts_client.mock'; + +const alertsClient = alertsClientMock.create(); +jest.mock('../lib/license_api_access.ts', () => ({ + verifyApiAccess: jest.fn(), +})); + +beforeEach(() => { + jest.resetAllMocks(); +}); + +describe('updateApiKeyRoute', () => { + it('updates api key for an alert', async () => { + const licenseState = mockLicenseState(); + const router: RouterMock = mockRouter.create(); + + updateApiKeyRoute(router, licenseState); + + const [config, handler] = router.post.mock.calls[0]; + + expect(config.path).toMatchInlineSnapshot(`"/api/alert/{id}/_update_api_key"`); + expect(config.options).toMatchInlineSnapshot(` + Object { + "tags": Array [ + "access:alerting-all", + ], + } + `); + + alertsClient.updateApiKey.mockResolvedValueOnce(); + + const [context, req, res] = mockHandlerArguments( + { alertsClient }, + { + params: { + id: '1', + }, + }, + ['noContent'] + ); + + expect(await handler(context, req, res)).toEqual(undefined); + + expect(alertsClient.updateApiKey).toHaveBeenCalledTimes(1); + expect(alertsClient.updateApiKey.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + Object { + "id": "1", + }, + ] + `); + + expect(res.noContent).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/alerting/server/routes/update_api_key.ts b/x-pack/plugins/alerting/server/routes/update_api_key.ts new file mode 100644 index 00000000000000..0951b6c7b939e6 --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/update_api_key.ts @@ -0,0 +1,45 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema, TypeOf } from '@kbn/config-schema'; +import { + IRouter, + RequestHandlerContext, + KibanaRequest, + IKibanaResponse, + KibanaResponseFactory, +} from 'kibana/server'; +import { LicenseState } from '../lib/license_state'; +import { verifyApiAccess } from '../lib/license_api_access'; + +const paramSchema = schema.object({ + id: schema.string(), +}); + +export const updateApiKeyRoute = (router: IRouter, licenseState: LicenseState) => { + router.post( + { + path: '/api/alert/{id}/_update_api_key', + validate: { + params: paramSchema, + }, + options: { + tags: ['access:alerting-all'], + }, + }, + router.handleLegacyErrors(async function( + context: RequestHandlerContext, + req: KibanaRequest, any, any, any>, + res: KibanaResponseFactory + ): Promise> { + verifyApiAccess(licenseState); + const alertsClient = context.alerting.getAlertsClient(); + const { id } = req.params; + await alertsClient.updateApiKey({ id }); + return res.noContent(); + }) + ); +}; diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/alert_task_instance.test.ts b/x-pack/plugins/alerting/server/task_runner/alert_task_instance.test.ts similarity index 98% rename from x-pack/legacy/plugins/alerting/server/task_runner/alert_task_instance.test.ts rename to x-pack/plugins/alerting/server/task_runner/alert_task_instance.test.ts index 9cbe91a4dbcedd..28b3576dffc6ed 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/alert_task_instance.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/alert_task_instance.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ConcreteTaskInstance, TaskStatus } from '../../../../../plugins/task_manager/server'; +import { ConcreteTaskInstance, TaskStatus } from '../../../../plugins/task_manager/server'; import { AlertTaskInstance, taskInstanceToAlertTaskInstance } from './alert_task_instance'; import uuid from 'uuid'; import { SanitizedAlert } from '../types'; diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/alert_task_instance.ts b/x-pack/plugins/alerting/server/task_runner/alert_task_instance.ts similarity index 94% rename from x-pack/legacy/plugins/alerting/server/task_runner/alert_task_instance.ts rename to x-pack/plugins/alerting/server/task_runner/alert_task_instance.ts index 6bc318070377d3..9f5e3851aa29d0 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/alert_task_instance.ts +++ b/x-pack/plugins/alerting/server/task_runner/alert_task_instance.ts @@ -6,7 +6,7 @@ import * as t from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; -import { ConcreteTaskInstance } from '../../../../../plugins/task_manager/server'; +import { ConcreteTaskInstance } from '../../../../plugins/task_manager/server'; import { SanitizedAlert, AlertTaskState, alertParamsSchema, alertStateSchema } from '../../common'; export interface AlertTaskInstance extends ConcreteTaskInstance { diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/create_execution_handler.test.ts b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts similarity index 98% rename from x-pack/legacy/plugins/alerting/server/task_runner/create_execution_handler.test.ts rename to x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts index 02fa09ba97a656..1b3a9ed8d7b067 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/create_execution_handler.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.test.ts @@ -6,7 +6,7 @@ import { AlertType } from '../types'; import { createExecutionHandler } from './create_execution_handler'; -import { loggingServiceMock } from '../../../../../../src/core/server/mocks'; +import { loggingServiceMock } from '../../../../../src/core/server/mocks'; const alertType: AlertType = { id: 'test', diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/create_execution_handler.ts b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts similarity index 94% rename from x-pack/legacy/plugins/alerting/server/task_runner/create_execution_handler.ts rename to x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts index 737f86a881c1fd..9b2d218114c31b 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/create_execution_handler.ts +++ b/x-pack/plugins/alerting/server/task_runner/create_execution_handler.ts @@ -6,9 +6,9 @@ import { pluck } from 'lodash'; import { AlertAction, State, Context, AlertType } from '../types'; -import { Logger } from '../../../../../../src/core/server'; +import { Logger } from '../../../../../src/core/server'; import { transformActionParams } from './transform_action_params'; -import { PluginStartContract as ActionsPluginStartContract } from '../../../../../plugins/actions/server'; +import { PluginStartContract as ActionsPluginStartContract } from '../../../../plugins/actions/server'; interface CreateExecutionHandlerOptions { alertId: string; diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/get_next_run_at.test.ts b/x-pack/plugins/alerting/server/task_runner/get_next_run_at.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/task_runner/get_next_run_at.test.ts rename to x-pack/plugins/alerting/server/task_runner/get_next_run_at.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/get_next_run_at.ts b/x-pack/plugins/alerting/server/task_runner/get_next_run_at.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/task_runner/get_next_run_at.ts rename to x-pack/plugins/alerting/server/task_runner/get_next_run_at.ts diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/index.ts b/x-pack/plugins/alerting/server/task_runner/index.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/task_runner/index.ts rename to x-pack/plugins/alerting/server/task_runner/index.ts diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts similarity index 97% rename from x-pack/legacy/plugins/alerting/server/task_runner/task_runner.test.ts rename to x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index b6dd4b3435fcbe..af0e7b658240a7 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -7,14 +7,11 @@ import sinon from 'sinon'; import { schema } from '@kbn/config-schema'; import { AlertExecutorOptions } from '../types'; -import { ConcreteTaskInstance, TaskStatus } from '../../../../../plugins/task_manager/server'; +import { ConcreteTaskInstance, TaskStatus } from '../../../../plugins/task_manager/server'; import { TaskRunnerContext } from './task_runner_factory'; import { TaskRunner } from './task_runner'; -import { encryptedSavedObjectsMock } from '../../../../../plugins/encrypted_saved_objects/server/mocks'; -import { - savedObjectsClientMock, - loggingServiceMock, -} from '../../../../../../src/core/server/mocks'; +import { encryptedSavedObjectsMock } from '../../../../plugins/encrypted_saved_objects/server/mocks'; +import { savedObjectsClientMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; const alertType = { id: 'test', diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts similarity index 97% rename from x-pack/legacy/plugins/alerting/server/task_runner/task_runner.ts rename to x-pack/plugins/alerting/server/task_runner/task_runner.ts index 2632decb125f06..34278ee62dbc4e 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -5,10 +5,10 @@ */ import { pick, mapValues, omit } from 'lodash'; -import { Logger } from '../../../../../../src/core/server'; -import { SavedObject } from '../../../../../../src/core/server'; +import { Logger } from '../../../../../src/core/server'; +import { SavedObject } from '../../../../../src/core/server'; import { TaskRunnerContext } from './task_runner_factory'; -import { ConcreteTaskInstance } from '../../../../../plugins/task_manager/server'; +import { ConcreteTaskInstance } from '../../../../plugins/task_manager/server'; import { createExecutionHandler } from './create_execution_handler'; import { AlertInstance, createAlertInstanceFactory } from '../alert_instance'; import { getNextRunAt } from './get_next_run_at'; diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner_factory.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts similarity index 89% rename from x-pack/legacy/plugins/alerting/server/task_runner/task_runner_factory.test.ts rename to x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts index 7474fcfb4baaa7..4dad46ef32f214 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner_factory.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts @@ -5,13 +5,10 @@ */ import sinon from 'sinon'; -import { ConcreteTaskInstance, TaskStatus } from '../../../../../plugins/task_manager/server'; +import { ConcreteTaskInstance, TaskStatus } from '../../../../plugins/task_manager/server'; import { TaskRunnerContext, TaskRunnerFactory } from './task_runner_factory'; -import { encryptedSavedObjectsMock } from '../../../../../plugins/encrypted_saved_objects/server/mocks'; -import { - savedObjectsClientMock, - loggingServiceMock, -} from '../../../../../../src/core/server/mocks'; +import { encryptedSavedObjectsMock } from '../../../../plugins/encrypted_saved_objects/server/mocks'; +import { savedObjectsClientMock, loggingServiceMock } from '../../../../../src/core/server/mocks'; const alertType = { id: 'test', diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner_factory.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts similarity index 83% rename from x-pack/legacy/plugins/alerting/server/task_runner/task_runner_factory.ts rename to x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts index d2ecfb64c8a813..c598b0f52f197b 100644 --- a/x-pack/legacy/plugins/alerting/server/task_runner/task_runner_factory.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.ts @@ -3,10 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { Logger } from '../../../../../../src/core/server'; -import { RunContext } from '../../../../../plugins/task_manager/server'; -import { EncryptedSavedObjectsPluginStart } from '../../../../../plugins/encrypted_saved_objects/server'; -import { PluginStartContract as ActionsPluginStartContract } from '../../../../../plugins/actions/server'; +import { Logger } from '../../../../../src/core/server'; +import { RunContext } from '../../../../plugins/task_manager/server'; +import { EncryptedSavedObjectsPluginStart } from '../../../../plugins/encrypted_saved_objects/server'; +import { PluginStartContract as ActionsPluginStartContract } from '../../../../plugins/actions/server'; import { AlertType, GetBasePathFunction, diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/transform_action_params.test.ts b/x-pack/plugins/alerting/server/task_runner/transform_action_params.test.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/task_runner/transform_action_params.test.ts rename to x-pack/plugins/alerting/server/task_runner/transform_action_params.test.ts diff --git a/x-pack/legacy/plugins/alerting/server/task_runner/transform_action_params.ts b/x-pack/plugins/alerting/server/task_runner/transform_action_params.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/task_runner/transform_action_params.ts rename to x-pack/plugins/alerting/server/task_runner/transform_action_params.ts diff --git a/x-pack/legacy/plugins/alerting/server/test_utils/index.ts b/x-pack/plugins/alerting/server/test_utils/index.ts similarity index 100% rename from x-pack/legacy/plugins/alerting/server/test_utils/index.ts rename to x-pack/plugins/alerting/server/test_utils/index.ts diff --git a/x-pack/legacy/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts similarity index 91% rename from x-pack/legacy/plugins/alerting/server/types.ts rename to x-pack/plugins/alerting/server/types.ts index 95a96fa384c2c9..202a73f076859f 100644 --- a/x-pack/legacy/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -7,8 +7,9 @@ import { AlertInstance } from './alert_instance'; import { AlertTypeRegistry as OrigAlertTypeRegistry } from './alert_type_registry'; import { PluginSetupContract, PluginStartContract } from './plugin'; -import { SavedObjectAttributes, SavedObjectsClientContract } from '../../../../../src/core/server'; +import { SavedObjectAttributes, SavedObjectsClientContract } from '../../../../src/core/server'; import { Alert, AlertActionParams } from '../common'; +import { AlertsClient } from './alerts_client'; export * from '../common'; export type State = Record; @@ -18,6 +19,15 @@ export type GetServicesFunction = (request: any) => Services; export type GetBasePathFunction = (spaceId?: string) => string; export type SpaceIdToNamespaceFunction = (spaceId?: string) => string | undefined; +declare module 'src/core/server' { + interface RequestHandlerContext { + alerting: { + getAlertsClient: () => AlertsClient; + listTypes: AlertTypeRegistry['list']; + }; + } +} + export interface Services { callCluster(path: string, opts: any): Promise; savedObjectsClient: SavedObjectsClientContract; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/alert_api.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/alert_api.ts index 22fd01c1aee819..e0ecae976146c0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/alert_api.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/alert_api.ts @@ -8,9 +8,9 @@ import { HttpSetup } from 'kibana/public'; import * as t from 'io-ts'; import { pipe } from 'fp-ts/lib/pipeable'; import { fold } from 'fp-ts/lib/Either'; +import { alertStateSchema } from '../../../../alerting/common'; import { BASE_ALERT_API_PATH } from '../constants'; import { Alert, AlertType, AlertWithoutId, AlertTaskState } from '../../types'; -import { alertStateSchema } from '../../../../../legacy/plugins/alerting/common'; export async function loadAlertTypes({ http }: { http: HttpSetup }): Promise { return await http.get(`${BASE_ALERT_API_PATH}/types`); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx index 1f0e4f015f229d..731489c61d60f1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx @@ -12,8 +12,7 @@ import { EuiBasicTable, EuiButtonToggle, EuiBadge, EuiHealth } from '@elastic/eu import { RIGHT_ALIGNMENT, CENTER_ALIGNMENT } from '@elastic/eui/lib/services'; import { padLeft, difference } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; -import { RawAlertInstance } from '../../../../../../../legacy/plugins/alerting/common'; -import { Alert, AlertTaskState } from '../../../../types'; +import { Alert, AlertTaskState, RawAlertInstance } from '../../../../types'; import { ComponentOpts as AlertApis, withBulkAlertOperations, diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 86853e88a81cd9..aa1d3d068ed77b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -10,7 +10,7 @@ import { AlertAction, AlertTaskState, RawAlertInstance, -} from '../../../legacy/plugins/alerting/common'; +} from '../../../plugins/alerting/common'; export { Alert, AlertAction, AlertTaskState, RawAlertInstance }; export { ActionType }; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts index 0cc45a624bc1a0..b06e0c9e0f8cdd 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/index.ts @@ -5,7 +5,7 @@ */ import { times } from 'lodash'; import { schema } from '@kbn/config-schema'; -import { AlertExecutorOptions, AlertType } from '../../../../../../legacy/plugins/alerting'; +import { AlertExecutorOptions, AlertType } from '../../../../../../plugins/alerting/server'; import { ActionTypeExecutorOptions, ActionType } from '../../../../../../plugins/actions/server'; // eslint-disable-next-line import/no-default-export @@ -392,13 +392,13 @@ export default function(kibana: any) { actionGroups: [{ id: 'default', name: 'Default' }], async executor({ services, params, state }: AlertExecutorOptions) {}, }; - server.plugins.alerting.setup.registerType(alwaysFiringAlertType); - server.plugins.alerting.setup.registerType(cumulativeFiringAlertType); - server.plugins.alerting.setup.registerType(neverFiringAlertType); - server.plugins.alerting.setup.registerType(failingAlertType); - server.plugins.alerting.setup.registerType(validationAlertType); - server.plugins.alerting.setup.registerType(authorizationAlertType); - server.plugins.alerting.setup.registerType(noopAlertType); + server.newPlatform.setup.plugins.alerting.registerType(alwaysFiringAlertType); + server.newPlatform.setup.plugins.alerting.registerType(cumulativeFiringAlertType); + server.newPlatform.setup.plugins.alerting.registerType(neverFiringAlertType); + server.newPlatform.setup.plugins.alerting.registerType(failingAlertType); + server.newPlatform.setup.plugins.alerting.registerType(validationAlertType); + server.newPlatform.setup.plugins.alerting.registerType(authorizationAlertType); + server.newPlatform.setup.plugins.alerting.registerType(noopAlertType); }, }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts index 003bb10c0adae5..7dae7e4ab7941d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/create.ts @@ -213,12 +213,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: - 'child "name" fails because ["name" is required]. child "alertTypeId" fails because ["alertTypeId" is required]. child "consumer" fails because ["consumer" is required]. child "schedule" fails because ["schedule" is required]. child "params" fails because ["params" is required]. child "actions" fails because ["actions" is required]', - validation: { - source: 'payload', - keys: ['name', 'alertTypeId', 'consumer', 'schedule', 'params', 'actions'], - }, + message: '[request body.name]: expected value of type [string] but got [undefined]', }); break; default: @@ -285,19 +280,9 @@ export default function createAlertTests({ getService }: FtrProviderContext) { case 'space_1_all at space1': expect(response.statusCode).to.eql(400); expect(response.body).to.eql({ - statusCode: 400, error: 'Bad Request', - message: - 'child "schedule" fails because [child "interval" fails because ["interval" with value "10x" fails to match the seconds pattern, "interval" with value "10x" fails to match the minutes pattern, "interval" with value "10x" fails to match the hours pattern, "interval" with value "10x" fails to match the days pattern]]', - validation: { - source: 'payload', - keys: [ - 'schedule.interval', - 'schedule.interval', - 'schedule.interval', - 'schedule.interval', - ], - }, + message: '[request body.schedule.interval]: string is not a valid duration: 10x', + statusCode: 400, }); break; default: @@ -327,19 +312,9 @@ export default function createAlertTests({ getService }: FtrProviderContext) { case 'space_1_all at space1': expect(response.statusCode).to.eql(400); expect(response.body).to.eql({ - statusCode: 400, error: 'Bad Request', - message: - 'child "schedule" fails because [child "interval" fails because ["interval" with value "0s" fails to match the seconds pattern, "interval" with value "0s" fails to match the minutes pattern, "interval" with value "0s" fails to match the hours pattern, "interval" with value "0s" fails to match the days pattern]]', - validation: { - source: 'payload', - keys: [ - 'schedule.interval', - 'schedule.interval', - 'schedule.interval', - 'schedule.interval', - ], - }, + message: '[request body.schedule.interval]: string is not a valid duration: 0s', + statusCode: 400, }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts index 65ffa9ebe9dfae..f91c06c5299b8d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/find.ts @@ -202,7 +202,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { expect(response.statusCode).to.eql(200); expect(response.body).to.eql({ page: 1, - perPage: 20, + perPage: 10, total: 0, data: [], }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts index 7a4f73885107c4..f7ccc6c97bcf0a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/update.ts @@ -53,7 +53,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { }, schedule: { interval: '12s' }, actions: [], - throttle: '2m', + throttle: '1m', }; const response = await supertestWithoutAuth .put(`${getUrlPrefix(space.id)}/api/alert/${createdAlert.id}`) @@ -134,7 +134,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { }, schedule: { interval: '12s' }, actions: [], - throttle: '2m', + throttle: '1m', }; const response = await supertestWithoutAuth .put(`${getUrlPrefix(space.id)}/api/alert/${createdAlert.id}`) @@ -277,11 +277,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: '"alertTypeId" is not allowed', - validation: { - source: 'payload', - keys: ['alertTypeId'], - }, + message: '[request body.alertTypeId]: definition for this key is missing', }); break; default: @@ -313,12 +309,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: - 'child "throttle" fails because ["throttle" is required]. child "name" fails because ["name" is required]. child "tags" fails because ["tags" is required]. child "schedule" fails because ["schedule" is required]. child "params" fails because ["params" is required]. child "actions" fails because ["actions" is required]', - validation: { - source: 'payload', - keys: ['throttle', 'name', 'tags', 'schedule', 'params', 'actions'], - }, + message: '[request body.name]: expected value of type [string] but got [undefined]', }); break; default: @@ -410,18 +401,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { expect(response.body).to.eql({ statusCode: 400, error: 'Bad Request', - message: - 'child "schedule" fails because [child "interval" fails because ["interval" with value "10x" fails to match the seconds pattern, "interval" with value "10x" fails to match the minutes pattern, "interval" with value "10x" fails to match the hours pattern, "interval" with value "10x" fails to match the days pattern]]. "alertTypeId" is not allowed', - validation: { - source: 'payload', - keys: [ - 'schedule.interval', - 'schedule.interval', - 'schedule.interval', - 'schedule.interval', - 'alertTypeId', - ], - }, + message: '[request body.schedule.interval]: string is not a valid duration: 10x', }); break; default: @@ -456,7 +436,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { }, schedule: { interval: '1m' }, actions: [], - throttle: '2m', + throttle: '1m', }; const response = await supertestWithoutAuth .put(`${getUrlPrefix(space.id)}/api/alert/${createdAlert.id}`) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/index.ts index 6a99ed366047b7..c0f56c55ba8503 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/index.ts @@ -18,7 +18,7 @@ export default function alertingApiIntegrationTests({ const esArchiver = getService('esArchiver'); describe('alerting api integration security and spaces enabled', function() { - this.tags('ciGroup1'); + this.tags('ciGroup3'); before(async () => { for (const space of Spaces) { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts index 70935a462d03e8..1dd0426c97ccab 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts @@ -77,7 +77,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { ) .expect(200, { page: 1, - perPage: 20, + perPage: 10, total: 0, data: [], }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/index.ts index cb2b17980d37ae..b118a48fd642c1 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/index.ts @@ -16,7 +16,7 @@ export default function alertingApiIntegrationTests({ const esArchiver = getService('esArchiver'); describe('alerting api integration spaces only', function() { - this.tags('ciGroup1'); + this.tags('ciGroup3'); before(async () => { for (const space of Object.values(Spaces)) { diff --git a/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/index.ts b/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/index.ts index d7551345203b49..678707af40bae5 100644 --- a/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/index.ts +++ b/x-pack/test/functional_with_es_ssl/fixtures/plugins/alerts/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { AlertType } from '../../../../../legacy/plugins/alerting'; +import { AlertType } from '../../../../../plugins/alerting/server'; // eslint-disable-next-line import/no-default-export export default function(kibana: any) { @@ -12,8 +12,8 @@ export default function(kibana: any) { require: ['alerting'], name: 'alerts', init(server: any) { - createNoopAlertType(server.plugins.alerting.setup); - createAlwaysFiringAlertType(server.plugins.alerting.setup); + createNoopAlertType(server.newPlatform.setup.plugins.alerting); + createAlwaysFiringAlertType(server.newPlatform.setup.plugins.alerting); }, }); } diff --git a/x-pack/typings/hapi.d.ts b/x-pack/typings/hapi.d.ts index 8d54d28794351d..872e042eb1cdb1 100644 --- a/x-pack/typings/hapi.d.ts +++ b/x-pack/typings/hapi.d.ts @@ -9,7 +9,7 @@ import 'hapi'; import { XPackMainPlugin } from '../legacy/plugins/xpack_main/server/xpack_main'; import { SecurityPlugin } from '../legacy/plugins/security'; import { ActionsPlugin, ActionsClient } from '../plugins/actions/server'; -import { AlertingPlugin, AlertsClient } from '../legacy/plugins/alerting'; +import { AlertingPlugin, AlertsClient } from '../plugins/alerting/server'; import { LegacyTaskManagerApi } from '../legacy/plugins/task_manager/server'; declare module 'hapi' {