From 93b67fb1a37b397284c92309e3ca864580b9fcfc Mon Sep 17 00:00:00 2001 From: Julian Gernun <17549662+jcger@users.noreply.github.com> Date: Thu, 28 Nov 2024 08:45:11 +0100 Subject: [PATCH] [ResponseOps][Alerting] Add deprecation object to legacy rule endpoints (#201550) ## Summary Adds deprecation object in deprecated alerting routes Closes https://github.com/elastic/kibana/issues/196556 --------- Co-authored-by: lcawl --- docs/CHANGELOG.asciidoc | 53 +++++++++++++++++++ docs/upgrade-notes.asciidoc | 45 +++++++++++++--- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + x-pack/plugins/alerting/server/plugin.ts | 1 + .../plugins/alerting/server/routes/index.ts | 3 +- .../server/routes/legacy/create.test.ts | 50 +++++++++++++++-- .../alerting/server/routes/legacy/create.ts | 12 ++++- .../server/routes/legacy/delete.test.ts | 39 ++++++++++++-- .../alerting/server/routes/legacy/delete.ts | 13 ++++- .../server/routes/legacy/disable.test.ts | 37 +++++++++++-- .../alerting/server/routes/legacy/disable.ts | 13 ++++- .../server/routes/legacy/enable.test.ts | 37 +++++++++++-- .../alerting/server/routes/legacy/enable.ts | 13 ++++- .../server/routes/legacy/find.test.ts | 45 +++++++++++++--- .../alerting/server/routes/legacy/find.ts | 13 ++++- .../alerting/server/routes/legacy/get.test.ts | 39 +++++++++++--- .../alerting/server/routes/legacy/get.ts | 13 ++++- .../legacy/get_alert_instance_summary.test.ts | 34 ++++++++++-- .../legacy/get_alert_instance_summary.ts | 11 +++- .../routes/legacy/get_alert_state.test.ts | 36 +++++++++++-- .../server/routes/legacy/get_alert_state.ts | 11 +++- .../server/routes/legacy/health.test.ts | 49 +++++++++++++---- .../alerting/server/routes/legacy/health.ts | 13 ++++- .../alerting/server/routes/legacy/index.ts | 33 ++++++------ .../routes/legacy/list_alert_types.test.ts | 38 +++++++++++-- .../server/routes/legacy/list_alert_types.ts | 13 ++++- .../server/routes/legacy/mute_all.test.ts | 37 +++++++++++-- .../alerting/server/routes/legacy/mute_all.ts | 13 ++++- .../routes/legacy/mute_instance.test.ts | 37 +++++++++++-- .../server/routes/legacy/mute_instance.ts | 13 ++++- .../server/routes/legacy/unmute_all.test.ts | 37 +++++++++++-- .../server/routes/legacy/unmute_all.ts | 13 ++++- .../routes/legacy/unmute_instance.test.ts | 37 +++++++++++-- .../server/routes/legacy/unmute_instance.ts | 13 ++++- .../server/routes/legacy/update.test.ts | 42 ++++++++++++--- .../alerting/server/routes/legacy/update.ts | 13 ++++- .../routes/legacy/update_api_key.test.ts | 36 +++++++++++-- .../server/routes/legacy/update_api_key.ts | 13 ++++- .../apis/create/create_rule_route.test.ts | 15 ++++-- 40 files changed, 847 insertions(+), 138 deletions(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 848042e475fee..ef8d4182144f0 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -27,6 +27,59 @@ For information about the {kib} 9.0.0 release, review the following information. [[breaking-changes-9.0.0]] === Breaking changes +[discrete] +.Removed legacy alerting endpoints (9.0.0) +[%collapsible] +==== +*Details* + +-- +* `POST /api/alerts/alert/{id?}` has been replaced by `POST /api/alerting/rule/{id?}` +* `GET /api/alerts/alert/{id}` has been replaced by `GET /api/alerting/rule/{id}` +* `PUT /api/alerts/alert/{id}` has been replaced by `PUT /api/alerting/rule/rule/{id}` +* `DELETE: /api/alerts/alert/{id}` has been replaced by `DELETE /api/alerting/rule/{id}` +* `POST /api/alerts/alert/{id}/_disable` has been replaced by `POST /api/alerting/rule/{id}/_disable` +* `POST /api/alerts/alert/{id}/_enable` has been replaced by `POST /api/alerting/rule/{id}/_enable` +* `GET /api/alerts/_find` has been replaced by `GET /api/alerting/rules/_find` +* `GET /api/alerts/_health` has been replaced by `GET /api/alerting/rule/_health` +* `GET /api/alerts/list_alert_types` has been replaced by `GET /api/alerting/rule_types` +* `POST /api/alerts/alert/{alert_id}/alert_instance/{alert_instance_id}/_mute` has been replaced by `POST /api/alerting/rule/{rule_id}/alert/{alert_id}/_mute` +* `POST /api/alerts/alert/{alert_id}/alert_instance/{alert_instance_id}/_unmute` has been replaced by `POST /api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute` +* `POST /api/alerts/alert/{id}/_mute_all` has been replaced by `POST /api/alerting/rule/{id}/_mute_all` +* `POST /api/alerts/alert/{id}/_unmute_all` has been replaced by `POST /api/alerting/rule/{id}/_unmute_all` +* `POST /api/alerts/alert/{id}/_update_api_key` has been replaced by `POST /api/alerting/rule/{id}/_update_api_key` +* `GET /api/alerts/{id}/_instance_summary` has been deprecated without replacement. Will be removed in v9.0.0 +* `GET /api/alerts/{id}/state` has been deprecated without replacement. Will be removed in v9.0.0 +-- + +*Impact* + +Deprecated endpoints will fail with a 404 status code starting from version 9.0.0 + +*Action* + +Remove references to `GET /api/alerts/{id}/_instance_summary` endpoint. +Remove references to `GET /api/alerts/{id}/state` endpoint. +Replace references to endpoints listed as deprecated by it's replacement. See `Details` section. +The updated APIs can be found in {api-kibana}/group/endpoint-alerting +==== + +.Removed legacy cases endpoints (9.0.0) +[%collapsible] +==== +*Details* + +-- +* `GET /api/cases/status` has been deprecated with no replacement. Deleted in v9.0.0 +* `GET /api/cases/{case_id}/comments` has been replaced by `GET /api/cases/{case_id}/comments/_find` released in v7.13 +* `GET /api/cases//user_actions` has been replaced by `GET /api/cases//user_actions/_find` released in v8.7 +* `includeComments` parameter in `GET /api/cases/{case_id}` has been deprecated. Use `GET /api/cases/{case_id}/comments/_find` instead, released in v7.13 +-- + +*Impact* + +Deprecated endpoints will fail with a 404 status code starting from version 9.0.0 + +*Action* + +Remove references to `GET /api/cases/status` endpoint. +Replace references to deprecated endpoints with the replacements listed in the breaking change details. +==== + [discrete] .Removed all security v1 endpoints (9.0.0) [%collapsible] diff --git a/docs/upgrade-notes.asciidoc b/docs/upgrade-notes.asciidoc index 92c53ae4613c5..236d768b16d4e 100644 --- a/docs/upgrade-notes.asciidoc +++ b/docs/upgrade-notes.asciidoc @@ -50,18 +50,51 @@ For Elastic Security solution release information, refer to {security-guide}/rel [discrete] -[[breaking-201004]] -.[Cases] Legacy deprecations (9.0.0) +[[breaking-201550]] +.Removed legacy alerting endpoints (9.0.0) [%collapsible] ==== *Details* + -`GET /api/cases/status` has been deprecated with no replacement. Deleted in v9.0.0 +-- +* `POST /api/alerts/alert/{id?}` has been replaced by `POST /api/alerting/rule/{id?}` +* `GET /api/alerts/alert/{id}` has been replaced by `GET /api/alerting/rule/{id}` +* `PUT /api/alerts/alert/{id}` has been replaced by `PUT /api/alerting/rule/rule/{id}` +* `DELETE: /api/alerts/alert/{id}` has been replaced by `DELETE /api/alerting/rule/{id}` +* `POST /api/alerts/alert/{id}/_disable` has been replaced by `POST /api/alerting/rule/{id}/_disable` +* `POST /api/alerts/alert/{id}/_enable` has been replaced by `POST /api/alerting/rule/{id}/_enable` +* `GET /api/alerts/_find` has been replaced by `GET /api/alerting/rules/_find` +* `GET /api/alerts/_health` has been replaced by `GET /api/alerting/rule/_health` +* `GET /api/alerts/list_alert_types` has been replaced by `GET /api/alerting/rule_types` +* `POST /api/alerts/alert/{alert_id}/alert_instance/{alert_instance_id}/_mute` has been replaced by `POST /api/alerting/rule/{rule_id}/alert/{alert_id}/_mute` +* `POST /api/alerts/alert/{alert_id}/alert_instance/{alert_instance_id}/_unmute` has been replaced by `POST /api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute` +* `POST /api/alerts/alert/{id}/_mute_all` has been replaced by `POST /api/alerting/rule/{id}/_mute_all` +* `POST /api/alerts/alert/{id}/_unmute_all` has been replaced by `POST /api/alerting/rule/{id}/_unmute_all` +* `POST /api/alerts/alert/{id}/_update_api_key` has been replaced by `POST /api/alerting/rule/{id}/_update_api_key` +* `GET /api/alerts/{id}/_instance_summary` has been deprecated without replacement. Will be removed in v9.0.0 +* `GET /api/alerts/{id}/state` has been deprecated without replacement. Will be removed in v9.0.0 +-- -`GET /api/cases/{case_id}/comments` has been replaced by `GET /api/cases/{case_id}/comments/_find` released in v7.13 +*Impact* + +Deprecated endpoints will fail with a 404 status code starting from version 9.0.0 -`GET /api/cases//user_actions` has been replaced by `GET /api/cases//user_actions/_find` released in v8.7 +*Action* + +Remove references to `GET /api/alerts/{id}/_instance_summary` endpoint. +Remove references to `GET /api/alerts/{id}/state` endpoint. +Replace references to endpoints listed as deprecated by it's replacement. See `Details` section. +The updated APIs can be found here https://www.elastic.co/docs/api/doc/kibana/v8/group/endpoint-alerting +==== -`includeComments` parameter in `GET /api/cases/{case_id}` has been deprecated. Use `GET /api/cases/{case_id}/comments/_find` instead, released in v7.13 +[[breaking-201004]] +.Removed legacy cases endpoints (9.0.0) +[%collapsible] +==== +*Details* + +-- +* `GET /api/cases/status` has been deprecated with no replacement. Deleted in v9.0.0 +* `GET /api/cases/{case_id}/comments` has been replaced by `GET /api/cases/{case_id}/comments/_find` released in v7.13 +* `GET /api/cases//user_actions` has been replaced by `GET /api/cases//user_actions/_find` released in v8.7 +* `includeComments` parameter in `GET /api/cases/{case_id}` has been deprecated. Use `GET /api/cases/{case_id}/comments/_find` instead, released in v7.13 +-- *Impact* + Deprecated endpoints will fail with a 404 status code starting from version 9.0.0 diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index 52bc6bd34809f..7fd12a815484a 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -672,6 +672,7 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D slackApiAction: `${KIBANA_DOCS}slack-action-type.html#configuring-slack-web-api`, teamsAction: `${KIBANA_DOCS}teams-action-type.html#configuring-teams`, connectors: `${KIBANA_DOCS}action-types.html`, + legacyRuleApiDeprecations: `${KIBANA_DOCS}breaking-changes-summary.html#breaking-201550`, }, taskManager: { healthMonitoring: `${KIBANA_DOCS}task-manager-health-monitoring.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index b010c195bccbd..d55146420ec73 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -474,6 +474,7 @@ export interface DocLinks { slackApiAction: string; teamsAction: string; connectors: string; + legacyRuleApiDeprecations: string; }>; readonly taskManager: Readonly<{ healthMonitoring: string; diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index bf1f02d3a4910..67a30dea9c819 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -411,6 +411,7 @@ export class AlertingPlugin { encryptedSavedObjects: plugins.encryptedSavedObjects, config$: plugins.unifiedSearch.autocomplete.getInitializerContextConfig().create(), isServerless: !!plugins.serverless, + docLinks: core.docLinks, }); return { diff --git a/x-pack/plugins/alerting/server/routes/index.ts b/x-pack/plugins/alerting/server/routes/index.ts index 1a274692cefe4..d1fc9989be5e7 100644 --- a/x-pack/plugins/alerting/server/routes/index.ts +++ b/x-pack/plugins/alerting/server/routes/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { IRouter } from '@kbn/core/server'; +import { DocLinksServiceSetup, IRouter } from '@kbn/core/server'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; import type { ConfigSchema } from '@kbn/unified-search-plugin/server/config'; @@ -81,6 +81,7 @@ export interface RouteOptions { usageCounter?: UsageCounter; config$?: Observable; isServerless?: boolean; + docLinks: DocLinksServiceSetup; } export function defineRoutes(opts: RouteOptions) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.test.ts b/x-pack/plugins/alerting/server/routes/legacy/create.test.ts index 52917ad5f3023..f3df843899f22 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.test.ts @@ -16,6 +16,7 @@ import { Rule, RuleSystemAction } from '../../../common/rule'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -32,6 +33,7 @@ beforeEach(() => { }); describe('createAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); const createdAt = new Date(); const updatedAt = new Date(); @@ -104,6 +106,7 @@ describe('createAlertRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -179,6 +182,7 @@ describe('createAlertRoute', () => { encryptedSavedObjects, usageCounter: mockUsageCounter, isServerless: true, + docLinks, }); const [config] = router.post.mock.calls[0]; @@ -204,6 +208,7 @@ describe('createAlertRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -281,6 +286,7 @@ describe('createAlertRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -359,6 +365,7 @@ describe('createAlertRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -426,7 +433,7 @@ describe('createAlertRoute', () => { const router = httpServiceMock.createRouter(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); - createAlertRoute({ router, licenseState, encryptedSavedObjects }); + createAlertRoute({ router, licenseState, encryptedSavedObjects, docLinks }); const [, handler] = router.post.mock.calls[0]; @@ -448,7 +455,7 @@ describe('createAlertRoute', () => { throw new Error('OMG'); }); - createAlertRoute({ router, licenseState, encryptedSavedObjects }); + createAlertRoute({ router, licenseState, encryptedSavedObjects, docLinks }); const [, handler] = router.post.mock.calls[0]; @@ -466,7 +473,7 @@ describe('createAlertRoute', () => { const router = httpServiceMock.createRouter(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); - createAlertRoute({ router, licenseState, encryptedSavedObjects }); + createAlertRoute({ router, licenseState, encryptedSavedObjects, docLinks }); const [, handler] = router.post.mock.calls[0]; @@ -491,6 +498,7 @@ describe('createAlertRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [, handler] = router.post.mock.calls[0]; rulesClient.create.mockResolvedValueOnce(createResult); @@ -511,6 +519,7 @@ describe('createAlertRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -570,4 +579,39 @@ describe('createAlertRoute', () => { body: createResult, }); }); + + it('should be deprecated', () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); + const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); + const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); + + createAlertRoute({ + router, + licenseState, + encryptedSavedObjects, + usageCounter: mockUsageCounter, + docLinks, + }); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{id?}", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.ts b/x-pack/plugins/alerting/server/routes/legacy/create.ts index 333877b7df49e..10c0fd2941068 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.ts @@ -49,6 +49,7 @@ export const createAlertRoute = ({ licenseState, usageCounter, isServerless, + docLinks, }: RouteOptions) => { router.post( { @@ -65,8 +66,15 @@ export const createAlertRoute = ({ access: isServerless ? 'internal' : 'public', summary: 'Create an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{id?}', + }, + }, }, }, handleDisabledApiKeysError( diff --git a/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts b/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts index 95a28904f4796..d8fd0effc50e4 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/delete.test.ts @@ -13,6 +13,7 @@ import { verifyApiAccess } from '../../lib/license_api_access'; import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -29,11 +30,13 @@ beforeEach(() => { }); describe('deleteAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('deletes an alert with proper parameters', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - deleteAlertRoute(router, licenseState); + deleteAlertRoute(router, licenseState, docLinks); const [config, handler] = router.delete.mock.calls[0]; @@ -70,7 +73,7 @@ describe('deleteAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - deleteAlertRoute(router, licenseState, undefined, true); + deleteAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.delete.mock.calls[0]; @@ -82,7 +85,7 @@ describe('deleteAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - deleteAlertRoute(router, licenseState); + deleteAlertRoute(router, licenseState, docLinks); const [, handler] = router.delete.mock.calls[0]; @@ -108,7 +111,7 @@ describe('deleteAlertRoute', () => { throw new Error('OMG'); }); - deleteAlertRoute(router, licenseState); + deleteAlertRoute(router, licenseState, docLinks); const [, handler] = router.delete.mock.calls[0]; @@ -132,7 +135,7 @@ describe('deleteAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - deleteAlertRoute(router, licenseState, mockUsageCounter); + deleteAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.delete.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: '1' } }, [ 'ok', @@ -140,4 +143,30 @@ describe('deleteAlertRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('delete', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + deleteAlertRoute(router, licenseState, docLinks); + + const [config] = router.delete.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "DELETE", + "newApiPath": "/api/alerting/rule/{id}", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/delete.ts b/x-pack/plugins/alerting/server/routes/legacy/delete.ts index 2b63de9e4ee73..a3ceb1ebccbba 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/delete.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/delete.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -20,6 +21,7 @@ const paramSchema = schema.object({ export const deleteAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -33,8 +35,15 @@ export const deleteAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Delete an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'DELETE', + newApiPath: '/api/alerting/rule/{id}', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/disable.test.ts b/x-pack/plugins/alerting/server/routes/legacy/disable.test.ts index 1c8ee110aca94..13fec185429ed 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/disable.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/disable.test.ts @@ -12,6 +12,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('disableAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('disables an alert', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - disableAlertRoute(router, licenseState); + disableAlertRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -69,7 +72,7 @@ describe('disableAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - disableAlertRoute(router, licenseState, undefined, true); + disableAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -81,7 +84,7 @@ describe('disableAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - disableAlertRoute(router, licenseState); + disableAlertRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -103,7 +106,7 @@ describe('disableAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - disableAlertRoute(router, licenseState, mockUsageCounter); + disableAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: '1' } }, [ 'ok', @@ -111,4 +114,30 @@ describe('disableAlertRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('disable', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + disableAlertRoute(router, licenseState, docLinks); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{id}/_disable", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/disable.ts b/x-pack/plugins/alerting/server/routes/legacy/disable.ts index 0c6f3cf062a0c..1d2293b698e42 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/disable.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/disable.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -21,6 +22,7 @@ const paramSchema = schema.object({ export const disableAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -34,8 +36,15 @@ export const disableAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Disable an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{id}/_disable', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/enable.test.ts b/x-pack/plugins/alerting/server/routes/legacy/enable.test.ts index d2ed24cc3fa15..88df304ea07c0 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/enable.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/enable.test.ts @@ -12,6 +12,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('enableAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('enables an alert', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - enableAlertRoute(router, licenseState); + enableAlertRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -69,7 +72,7 @@ describe('enableAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - enableAlertRoute(router, licenseState, undefined, true); + enableAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -81,7 +84,7 @@ describe('enableAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - enableAlertRoute(router, licenseState); + enableAlertRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -103,7 +106,7 @@ describe('enableAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - enableAlertRoute(router, licenseState, mockUsageCounter); + enableAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: '1' } }, [ 'ok', @@ -111,4 +114,30 @@ describe('enableAlertRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('enable', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + enableAlertRoute(router, licenseState, docLinks, undefined, true); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{id}/_enable", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/enable.ts b/x-pack/plugins/alerting/server/routes/legacy/enable.ts index d52eaa784f670..8f680a23f89eb 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/enable.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/enable.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -22,6 +23,7 @@ const paramSchema = schema.object({ export const enableAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -35,8 +37,15 @@ export const enableAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Enable an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{id}/_enable', + }, + }, }, }, handleDisabledApiKeysError( diff --git a/x-pack/plugins/alerting/server/routes/legacy/find.test.ts b/x-pack/plugins/alerting/server/routes/legacy/find.test.ts index 0b8584be43da7..646f18fa072ea 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/find.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/find.test.ts @@ -15,6 +15,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; import { trackLegacyTerminology } from '../lib/track_legacy_terminology'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -35,11 +36,13 @@ beforeEach(() => { }); describe('findAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('finds alerts with proper parameters', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - findAlertRoute(router, licenseState); + findAlertRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -100,7 +103,7 @@ describe('findAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - findAlertRoute(router, licenseState, undefined, true); + findAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.get.mock.calls[0]; @@ -112,7 +115,7 @@ describe('findAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - findAlertRoute(router, licenseState); + findAlertRoute(router, licenseState, docLinks); const [, handler] = router.get.mock.calls[0]; @@ -147,7 +150,7 @@ describe('findAlertRoute', () => { throw new Error('OMG'); }); - findAlertRoute(router, licenseState); + findAlertRoute(router, licenseState, docLinks); const [, handler] = router.get.mock.calls[0]; @@ -173,7 +176,7 @@ describe('findAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - findAlertRoute(router, licenseState, mockUsageCounter); + findAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; const findResult = { page: 1, @@ -195,7 +198,7 @@ describe('findAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - findAlertRoute(router, licenseState, mockUsageCounter); + findAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; const findResult = { @@ -232,7 +235,7 @@ describe('findAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - findAlertRoute(router, licenseState, mockUsageCounter); + findAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; const findResult = { page: 1, @@ -263,7 +266,7 @@ describe('findAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - findAlertRoute(router, licenseState); + findAlertRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -407,4 +410,30 @@ describe('findAlertRoute', () => { body: omit(findResult, 'data[0].systemActions'), }); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + findAlertRoute(router, licenseState, docLinks); + + const [config] = router.get.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "GET", + "newApiPath": "/api/alerting/rules/_find", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/find.ts b/x-pack/plugins/alerting/server/routes/legacy/find.ts index fa309ae51f2e4..ef4f8a45bcc0f 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/find.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/find.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; import { estypes } from '@elastic/elasticsearch'; import { KueryNode } from '@kbn/es-query'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; @@ -64,6 +65,7 @@ const querySchema = schema.object({ export const findAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -79,8 +81,15 @@ export const findAlertRoute = ( tags: ['oas-tag:alerting'], description: 'Gets a paginated set of alerts. Alert `params` are stored as a flattened field type and analyzed as keywords. As alerts change in Kibana, the results on each page of the response also change. Use the find API for traditional paginated results, but avoid using it to export large amounts of data.', - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'GET', + newApiPath: '/api/alerting/rules/_find', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/get.test.ts b/x-pack/plugins/alerting/server/routes/legacy/get.test.ts index f27210c773878..ca8154fc7adae 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get.test.ts @@ -14,6 +14,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { Rule, RuleSystemAction } from '../../../common'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -29,6 +30,7 @@ beforeEach(() => { }); describe('getAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); const mockedAlert: Rule<{ bar: true; }> = { @@ -82,7 +84,7 @@ describe('getAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertRoute(router, licenseState); + getAlertRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; expect(config.path).toMatchInlineSnapshot(`"/api/alerts/alert/{id}"`); @@ -111,7 +113,7 @@ describe('getAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertRoute(router, licenseState, undefined, true); + getAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.get.mock.calls[0]; expect(config.path).toMatchInlineSnapshot(`"/api/alerts/alert/{id}"`); @@ -122,7 +124,7 @@ describe('getAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertRoute(router, licenseState); + getAlertRoute(router, licenseState, docLinks); const [, handler] = router.get.mock.calls[0]; @@ -149,7 +151,7 @@ describe('getAlertRoute', () => { throw new Error('OMG'); }); - getAlertRoute(router, licenseState); + getAlertRoute(router, licenseState, docLinks); const [, handler] = router.get.mock.calls[0]; @@ -174,7 +176,7 @@ describe('getAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - getAlertRoute(router, licenseState, mockUsageCounter); + getAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; rulesClient.get.mockResolvedValueOnce(mockedAlert); @@ -190,7 +192,7 @@ describe('getAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertRoute(router, licenseState); + getAlertRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; expect(config.path).toMatchInlineSnapshot(`"/api/alerts/alert/{id}"`); @@ -213,4 +215,29 @@ describe('getAlertRoute', () => { body: mockedAlert, }); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + getAlertRoute(router, licenseState, docLinks); + const [config] = router.get.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "GET", + "newApiPath": "/api/alerting/rule/{id}", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/get.ts b/x-pack/plugins/alerting/server/routes/legacy/get.ts index e5eff52bf02d6..08ecd410adc1f 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; import { LEGACY_BASE_ALERT_API_PATH } from '../../../common'; @@ -20,6 +21,7 @@ const paramSchema = schema.object({ export const getAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -33,8 +35,15 @@ export const getAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Get an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'GET', + newApiPath: '/api/alerting/rule/{id}', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.test.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.test.ts index 4ecc085c3bb40..cc3deaad9af99 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.test.ts @@ -14,6 +14,7 @@ import { rulesClientMock } from '../../rules_client.mock'; import { AlertSummary } from '../../types'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -29,6 +30,7 @@ beforeEach(() => { }); describe('getAlertInstanceSummaryRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); const dateString = new Date().toISOString(); const mockedAlertInstanceSummary: AlertSummary = { id: '', @@ -55,7 +57,7 @@ describe('getAlertInstanceSummaryRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertInstanceSummaryRoute(router, licenseState); + getAlertInstanceSummaryRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -94,7 +96,7 @@ describe('getAlertInstanceSummaryRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertInstanceSummaryRoute(router, licenseState, undefined, true); + getAlertInstanceSummaryRoute(router, licenseState, docLinks, undefined, true); const [config] = router.get.mock.calls[0]; @@ -106,7 +108,7 @@ describe('getAlertInstanceSummaryRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertInstanceSummaryRoute(router, licenseState); + getAlertInstanceSummaryRoute(router, licenseState, docLinks); const [, handler] = router.get.mock.calls[0]; @@ -136,7 +138,7 @@ describe('getAlertInstanceSummaryRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - getAlertInstanceSummaryRoute(router, licenseState, mockUsageCounter); + getAlertInstanceSummaryRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; rulesClient.getAlertSummary.mockResolvedValueOnce(mockedAlertInstanceSummary); @@ -148,4 +150,28 @@ describe('getAlertInstanceSummaryRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('instanceSummary', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + getAlertInstanceSummaryRoute(router, licenseState, docLinks); + + const [config] = router.get.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "type": "remove", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts index 58a75dd68dce7..58ab6a5446756 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_instance_summary.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -30,6 +31,7 @@ const rewriteBodyRes = ({ ruleTypeId, alerts, ...rest }: AlertSummary) => ({ export const getAlertInstanceSummaryRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -44,8 +46,13 @@ export const getAlertInstanceSummaryRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Get an alert summary', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'remove', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.test.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.test.ts index f8f1d4caeed9f..ca79291b23dbc 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.test.ts @@ -13,6 +13,7 @@ import { SavedObjectsErrorHelpers } from '@kbn/core/server'; import { rulesClientMock } from '../../rules_client.mock'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; import { RULE_SAVED_OBJECT_TYPE } from '../../saved_objects'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -28,6 +29,7 @@ beforeEach(() => { }); describe('getAlertStateRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); const mockedAlertState = { alertTypeState: { some: 'value', @@ -50,7 +52,7 @@ describe('getAlertStateRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertStateRoute(router, licenseState); + getAlertStateRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -87,7 +89,7 @@ describe('getAlertStateRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertStateRoute(router, licenseState, undefined, true); + getAlertStateRoute(router, licenseState, docLinks, undefined, true); const [config] = router.get.mock.calls[0]; @@ -99,7 +101,7 @@ describe('getAlertStateRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertStateRoute(router, licenseState); + getAlertStateRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -135,7 +137,7 @@ describe('getAlertStateRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - getAlertStateRoute(router, licenseState); + getAlertStateRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -175,7 +177,7 @@ describe('getAlertStateRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - getAlertStateRoute(router, licenseState, mockUsageCounter); + getAlertStateRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: '1' } }, [ 'ok', @@ -183,4 +185,28 @@ describe('getAlertStateRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('state', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + getAlertStateRoute(router, licenseState, docLinks); + + const [config] = router.get.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "type": "remove", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts index e952ef8719667..ad3d9591c92c4 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/get_alert_state.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -20,6 +21,7 @@ const paramSchema = schema.object({ export const getAlertStateRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -33,8 +35,13 @@ export const getAlertStateRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Get the state of an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'remove', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/health.test.ts b/x-pack/plugins/alerting/server/routes/legacy/health.test.ts index 6c0b3ae6f67a4..64c994f9936b3 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/health.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/health.test.ts @@ -16,6 +16,7 @@ import { RecoveredActionGroup } from '../../types'; import { alertsMock } from '../../mocks'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; import { RegistryAlertTypeWithAuth } from '../../authorization'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -80,13 +81,15 @@ beforeEach(() => { }); describe('healthRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('registers the route', async () => { rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); const router = httpServiceMock.createRouter(); const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [config] = router.get.mock.calls[0]; @@ -100,7 +103,7 @@ describe('healthRoute', () => { const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); - healthRoute(router, licenseState, encryptedSavedObjects, undefined, true); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks, undefined, true); const [config] = router.get.mock.calls[0]; @@ -114,7 +117,7 @@ describe('healthRoute', () => { const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: false }); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( @@ -140,7 +143,7 @@ describe('healthRoute', () => { const licenseState = licenseStateMock.create(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: false }); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( @@ -198,7 +201,7 @@ describe('healthRoute', () => { const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); licenseState.getIsSecurityEnabled.mockReturnValueOnce(null); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( @@ -256,7 +259,7 @@ describe('healthRoute', () => { const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); licenseState.getIsSecurityEnabled.mockReturnValueOnce(false); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( @@ -314,7 +317,7 @@ describe('healthRoute', () => { const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); licenseState.getIsSecurityEnabled.mockReturnValueOnce(true); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( @@ -372,7 +375,7 @@ describe('healthRoute', () => { const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); licenseState.getIsSecurityEnabled.mockReturnValueOnce(true); - healthRoute(router, licenseState, encryptedSavedObjects); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( @@ -431,7 +434,7 @@ describe('healthRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - healthRoute(router, licenseState, encryptedSavedObjects, mockUsageCounter); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: { id: '1' } }, [ 'ok', @@ -439,4 +442,32 @@ describe('healthRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('health', mockUsageCounter); }); + + it('should be deprecated', async () => { + rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(ruleTypes)); + const router = httpServiceMock.createRouter(); + + const licenseState = licenseStateMock.create(); + const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks); + + const [config] = router.get.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "GET", + "newApiPath": "/api/alerting/rule/_health", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/health.ts b/x-pack/plugins/alerting/server/routes/legacy/health.ts index 8f67767941fd2..223859124072b 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/health.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/health.ts @@ -7,6 +7,7 @@ import { UsageCounter } from '@kbn/usage-collection-plugin/server'; import { EncryptedSavedObjectsPluginSetup } from '@kbn/encrypted-saved-objects-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -18,6 +19,7 @@ export function healthRoute( router: AlertingRouter, licenseState: ILicenseState, encryptedSavedObjects: EncryptedSavedObjectsPluginSetup, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) { @@ -29,8 +31,15 @@ export function healthRoute( access: isServerless ? 'internal' : 'public', summary: 'Get the alerting framework health', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'GET', + newApiPath: '/api/alerting/rule/_health', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/index.ts b/x-pack/plugins/alerting/server/routes/legacy/index.ts index 99220106d5ac1..e9551d938e6c1 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/index.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/index.ts @@ -24,22 +24,23 @@ import { healthRoute } from './health'; import { RouteOptions } from '..'; export function defineLegacyRoutes(opts: RouteOptions) { - const { router, licenseState, encryptedSavedObjects, usageCounter, isServerless } = opts; + const { router, licenseState, encryptedSavedObjects, usageCounter, isServerless, docLinks } = + opts; createAlertRoute(opts); - deleteAlertRoute(router, licenseState, usageCounter, isServerless); - findAlertRoute(router, licenseState, usageCounter, isServerless); - getAlertRoute(router, licenseState, usageCounter, isServerless); - getAlertStateRoute(router, licenseState, usageCounter, isServerless); - getAlertInstanceSummaryRoute(router, licenseState, usageCounter, isServerless); - listAlertTypesRoute(router, licenseState, usageCounter, isServerless); - updateAlertRoute(router, licenseState, usageCounter, isServerless); - enableAlertRoute(router, licenseState, usageCounter, isServerless); - disableAlertRoute(router, licenseState, usageCounter, isServerless); - updateApiKeyRoute(router, licenseState, usageCounter, isServerless); - muteAllAlertRoute(router, licenseState, usageCounter, isServerless); - unmuteAllAlertRoute(router, licenseState, usageCounter, isServerless); - muteAlertInstanceRoute(router, licenseState, usageCounter, isServerless); - unmuteAlertInstanceRoute(router, licenseState, usageCounter, isServerless); - healthRoute(router, licenseState, encryptedSavedObjects, usageCounter, isServerless); + deleteAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + findAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + getAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + getAlertStateRoute(router, licenseState, docLinks, usageCounter, isServerless); + getAlertInstanceSummaryRoute(router, licenseState, docLinks, usageCounter, isServerless); + listAlertTypesRoute(router, licenseState, docLinks, usageCounter, isServerless); + updateAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + enableAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + disableAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + updateApiKeyRoute(router, licenseState, docLinks, usageCounter, isServerless); + muteAllAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + unmuteAllAlertRoute(router, licenseState, docLinks, usageCounter, isServerless); + muteAlertInstanceRoute(router, licenseState, docLinks, usageCounter, isServerless); + unmuteAlertInstanceRoute(router, licenseState, docLinks, usageCounter, isServerless); + healthRoute(router, licenseState, encryptedSavedObjects, docLinks, usageCounter, isServerless); } diff --git a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts index 80298f7fd288e..3c1be0410f586 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.test.ts @@ -15,6 +15,7 @@ import { rulesClientMock } from '../../rules_client.mock'; import { RecoveredActionGroup } from '../../../common'; import { RegistryAlertTypeWithAuth } from '../../authorization'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -31,11 +32,12 @@ beforeEach(() => { }); describe('listAlertTypesRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); it('lists alert types with proper parameters', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - listAlertTypesRoute(router, licenseState); + listAlertTypesRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -119,7 +121,7 @@ describe('listAlertTypesRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - listAlertTypesRoute(router, licenseState, undefined, true); + listAlertTypesRoute(router, licenseState, docLinks, undefined, true); const [config] = router.get.mock.calls[0]; @@ -131,7 +133,7 @@ describe('listAlertTypesRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - listAlertTypesRoute(router, licenseState); + listAlertTypesRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -188,7 +190,7 @@ describe('listAlertTypesRoute', () => { throw new Error('OMG'); }); - listAlertTypesRoute(router, licenseState); + listAlertTypesRoute(router, licenseState, docLinks); const [config, handler] = router.get.mock.calls[0]; @@ -245,7 +247,7 @@ describe('listAlertTypesRoute', () => { rulesClient.listRuleTypes.mockResolvedValueOnce(new Set([])); - listAlertTypesRoute(router, licenseState, mockUsageCounter); + listAlertTypesRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.get.mock.calls[0]; const [context, req, res] = mockHandlerArguments( { rulesClient }, @@ -255,4 +257,30 @@ describe('listAlertTypesRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('listAlertTypes', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + listAlertTypesRoute(router, licenseState, docLinks); + + const [config] = router.get.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "GET", + "newApiPath": "/api/alerting/rule_types", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts index 35d6a7efeeee3..ad0f470ae9235 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/list_alert_types.ts @@ -5,6 +5,7 @@ * 2.0. */ import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -14,6 +15,7 @@ import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; export const listAlertTypesRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -25,8 +27,15 @@ export const listAlertTypesRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Get the alert types', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'GET', + newApiPath: '/api/alerting/rule_types', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_all.test.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_all.test.ts index 9a9ea27ba6751..d80cf415283d0 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_all.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_all.test.ts @@ -13,6 +13,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('muteAllAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('mute an alert', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - muteAllAlertRoute(router, licenseState); + muteAllAlertRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -69,7 +72,7 @@ describe('muteAllAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - muteAllAlertRoute(router, licenseState, undefined, true); + muteAllAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -81,7 +84,7 @@ describe('muteAllAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - muteAllAlertRoute(router, licenseState); + muteAllAlertRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -103,7 +106,7 @@ describe('muteAllAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - muteAllAlertRoute(router, licenseState, mockUsageCounter); + muteAllAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ 'ok', @@ -111,4 +114,30 @@ describe('muteAllAlertRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('muteAll', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + muteAllAlertRoute(router, licenseState, docLinks, undefined, true); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{id}/_mute_all", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts index 5c4fc1542ef5b..f7cb03a81dcb2 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_all.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -21,6 +22,7 @@ const paramSchema = schema.object({ export const muteAllAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -34,8 +36,15 @@ export const muteAllAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Mute all alert instances', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{id}/_mute_all', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.test.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.test.ts index 7a142e4e94854..08e03a6d053ef 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.test.ts @@ -13,6 +13,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('muteAlertInstanceRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('mutes an alert instance', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - muteAlertInstanceRoute(router, licenseState); + muteAlertInstanceRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -73,7 +76,7 @@ describe('muteAlertInstanceRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - muteAlertInstanceRoute(router, licenseState, undefined, true); + muteAlertInstanceRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -87,7 +90,7 @@ describe('muteAlertInstanceRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - muteAlertInstanceRoute(router, licenseState); + muteAlertInstanceRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -111,7 +114,7 @@ describe('muteAlertInstanceRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - muteAlertInstanceRoute(router, licenseState, mockUsageCounter); + muteAlertInstanceRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ 'ok', @@ -119,4 +122,30 @@ describe('muteAlertInstanceRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('muteInstance', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + muteAlertInstanceRoute(router, licenseState, docLinks); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts index ab0b52d41de29..a8e70ba707b78 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/mute_instance.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -24,6 +25,7 @@ const paramSchema = schema.object({ export const muteAlertInstanceRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -37,8 +39,15 @@ export const muteAlertInstanceRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Mute an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{rule_id}/alert/{alert_id}/_mute', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.test.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.test.ts index 6a88335ec98ae..5ae337e6a3f51 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.test.ts @@ -13,6 +13,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('unmuteAllAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('unmutes an alert', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - unmuteAllAlertRoute(router, licenseState); + unmuteAllAlertRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -69,7 +72,7 @@ describe('unmuteAllAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - unmuteAllAlertRoute(router, licenseState, undefined, true); + unmuteAllAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -81,7 +84,7 @@ describe('unmuteAllAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - unmuteAllAlertRoute(router, licenseState); + unmuteAllAlertRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -103,7 +106,7 @@ describe('unmuteAllAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - unmuteAllAlertRoute(router, licenseState, mockUsageCounter); + unmuteAllAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ 'ok', @@ -111,4 +114,30 @@ describe('unmuteAllAlertRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('unmuteAll', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + unmuteAllAlertRoute(router, licenseState, docLinks); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{id}/_unmute_all", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts index 0681e7d2cf01e..bde7bea430fa5 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_all.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -21,6 +22,7 @@ const paramSchema = schema.object({ export const unmuteAllAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -34,8 +36,15 @@ export const unmuteAllAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Unmute all alert instances', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{id}/_unmute_all', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.test.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.test.ts index b04f376c38ca1..b6fba61aaff8a 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.test.ts @@ -13,6 +13,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('unmuteAlertInstanceRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('unmutes an alert instance', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - unmuteAlertInstanceRoute(router, licenseState); + unmuteAlertInstanceRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -73,7 +76,7 @@ describe('unmuteAlertInstanceRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - unmuteAlertInstanceRoute(router, licenseState, undefined, true); + unmuteAlertInstanceRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -87,7 +90,7 @@ describe('unmuteAlertInstanceRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - unmuteAlertInstanceRoute(router, licenseState); + unmuteAlertInstanceRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -111,7 +114,7 @@ describe('unmuteAlertInstanceRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - unmuteAlertInstanceRoute(router, licenseState, mockUsageCounter); + unmuteAlertInstanceRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ 'ok', @@ -119,4 +122,30 @@ describe('unmuteAlertInstanceRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('unmuteInstance', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + unmuteAlertInstanceRoute(router, licenseState, docLinks); + + const [config] = router.post.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts index 1101a2b5092e7..91774b0df7ac8 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/unmute_instance.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -22,6 +23,7 @@ const paramSchema = schema.object({ export const unmuteAlertInstanceRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -35,8 +37,15 @@ export const unmuteAlertInstanceRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Unmute an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{rule_id}/alert/{alert_id}/_unmute', + }, + }, }, }, router.handleLegacyErrors(async function (context, req, res) { diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.test.ts b/x-pack/plugins/alerting/server/routes/legacy/update.test.ts index fc4a814c26a27..7aaee90b805c5 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.test.ts @@ -15,6 +15,7 @@ import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { RuleNotifyWhen, SanitizedRule, RuleSystemAction } from '../../../common'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -30,6 +31,7 @@ beforeEach(() => { }); describe('updateAlertRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); const mockedResponse = { id: '1', alertTypeId: '1', @@ -66,7 +68,7 @@ describe('updateAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateAlertRoute(router, licenseState); + updateAlertRoute(router, licenseState, docLinks); const [config, handler] = router.put.mock.calls[0]; @@ -145,7 +147,7 @@ describe('updateAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateAlertRoute(router, licenseState, undefined, true); + updateAlertRoute(router, licenseState, docLinks, undefined, true); const [config] = router.put.mock.calls[0]; @@ -157,7 +159,7 @@ describe('updateAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateAlertRoute(router, licenseState); + updateAlertRoute(router, licenseState, docLinks); const [, handler] = router.put.mock.calls[0]; @@ -204,7 +206,7 @@ describe('updateAlertRoute', () => { throw new Error('OMG'); }); - updateAlertRoute(router, licenseState); + updateAlertRoute(router, licenseState, docLinks); const [, handler] = router.put.mock.calls[0]; @@ -247,7 +249,7 @@ describe('updateAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateAlertRoute(router, licenseState); + updateAlertRoute(router, licenseState, docLinks); const [, handler] = router.put.mock.calls[0]; @@ -269,7 +271,7 @@ describe('updateAlertRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - updateAlertRoute(router, licenseState, mockUsageCounter); + updateAlertRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.put.mock.calls[0]; rulesClient.update.mockResolvedValueOnce(mockedResponse as unknown as SanitizedRule); const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ @@ -283,7 +285,7 @@ describe('updateAlertRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateAlertRoute(router, licenseState); + updateAlertRoute(router, licenseState, docLinks); const [config, handler] = router.put.mock.calls[0]; @@ -359,4 +361,30 @@ describe('updateAlertRoute', () => { expect(res.ok).toHaveBeenCalled(); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + updateAlertRoute(router, licenseState, docLinks); + + const [config] = router.put.mock.calls[0]; + + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "PUT", + "newApiPath": "/api/alerting/rule/rule/{id}", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.ts b/x-pack/plugins/alerting/server/routes/legacy/update.ts index 01adeb5c634dc..04f54738e9608 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -47,6 +48,7 @@ const bodySchema = schema.object({ export const updateAlertRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -61,8 +63,15 @@ export const updateAlertRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Update an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'PUT', + newApiPath: '/api/alerting/rule/rule/{id}', + }, + }, }, }, handleDisabledApiKeysError( diff --git a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.test.ts b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.test.ts index cd5b6639ad004..cb2817af2ed58 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.test.ts @@ -13,6 +13,7 @@ import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); jest.mock('../../lib/license_api_access', () => ({ @@ -28,11 +29,13 @@ beforeEach(() => { }); describe('updateApiKeyRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); + it('updates api key for an alert', async () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateApiKeyRoute(router, licenseState); + updateApiKeyRoute(router, licenseState, docLinks); const [config, handler] = router.post.mock.calls[0]; @@ -69,7 +72,7 @@ describe('updateApiKeyRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateApiKeyRoute(router, licenseState, undefined, true); + updateApiKeyRoute(router, licenseState, docLinks, undefined, true); const [config] = router.post.mock.calls[0]; @@ -81,7 +84,7 @@ describe('updateApiKeyRoute', () => { const licenseState = licenseStateMock.create(); const router = httpServiceMock.createRouter(); - updateApiKeyRoute(router, licenseState); + updateApiKeyRoute(router, licenseState, docLinks); const [, handler] = router.post.mock.calls[0]; @@ -105,7 +108,7 @@ describe('updateApiKeyRoute', () => { const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); - updateApiKeyRoute(router, licenseState, mockUsageCounter); + updateApiKeyRoute(router, licenseState, docLinks, mockUsageCounter); const [, handler] = router.post.mock.calls[0]; const [context, req, res] = mockHandlerArguments({ rulesClient }, { params: {}, body: {} }, [ 'ok', @@ -113,4 +116,29 @@ describe('updateApiKeyRoute', () => { await handler(context, req, res); expect(trackLegacyRouteUsage).toHaveBeenCalledWith('updateApiKey', mockUsageCounter); }); + + it('should be deprecated', async () => { + const licenseState = licenseStateMock.create(); + const router = httpServiceMock.createRouter(); + + updateApiKeyRoute(router, licenseState, docLinks); + + const [config] = router.post.mock.calls[0]; + expect(config.options?.deprecated).toMatchInlineSnapshot( + { + documentationUrl: expect.stringMatching(/#breaking-201550$/), + }, + ` + Object { + "documentationUrl": StringMatching /#breaking-201550\\$/, + "reason": Object { + "newApiMethod": "POST", + "newApiPath": "/api/alerting/rule/{id}/_update_api_key", + "type": "migrate", + }, + "severity": "warning", + } + ` + ); + }); }); diff --git a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts index 30c51d3cdcf5c..0a3b62ebed368 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update_api_key.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { UsageCounter } from '@kbn/usage-collection-plugin/server'; +import { DocLinksServiceSetup } from '@kbn/core/server'; import type { AlertingRouter } from '../../types'; import { ILicenseState } from '../../lib/license_state'; import { verifyApiAccess } from '../../lib/license_api_access'; @@ -22,6 +23,7 @@ const paramSchema = schema.object({ export const updateApiKeyRoute = ( router: AlertingRouter, licenseState: ILicenseState, + docLinks: DocLinksServiceSetup, usageCounter?: UsageCounter, isServerless?: boolean ) => { @@ -35,8 +37,15 @@ export const updateApiKeyRoute = ( access: isServerless ? 'internal' : 'public', summary: 'Update the API key for an alert', tags: ['oas-tag:alerting'], - // @ts-expect-error TODO(https://github.com/elastic/kibana/issues/196095): Replace {RouteDeprecationInfo} - deprecated: true, + deprecated: { + documentationUrl: docLinks.links.alerting.legacyRuleApiDeprecations, + severity: 'warning', + reason: { + type: 'migrate', + newApiMethod: 'POST', + newApiPath: '/api/alerting/rule/{id}/_update_api_key', + }, + }, }, }, handleDisabledApiKeysError( diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts index cab3956161613..f778b09854abd 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/create_rule_route.test.ts @@ -18,6 +18,7 @@ import { RuleAction, RuleSystemAction, SanitizedRule } from '../../../../types'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { usageCountersServiceMock } from '@kbn/usage-collection-plugin/server/usage_counters/usage_counters_service.mock'; import { actionsClientMock } from '@kbn/actions-plugin/server/mocks'; +import { docLinksServiceMock } from '@kbn/core/server/mocks'; const rulesClient = rulesClientMock.create(); @@ -30,6 +31,7 @@ beforeEach(() => { }); describe('createRuleRoute', () => { + const docLinks = docLinksServiceMock.createSetupContract(); const createdAt = new Date(); const updatedAt = new Date(); const action: RuleAction = { @@ -151,6 +153,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -264,6 +267,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -381,6 +385,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -499,6 +504,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [config, handler] = router.post.mock.calls[0]; @@ -606,7 +612,7 @@ describe('createRuleRoute', () => { const router = httpServiceMock.createRouter(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); - createRuleRoute({ router, licenseState, encryptedSavedObjects }); + createRuleRoute({ router, licenseState, encryptedSavedObjects, docLinks }); const [, handler] = router.post.mock.calls[0]; @@ -628,7 +634,7 @@ describe('createRuleRoute', () => { throw new Error('OMG'); }); - createRuleRoute({ router, licenseState, encryptedSavedObjects }); + createRuleRoute({ router, licenseState, encryptedSavedObjects, docLinks }); const [, handler] = router.post.mock.calls[0]; @@ -646,7 +652,7 @@ describe('createRuleRoute', () => { const router = httpServiceMock.createRouter(); const encryptedSavedObjects = encryptedSavedObjectsMock.createSetup({ canEncrypt: true }); - createRuleRoute({ router, licenseState, encryptedSavedObjects }); + createRuleRoute({ router, licenseState, encryptedSavedObjects, docLinks }); const [, handler] = router.post.mock.calls[0]; @@ -677,6 +683,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [_, handler] = router.post.mock.calls[0]; @@ -759,6 +766,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [_, handler] = router.post.mock.calls[0]; @@ -815,6 +823,7 @@ describe('createRuleRoute', () => { licenseState, encryptedSavedObjects, usageCounter: mockUsageCounter, + docLinks, }); const [_, handler] = router.post.mock.calls[0];