mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Response Ops][Rules] Version Get Rule Types API (#195361)](https://github.com/elastic/kibana/pull/195361) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Julian Gernun","email":"17549662+jcger@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-14T15:46:17Z","message":"[Response Ops][Rules] Version Get Rule Types API (#195361)\n\n## Summary\r\n\r\n`GET /api/alerting/rule_types` item in\r\nhttps://github.com/elastic/kibana/issues/195181","sha":"512a31d7a1e42139c2e1b26e961b2226ace3836d","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:ResponseOps","v9.0.0","backport:prev-minor","v8.16.0"],"title":"[Response Ops][Rules] Version Get Rule Types API","number":195361,"url":"https://github.com/elastic/kibana/pull/195361","mergeCommit":{"message":"[Response Ops][Rules] Version Get Rule Types API (#195361)\n\n## Summary\r\n\r\n`GET /api/alerting/rule_types` item in\r\nhttps://github.com/elastic/kibana/issues/195181","sha":"512a31d7a1e42139c2e1b26e961b2226ace3836d"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/195361","number":195361,"mergeCommit":{"message":"[Response Ops][Rules] Version Get Rule Types API (#195361)\n\n## Summary\r\n\r\n`GET /api/alerting/rule_types` item in\r\nhttps://github.com/elastic/kibana/issues/195181","sha":"512a31d7a1e42139c2e1b26e961b2226ace3836d"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Julian Gernun <17549662+jcger@users.noreply.github.com>
This commit is contained in:
parent
d0f095f2ec
commit
c156cb3816
16 changed files with 248 additions and 87 deletions
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { typesRulesResponseSchema, typesRulesResponseBodySchema } from './schemas/latest';
|
||||
export type { TypesRulesResponse, TypesRulesResponseBody } from './types/latest';
|
||||
|
||||
export {
|
||||
typesRulesResponseSchema as typesRulesResponseSchemaV1,
|
||||
typesRulesResponseBodySchema as typesRulesResponseBodySchemaV1,
|
||||
} from './schemas/v1';
|
||||
export type {
|
||||
TypesRulesResponse as TypesRulesResponseV1,
|
||||
TypesRulesResponseBody as TypesRulesResponseBodyV1,
|
||||
} from './types/v1';
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './v1';
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
const actionVariableSchema = schema.object({
|
||||
name: schema.string(),
|
||||
description: schema.string(),
|
||||
usesPublicBaseUrl: schema.maybe(schema.boolean()),
|
||||
});
|
||||
|
||||
const actionGroupSchema = schema.object({
|
||||
id: schema.string(),
|
||||
name: schema.string(),
|
||||
});
|
||||
|
||||
export const typesRulesResponseBodySchema = schema.arrayOf(
|
||||
schema.object({
|
||||
action_groups: schema.maybe(schema.arrayOf(actionGroupSchema)),
|
||||
action_variables: schema.maybe(
|
||||
schema.object({
|
||||
context: schema.maybe(schema.arrayOf(actionVariableSchema)),
|
||||
state: schema.maybe(schema.arrayOf(actionVariableSchema)),
|
||||
params: schema.maybe(schema.arrayOf(actionVariableSchema)),
|
||||
})
|
||||
),
|
||||
alerts: schema.maybe(
|
||||
schema.object({
|
||||
context: schema.string(),
|
||||
mappings: schema.maybe(
|
||||
schema.object({
|
||||
dynamic: schema.maybe(schema.oneOf([schema.literal(false), schema.literal('strict')])),
|
||||
fieldMap: schema.recordOf(schema.string(), schema.any()),
|
||||
shouldWrite: schema.maybe(schema.boolean()),
|
||||
useEcs: schema.maybe(schema.boolean()),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
authorized_consumers: schema.recordOf(
|
||||
schema.string(),
|
||||
schema.object({ read: schema.boolean(), all: schema.boolean() })
|
||||
),
|
||||
category: schema.string(),
|
||||
default_action_group_id: schema.string(),
|
||||
default_schedule_interval: schema.maybe(schema.string()),
|
||||
does_set_recovery_context: schema.maybe(schema.boolean()),
|
||||
enabled_in_license: schema.boolean(),
|
||||
fieldsForAAD: schema.maybe(schema.arrayOf(schema.string())),
|
||||
has_alerts_mappings: schema.boolean(),
|
||||
has_fields_for_a_a_d: schema.boolean(),
|
||||
id: schema.string(),
|
||||
is_exportable: schema.boolean(),
|
||||
minimum_license_required: schema.oneOf([
|
||||
schema.literal('basic'),
|
||||
schema.literal('gold'),
|
||||
schema.literal('platinum'),
|
||||
schema.literal('standard'),
|
||||
schema.literal('enterprise'),
|
||||
schema.literal('trial'),
|
||||
]),
|
||||
name: schema.string(),
|
||||
producer: schema.string(),
|
||||
recovery_action_group: actionGroupSchema,
|
||||
rule_task_timeout: schema.maybe(schema.string()),
|
||||
})
|
||||
);
|
||||
|
||||
export const typesRulesResponseSchema = schema.object({
|
||||
body: typesRulesResponseBodySchema,
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './v1';
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { TypeOf } from '@kbn/config-schema';
|
||||
|
||||
import { typesRulesResponseSchemaV1, typesRulesResponseBodySchemaV1 } from '..';
|
||||
|
||||
export type TypesRulesResponse = TypeOf<typeof typesRulesResponseSchemaV1>;
|
||||
export type TypesRulesResponseBody = TypeOf<typeof typesRulesResponseBodySchemaV1>;
|
|
@ -5,8 +5,12 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { WriteOperations, ReadOperations, AlertingAuthorizationEntity } from '../../authorization';
|
||||
import { RulesClientContext } from '../types';
|
||||
import {
|
||||
WriteOperations,
|
||||
ReadOperations,
|
||||
AlertingAuthorizationEntity,
|
||||
} from '../../../../authorization';
|
||||
import { RulesClientContext } from '../../../../rules_client/types';
|
||||
|
||||
export async function listRuleTypes(context: RulesClientContext) {
|
||||
return await context.authorization.filterByRuleTypeAuthorization(
|
|
@ -30,7 +30,7 @@ import { getRuleExecutionKPIRoute } from './get_rule_execution_kpi';
|
|||
import { getRuleStateRoute } from './get_rule_state';
|
||||
import { healthRoute } from './health';
|
||||
import { resolveRuleRoute } from './rule/apis/resolve';
|
||||
import { ruleTypesRoute } from './rule_types';
|
||||
import { ruleTypesRoute } from './rule/apis/list_types/rule_types';
|
||||
import { muteAllRuleRoute } from './rule/apis/mute_all/mute_all_rule';
|
||||
import { muteAlertRoute } from './rule/apis/mute_alert/mute_alert';
|
||||
import { unmuteAllRuleRoute } from './rule/apis/unmute_all';
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { ruleTypesRoute } from './rule_types';
|
|
@ -7,17 +7,17 @@
|
|||
|
||||
import { ruleTypesRoute } from './rule_types';
|
||||
import { httpServiceMock } from '@kbn/core/server/mocks';
|
||||
import { licenseStateMock } from '../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../lib/license_api_access';
|
||||
import { mockHandlerArguments } from './_mock_handler_arguments';
|
||||
import { rulesClientMock } from '../rules_client.mock';
|
||||
import { RecoveredActionGroup } from '../../common';
|
||||
import { RegistryAlertTypeWithAuth } from '../authorization';
|
||||
import { AsApiContract } from './lib';
|
||||
import { licenseStateMock } from '../../../../lib/license_state.mock';
|
||||
import { verifyApiAccess } from '../../../../lib/license_api_access';
|
||||
import { mockHandlerArguments } from '../../../_mock_handler_arguments';
|
||||
import { rulesClientMock } from '../../../../rules_client.mock';
|
||||
import { RecoveredActionGroup } from '../../../../../common';
|
||||
import { RegistryAlertTypeWithAuth } from '../../../../authorization';
|
||||
import { AsApiContract } from '../../../lib';
|
||||
|
||||
const rulesClient = rulesClientMock.create();
|
||||
|
||||
jest.mock('../lib/license_api_access', () => ({
|
||||
jest.mock('../../../../lib/license_api_access', () => ({
|
||||
verifyApiAccess: jest.fn(),
|
||||
}));
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { TypesRulesResponseBodyV1 } from '../../../../../common/routes/rule/apis/list_types';
|
||||
import { ILicenseState } from '../../../../lib';
|
||||
import { verifyAccessAndContext } from '../../../lib';
|
||||
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../../../../types';
|
||||
import { transformRuleTypesResponseV1 } from './transforms';
|
||||
|
||||
export const ruleTypesRoute = (
|
||||
router: IRouter<AlertingRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ALERTING_API_PATH}/rule_types`,
|
||||
options: {
|
||||
access: 'public',
|
||||
summary: `Get the rule types`,
|
||||
tags: ['oas-tag:alerting'],
|
||||
},
|
||||
validate: {},
|
||||
},
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const rulesClient = (await context.alerting).getRulesClient();
|
||||
const ruleTypes = await rulesClient.listRuleTypes();
|
||||
|
||||
const responseBody: TypesRulesResponseBodyV1 = transformRuleTypesResponseV1(ruleTypes);
|
||||
|
||||
return res.ok({
|
||||
body: responseBody,
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { transformRuleTypesResponse } from './transform_rule_types_response/latest';
|
||||
export { transformRuleTypesResponse as transformRuleTypesResponseV1 } from './transform_rule_types_response/v1';
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export * from './v1';
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { isBoolean } from 'lodash/fp';
|
||||
import { RegistryAlertTypeWithAuth } from '../../../../../../authorization';
|
||||
import type { TypesRulesResponseBodyV1 } from '../../../../../../../common/routes/rule/apis/list_types';
|
||||
|
||||
export const transformRuleTypesResponse = (
|
||||
ruleTypes: Set<RegistryAlertTypeWithAuth>
|
||||
): TypesRulesResponseBodyV1 => {
|
||||
return Array.from(ruleTypes).map((ruleType: RegistryAlertTypeWithAuth) => {
|
||||
return {
|
||||
...(ruleType.actionGroups ? { action_groups: ruleType.actionGroups } : {}),
|
||||
...(ruleType.actionVariables ? { action_variables: ruleType.actionVariables } : {}),
|
||||
...(ruleType.alerts ? { alerts: ruleType.alerts } : {}),
|
||||
authorized_consumers: ruleType.authorizedConsumers,
|
||||
category: ruleType.category,
|
||||
default_action_group_id: ruleType.defaultActionGroupId,
|
||||
...(ruleType.defaultScheduleInterval
|
||||
? { default_schedule_interval: ruleType.defaultScheduleInterval }
|
||||
: {}),
|
||||
...(isBoolean(ruleType.doesSetRecoveryContext)
|
||||
? { does_set_recovery_context: ruleType.doesSetRecoveryContext }
|
||||
: {}),
|
||||
enabled_in_license: ruleType.enabledInLicense,
|
||||
...(ruleType.fieldsForAAD ? { fieldsForAAD: ruleType.fieldsForAAD } : {}),
|
||||
has_alerts_mappings: ruleType.hasAlertsMappings,
|
||||
has_fields_for_a_a_d: ruleType.hasFieldsForAAD,
|
||||
id: ruleType.id,
|
||||
is_exportable: ruleType.isExportable,
|
||||
minimum_license_required: ruleType.minimumLicenseRequired,
|
||||
name: ruleType.name,
|
||||
producer: ruleType.producer,
|
||||
recovery_action_group: ruleType.recoveryActionGroup,
|
||||
...(ruleType.ruleTaskTimeout ? { rule_task_timeout: ruleType.ruleTaskTimeout } : {}),
|
||||
};
|
||||
});
|
||||
};
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IRouter } from '@kbn/core/server';
|
||||
import { ILicenseState } from '../lib';
|
||||
import { RegistryAlertTypeWithAuth } from '../authorization';
|
||||
import { verifyAccessAndContext } from './lib';
|
||||
import { AlertingRequestHandlerContext, BASE_ALERTING_API_PATH } from '../types';
|
||||
|
||||
const rewriteBodyRes = (results: RegistryAlertTypeWithAuth[]) => {
|
||||
return results.map(
|
||||
({
|
||||
enabledInLicense,
|
||||
recoveryActionGroup,
|
||||
actionGroups,
|
||||
defaultActionGroupId,
|
||||
minimumLicenseRequired,
|
||||
isExportable,
|
||||
ruleTaskTimeout,
|
||||
actionVariables,
|
||||
authorizedConsumers,
|
||||
defaultScheduleInterval,
|
||||
doesSetRecoveryContext,
|
||||
hasAlertsMappings,
|
||||
hasFieldsForAAD,
|
||||
validLegacyConsumers,
|
||||
...rest
|
||||
}: RegistryAlertTypeWithAuth) => ({
|
||||
...rest,
|
||||
enabled_in_license: enabledInLicense,
|
||||
recovery_action_group: recoveryActionGroup,
|
||||
action_groups: actionGroups,
|
||||
default_action_group_id: defaultActionGroupId,
|
||||
minimum_license_required: minimumLicenseRequired,
|
||||
is_exportable: isExportable,
|
||||
rule_task_timeout: ruleTaskTimeout,
|
||||
action_variables: actionVariables,
|
||||
authorized_consumers: authorizedConsumers,
|
||||
default_schedule_interval: defaultScheduleInterval,
|
||||
does_set_recovery_context: doesSetRecoveryContext,
|
||||
has_alerts_mappings: !!hasAlertsMappings,
|
||||
has_fields_for_a_a_d: !!hasFieldsForAAD,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
export const ruleTypesRoute = (
|
||||
router: IRouter<AlertingRequestHandlerContext>,
|
||||
licenseState: ILicenseState
|
||||
) => {
|
||||
router.get(
|
||||
{
|
||||
path: `${BASE_ALERTING_API_PATH}/rule_types`,
|
||||
options: {
|
||||
access: 'public',
|
||||
summary: `Get the rule types`,
|
||||
tags: ['oas-tag:alerting'],
|
||||
},
|
||||
validate: {},
|
||||
},
|
||||
router.handleLegacyErrors(
|
||||
verifyAccessAndContext(licenseState, async function (context, req, res) {
|
||||
const rulesClient = (await context.alerting).getRulesClient();
|
||||
const ruleTypes = Array.from(await rulesClient.listRuleTypes());
|
||||
return res.ok({
|
||||
body: rewriteBodyRes(ruleTypes),
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
};
|
|
@ -72,6 +72,7 @@ export interface RegistryRuleType
|
|||
| 'defaultScheduleInterval'
|
||||
| 'doesSetRecoveryContext'
|
||||
| 'fieldsForAAD'
|
||||
| 'alerts'
|
||||
> {
|
||||
id: string;
|
||||
enabledInLicense: boolean;
|
||||
|
|
|
@ -62,7 +62,7 @@ import { unmuteAll } from '../application/rule/methods/unmute_all';
|
|||
import { muteAll } from '../application/rule/methods/mute_all';
|
||||
import { unmuteInstance } from '../application/rule/methods/unmute_alert/unmute_instance';
|
||||
import { runSoon } from './methods/run_soon';
|
||||
import { listRuleTypes } from './methods/list_rule_types';
|
||||
import { listRuleTypes } from '../application/rule/methods/rule_types/rule_types';
|
||||
import { getScheduleFrequency } from '../application/rule/methods/get_schedule_frequency/get_schedule_frequency';
|
||||
import {
|
||||
bulkUntrackAlerts,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue