mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[ResponseOps][Rules] Adding rule.url variable (#145035)
This PR adds a new actions variable for linking back the stack management rule page. In a future PR we will require the rule type to specify the plugin's path when registering the rule type that way we can link back to the specific plugin that created the rule. Issue: https://github.com/elastic/kibana/issues/145132 <details><summary>Mustache variable</summary>   </details> <details><summary>Constructed URL</summary>  </details> Co-authored-by: Xavier Mouligneau <xavier.mouligneau@elastic.co>
This commit is contained in:
parent
5ee2172547
commit
2180a8a6b0
13 changed files with 393 additions and 150 deletions
|
@ -10,3 +10,4 @@ export * from './src/technical_field_names';
|
|||
export * from './src/alerts_as_data_rbac';
|
||||
export * from './src/alerts_as_data_severity';
|
||||
export * from './src/alerts_as_data_status';
|
||||
export * from './src/routes/stack_rule_paths';
|
||||
|
|
12
packages/kbn-rule-data-utils/src/routes/stack_rule_paths.ts
Normal file
12
packages/kbn-rule-data-utils/src/routes/stack_rule_paths.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export const ruleDetailsRoute = '/rule/:ruleId' as const;
|
||||
export const triggersActionsRoute = '/app/management/insightsAndAlerting/triggersActions' as const;
|
||||
|
||||
export const getRuleDetailsRoute = (ruleId: string) => ruleDetailsRoute.replace(':ruleId', ruleId);
|
|
@ -13,7 +13,7 @@ import {
|
|||
renderActionParameterTemplatesDefault,
|
||||
} from '@kbn/actions-plugin/server/mocks';
|
||||
import { KibanaRequest } from '@kbn/core/server';
|
||||
import { InjectActionParamsOpts } from './inject_action_params';
|
||||
import { InjectActionParamsOpts, injectActionParams } from './inject_action_params';
|
||||
import { NormalizedRuleType } from '../rule_type_registry';
|
||||
import { ActionsCompletion, RuleTypeParams, RuleTypeState, SanitizedRule } from '../types';
|
||||
import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store';
|
||||
|
@ -29,6 +29,8 @@ jest.mock('./inject_action_params', () => ({
|
|||
injectActionParams: jest.fn(),
|
||||
}));
|
||||
|
||||
const injectActionParamsMock = injectActionParams as jest.Mock;
|
||||
|
||||
const alertingEventLogger = alertingEventLoggerMock.create();
|
||||
const actionsClient = actionsClientMock.create();
|
||||
const mockActionsPlugin = actionsMock.createStart();
|
||||
|
@ -184,39 +186,39 @@ describe('Execution Handler', () => {
|
|||
expect(ruleRunMetricsStore.getNumberOfGeneratedActions()).toBe(1);
|
||||
expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.bulkEnqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 1 goes here",
|
||||
"contextVal": "My goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 1 goes here",
|
||||
"contextVal": "My goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
|
||||
expect(alertingEventLogger.logAction).toHaveBeenCalledTimes(1);
|
||||
expect(alertingEventLogger.logAction).toHaveBeenNthCalledWith(1, {
|
||||
|
@ -308,7 +310,7 @@ describe('Execution Handler', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
test('trow error error message when action type is disabled', async () => {
|
||||
test('throw error message when action type is disabled', async () => {
|
||||
mockActionsPlugin.preconfiguredActions = [];
|
||||
mockActionsPlugin.isActionExecutable.mockReturnValue(false);
|
||||
mockActionsPlugin.isActionTypeEnabled.mockReturnValue(false);
|
||||
|
@ -370,39 +372,39 @@ describe('Execution Handler', () => {
|
|||
expect(ruleRunMetricsStore.getNumberOfGeneratedActions()).toBe(1);
|
||||
expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.bulkEnqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 2 goes here",
|
||||
"contextVal": "My context-val goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 2 goes here",
|
||||
"contextVal": "My context-val goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test('state attribute gets parameterized', async () => {
|
||||
|
@ -410,39 +412,39 @@ describe('Execution Handler', () => {
|
|||
await executionHandler.run(generateAlert({ id: 2, state: { value: 'state-val' } }));
|
||||
expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.bulkEnqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 2 goes here",
|
||||
"contextVal": "My goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My state-val goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 2 goes here",
|
||||
"contextVal": "My goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My state-val goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test(`logs an error when action group isn't part of actionGroups available for the ruleType`, async () => {
|
||||
|
@ -622,39 +624,39 @@ describe('Execution Handler', () => {
|
|||
await executionHandler.run(generateAlert({ id: 1, scheduleActions: false }), true);
|
||||
expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1);
|
||||
expect(actionsClient.bulkEnqueueExecution.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 1 goes here",
|
||||
"contextVal": "My goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
Array [
|
||||
Object {
|
||||
"apiKey": "MTIzOmFiYw==",
|
||||
"consumer": "rule-consumer",
|
||||
"executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28",
|
||||
"id": "1",
|
||||
"params": Object {
|
||||
"alertVal": "My 1 name-of-alert test1 tag-A,tag-B 1 goes here",
|
||||
"contextVal": "My goes here",
|
||||
"foo": true,
|
||||
"stateVal": "My goes here",
|
||||
},
|
||||
"relatedSavedObjects": Array [
|
||||
Object {
|
||||
"id": "1",
|
||||
"namespace": "test1",
|
||||
"type": "alert",
|
||||
"typeId": "test",
|
||||
},
|
||||
],
|
||||
"source": Object {
|
||||
"source": Object {
|
||||
"id": "1",
|
||||
"type": "alert",
|
||||
},
|
||||
"type": "SAVED_OBJECT",
|
||||
},
|
||||
"spaceId": "test1",
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test('does not schedule alerts with recovered actions that are muted', async () => {
|
||||
|
@ -729,4 +731,191 @@ describe('Execution Handler', () => {
|
|||
`skipping scheduling of actions for '1' in rule ${defaultExecutionParams.ruleLabel}: rule is muted`
|
||||
);
|
||||
});
|
||||
|
||||
describe('rule url', () => {
|
||||
const ruleWithUrl = {
|
||||
...rule,
|
||||
actions: [
|
||||
{
|
||||
id: '1',
|
||||
group: 'default',
|
||||
actionTypeId: 'test',
|
||||
params: {
|
||||
val: 'rule url: {{rule.url}}',
|
||||
},
|
||||
},
|
||||
],
|
||||
} as unknown as SanitizedRule<RuleTypeParams>;
|
||||
|
||||
it('populates the rule.url in the action params when the base url and rule id are specified', async () => {
|
||||
const execParams = {
|
||||
...defaultExecutionParams,
|
||||
rule: ruleWithUrl,
|
||||
taskRunnerContext: {
|
||||
...defaultExecutionParams.taskRunnerContext,
|
||||
kibanaBaseUrl: 'http://localhost:12345',
|
||||
},
|
||||
};
|
||||
|
||||
const executionHandler = new ExecutionHandler(generateExecutionParams(execParams));
|
||||
await executionHandler.run(generateAlert({ id: 1 }));
|
||||
|
||||
expect(injectActionParamsMock.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"actionParams": Object {
|
||||
"val": "rule url: http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
|
||||
},
|
||||
"actionTypeId": "test",
|
||||
"ruleId": "1",
|
||||
"spaceId": "test1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('populates the rule.url without the space specifier when the spaceId is the string "default"', async () => {
|
||||
const execParams = {
|
||||
...defaultExecutionParams,
|
||||
rule: ruleWithUrl,
|
||||
taskRunnerContext: {
|
||||
...defaultExecutionParams.taskRunnerContext,
|
||||
kibanaBaseUrl: 'http://localhost:12345',
|
||||
},
|
||||
taskInstance: {
|
||||
params: { spaceId: 'default', alertId: '1' },
|
||||
} as unknown as ConcreteTaskInstance,
|
||||
};
|
||||
|
||||
const executionHandler = new ExecutionHandler(generateExecutionParams(execParams));
|
||||
await executionHandler.run(generateAlert({ id: 1 }));
|
||||
|
||||
expect(injectActionParamsMock.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"actionParams": Object {
|
||||
"val": "rule url: http://localhost:12345/app/management/insightsAndAlerting/triggersActions/rule/1",
|
||||
},
|
||||
"actionTypeId": "test",
|
||||
"ruleId": "1",
|
||||
"spaceId": "default",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('populates the rule.url in the action params when the base url has a trailing slash and removes the trailing slash', async () => {
|
||||
const execParams = {
|
||||
...defaultExecutionParams,
|
||||
rule: ruleWithUrl,
|
||||
taskRunnerContext: {
|
||||
...defaultExecutionParams.taskRunnerContext,
|
||||
kibanaBaseUrl: 'http://localhost:12345/',
|
||||
},
|
||||
};
|
||||
|
||||
const executionHandler = new ExecutionHandler(generateExecutionParams(execParams));
|
||||
await executionHandler.run(generateAlert({ id: 1 }));
|
||||
|
||||
expect(injectActionParamsMock.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"actionParams": Object {
|
||||
"val": "rule url: http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
|
||||
},
|
||||
"actionTypeId": "test",
|
||||
"ruleId": "1",
|
||||
"spaceId": "test1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('does not populate the rule.url when the base url is not specified', async () => {
|
||||
const execParams = {
|
||||
...defaultExecutionParams,
|
||||
rule: ruleWithUrl,
|
||||
taskRunnerContext: {
|
||||
...defaultExecutionParams.taskRunnerContext,
|
||||
kibanaBaseUrl: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
const executionHandler = new ExecutionHandler(generateExecutionParams(execParams));
|
||||
await executionHandler.run(generateAlert({ id: 1 }));
|
||||
|
||||
expect(injectActionParamsMock.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"actionParams": Object {
|
||||
"val": "rule url: ",
|
||||
},
|
||||
"actionTypeId": "test",
|
||||
"ruleId": "1",
|
||||
"spaceId": "test1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('does not populate the rule.url when base url is not a valid url', async () => {
|
||||
const execParams = {
|
||||
...defaultExecutionParams,
|
||||
rule: ruleWithUrl,
|
||||
taskRunnerContext: {
|
||||
...defaultExecutionParams.taskRunnerContext,
|
||||
kibanaBaseUrl: 'localhost12345',
|
||||
},
|
||||
taskInstance: {
|
||||
params: { spaceId: 'test1', alertId: '1' },
|
||||
} as unknown as ConcreteTaskInstance,
|
||||
};
|
||||
|
||||
const executionHandler = new ExecutionHandler(generateExecutionParams(execParams));
|
||||
await executionHandler.run(generateAlert({ id: 1 }));
|
||||
|
||||
expect(injectActionParamsMock.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"actionParams": Object {
|
||||
"val": "rule url: ",
|
||||
},
|
||||
"actionTypeId": "test",
|
||||
"ruleId": "1",
|
||||
"spaceId": "test1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('does not populate the rule.url when base url is a number', async () => {
|
||||
const execParams = {
|
||||
...defaultExecutionParams,
|
||||
rule: ruleWithUrl,
|
||||
taskRunnerContext: {
|
||||
...defaultExecutionParams.taskRunnerContext,
|
||||
kibanaBaseUrl: 1,
|
||||
},
|
||||
taskInstance: {
|
||||
params: { spaceId: 'test1', alertId: '1' },
|
||||
} as unknown as ConcreteTaskInstance,
|
||||
};
|
||||
|
||||
const executionHandler = new ExecutionHandler(generateExecutionParams(execParams));
|
||||
await executionHandler.run(generateAlert({ id: 1 }));
|
||||
|
||||
expect(injectActionParamsMock.mock.calls[0]).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"actionParams": Object {
|
||||
"val": "rule url: ",
|
||||
},
|
||||
"actionTypeId": "test",
|
||||
"ruleId": "1",
|
||||
"spaceId": "test1",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import type { PublicMethodsOf } from '@kbn/utility-types';
|
||||
import { Logger } from '@kbn/core/server';
|
||||
import { getRuleDetailsRoute, triggersActionsRoute } from '@kbn/rule-data-utils';
|
||||
import { asSavedObjectExecutionSource } from '@kbn/actions-plugin/server';
|
||||
import { isEphemeralTaskRejectedDueToCapacityError } from '@kbn/task-manager-plugin/server';
|
||||
import { ExecuteOptions as EnqueueExecutionOptions } from '@kbn/actions-plugin/server/create_execute_function';
|
||||
|
@ -208,6 +209,7 @@ export class ExecutionHandler<
|
|||
kibanaBaseUrl: this.taskRunnerContext.kibanaBaseUrl,
|
||||
alertParams: this.rule.params,
|
||||
actionParams: action.params,
|
||||
ruleUrl: this.buildRuleUrl(spaceId),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
@ -282,6 +284,28 @@ export class ExecutionHandler<
|
|||
return executables;
|
||||
}
|
||||
|
||||
private buildRuleUrl(spaceId: string): string | undefined {
|
||||
if (!this.taskRunnerContext.kibanaBaseUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const ruleUrl = new URL(
|
||||
`${
|
||||
spaceId !== 'default' ? `/s/${spaceId}` : ''
|
||||
}${triggersActionsRoute}${getRuleDetailsRoute(this.rule.id)}`,
|
||||
this.taskRunnerContext.kibanaBaseUrl
|
||||
);
|
||||
|
||||
return ruleUrl.toString();
|
||||
} catch (error) {
|
||||
this.logger.debug(
|
||||
`Rule "${this.rule.id}" encountered an error while constructing the rule.url variable: ${error.message}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private async actionRunOrAddToBulk({
|
||||
enqueueOptions,
|
||||
bulkActions,
|
||||
|
|
|
@ -30,6 +30,7 @@ interface TransformActionParamsOptions {
|
|||
state: AlertInstanceState;
|
||||
kibanaBaseUrl?: string;
|
||||
context: AlertInstanceContext;
|
||||
ruleUrl?: string;
|
||||
}
|
||||
|
||||
export function transformActionParams({
|
||||
|
@ -49,6 +50,7 @@ export function transformActionParams({
|
|||
state,
|
||||
kibanaBaseUrl,
|
||||
alertParams,
|
||||
ruleUrl,
|
||||
}: TransformActionParamsOptions): RuleActionParams {
|
||||
// when the list of variables we pass in here changes,
|
||||
// the UI will need to be updated as well; see:
|
||||
|
@ -72,6 +74,7 @@ export function transformActionParams({
|
|||
type: alertType,
|
||||
spaceId,
|
||||
tags,
|
||||
url: ruleUrl,
|
||||
},
|
||||
alert: {
|
||||
id: alertInstanceId,
|
||||
|
|
|
@ -25,18 +25,14 @@ import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
|
|||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import { ActionsPublicPluginSetup } from '@kbn/actions-plugin/public';
|
||||
import { ruleDetailsRoute } from '@kbn/rule-data-utils';
|
||||
import { suspendedComponentWithProps } from './lib/suspended_component_with_props';
|
||||
import {
|
||||
ActionTypeRegistryContract,
|
||||
AlertsTableConfigurationRegistryContract,
|
||||
RuleTypeRegistryContract,
|
||||
} from '../types';
|
||||
import {
|
||||
Section,
|
||||
routeToRuleDetails,
|
||||
legacyRouteToRuleDetails,
|
||||
routeToConnectors,
|
||||
} from './constants';
|
||||
import { Section, legacyRouteToRuleDetails, routeToConnectors } from './constants';
|
||||
|
||||
import { setDataViewsService } from '../common/lib/data_apis';
|
||||
import { KibanaContextProvider, useKibana } from '../common/lib/kibana';
|
||||
|
@ -113,7 +109,7 @@ export const AppWithoutRouter = ({ sectionsRegex }: { sectionsRegex: string }) =
|
|||
component={suspendedComponentWithProps(TriggersActionsUIHome, 'xl')}
|
||||
/>
|
||||
<Route
|
||||
path={routeToRuleDetails}
|
||||
path={ruleDetailsRoute}
|
||||
component={suspendedComponentWithProps(RuleDetailsRoute, 'xl')}
|
||||
/>
|
||||
<Route
|
||||
|
|
|
@ -19,7 +19,6 @@ export const routeToHome = `/`;
|
|||
export const routeToConnectors = `/connectors`;
|
||||
export const routeToRules = `/rules`;
|
||||
export const routeToLogs = `/logs`;
|
||||
export const routeToRuleDetails = `/rule/:ruleId`;
|
||||
export const routeToInternalAlerts = `/alerts`;
|
||||
export const legacyRouteToRules = `/alerts`;
|
||||
export const legacyRouteToRuleDetails = `/alert/:alertId`;
|
||||
|
|
|
@ -43,6 +43,11 @@ const expectedTransformResult = [
|
|||
{ description: 'The space ID of the rule.', name: 'rule.spaceId' },
|
||||
{ description: 'The tags of the rule.', name: 'rule.tags' },
|
||||
{ description: 'The type of rule.', name: 'rule.type' },
|
||||
{
|
||||
description:
|
||||
'The URL to the Stack Management rule page that generated the alert. This will be an empty string if the server.publicBaseUrl is not configured.',
|
||||
name: 'rule.url',
|
||||
},
|
||||
{ description: 'The date the rule scheduled the action.', name: 'date' },
|
||||
{ description: 'The ID of the alert that scheduled actions for the rule.', name: 'alert.id' },
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ export enum AlertProvidedActionVariables {
|
|||
ruleSpaceId = 'rule.spaceId',
|
||||
ruleTags = 'rule.tags',
|
||||
ruleType = 'rule.type',
|
||||
ruleUrl = 'rule.url',
|
||||
date = 'date',
|
||||
alertId = 'alert.id',
|
||||
alertActionGroup = 'alert.actionGroup',
|
||||
|
@ -105,6 +106,14 @@ function getAlwaysProvidedActionVariables(): ActionVariable[] {
|
|||
}),
|
||||
});
|
||||
|
||||
result.push({
|
||||
name: AlertProvidedActionVariables.ruleUrl,
|
||||
description: i18n.translate('xpack.triggersActionsUI.actionVariables.ruleUrlLabel', {
|
||||
defaultMessage:
|
||||
'The URL to the Stack Management rule page that generated the alert. This will be an empty string if the server.publicBaseUrl is not configured.',
|
||||
}),
|
||||
});
|
||||
|
||||
result.push({
|
||||
name: AlertProvidedActionVariables.date,
|
||||
description: i18n.translate('xpack.triggersActionsUI.actionVariables.dateLabel', {
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { toMountPoint } from '@kbn/kibana-react-plugin/public';
|
||||
import { RuleExecutionStatusErrorReasons, parseDuration } from '@kbn/alerting-plugin/common';
|
||||
import { getRuleDetailsRoute } from '@kbn/rule-data-utils';
|
||||
import { UpdateApiKeyModalConfirmation } from '../../../components/update_api_key_modal_confirmation';
|
||||
import { bulkUpdateAPIKey, deleteRules } from '../../../lib/rule_api';
|
||||
import { DeleteModalConfirmation } from '../../../components/delete_modal_confirmation';
|
||||
|
@ -50,7 +51,7 @@ import {
|
|||
import { RuleRouteWithApi } from './rule_route';
|
||||
import { ViewInApp } from './view_in_app';
|
||||
import { RuleEdit } from '../../rule_form';
|
||||
import { routeToRuleDetails, routeToRules } from '../../../constants';
|
||||
import { routeToRules } from '../../../constants';
|
||||
import {
|
||||
rulesErrorReasonTranslationsMapping,
|
||||
rulesWarningReasonTranslationsMapping,
|
||||
|
@ -209,7 +210,7 @@ export const RuleDetails: React.FunctionComponent<RuleDetailsProps> = ({
|
|||
}, [rule.schedule.interval, config.minimumScheduleInterval, toasts, hasEditButton]);
|
||||
|
||||
const setRule = async () => {
|
||||
history.push(routeToRuleDetails.replace(`:ruleId`, rule.id));
|
||||
history.push(getRuleDetailsRoute(rule.id));
|
||||
};
|
||||
|
||||
const goToRulesList = () => {
|
||||
|
|
|
@ -10,7 +10,7 @@ import moment from 'moment';
|
|||
import { EuiLink } from '@elastic/eui';
|
||||
import { RuleAlertingOutcome } from '@kbn/alerting-plugin/common';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { routeToRuleDetails } from '../../../constants';
|
||||
import { getRuleDetailsRoute } from '@kbn/rule-data-utils';
|
||||
import { formatRuleAlertCount } from '../../../../common/lib/format_rule_alert_count';
|
||||
import { useKibana, useSpacesData } from '../../../../common/lib/kibana';
|
||||
import { RuleEventLogListStatus } from './rule_event_log_list_status';
|
||||
|
@ -53,7 +53,9 @@ export const RuleEventLogListCellRenderer = (props: RuleEventLogListCellRenderer
|
|||
|
||||
const ruleNamePathname = useMemo(() => {
|
||||
if (!ruleId) return '';
|
||||
const ruleRoute = routeToRuleDetails.replace(':ruleId', ruleId);
|
||||
|
||||
const ruleRoute = getRuleDetailsRoute(ruleId);
|
||||
|
||||
if (ruleOnDifferentSpace) {
|
||||
const [linkedSpaceId] = spaceIds ?? [];
|
||||
const basePath = http.basePath.get();
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
RuleExecutionStatusErrorReasons,
|
||||
} from '@kbn/alerting-plugin/common';
|
||||
import { AlertingConnectorFeatureId } from '@kbn/actions-plugin/common';
|
||||
import { ruleDetailsRoute as commonRuleDetailsRoute } from '@kbn/rule-data-utils';
|
||||
import {
|
||||
ActionType,
|
||||
Rule,
|
||||
|
@ -68,7 +69,7 @@ import {
|
|||
} from '../../../lib/rule_api';
|
||||
import { loadActionTypes } from '../../../lib/action_connector_api';
|
||||
import { hasAllPrivilege, hasExecuteActionsCapability } from '../../../lib/capabilities';
|
||||
import { routeToRuleDetails, DEFAULT_SEARCH_PAGE_SIZE } from '../../../constants';
|
||||
import { DEFAULT_SEARCH_PAGE_SIZE } from '../../../constants';
|
||||
import { RulesDeleteModalConfirmation } from '../../../components/rules_delete_modal_confirmation';
|
||||
import { EmptyPrompt } from '../../../components/prompts/empty_prompt';
|
||||
import { ALERT_STATUS_LICENSE_ERROR } from '../translations';
|
||||
|
@ -886,7 +887,7 @@ export const RulesList = ({
|
|||
onPage={setPage}
|
||||
onRuleChanged={() => refreshRules()}
|
||||
onRuleClick={(rule) => {
|
||||
const detailsRoute = ruleDetailsRoute ? ruleDetailsRoute : routeToRuleDetails;
|
||||
const detailsRoute = ruleDetailsRoute ? ruleDetailsRoute : commonRuleDetailsRoute;
|
||||
history.push(detailsRoute.replace(`:ruleId`, rule.id));
|
||||
}}
|
||||
onRuleEditClick={(rule) => {
|
||||
|
|
|
@ -23,6 +23,7 @@ import type { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public';
|
|||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
|
||||
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
|
||||
import { triggersActionsRoute } from '@kbn/rule-data-utils';
|
||||
import type { AlertsSearchBarProps } from './application/sections/alerts_search_bar';
|
||||
import { TypeRegistry } from './application/type_registry';
|
||||
|
||||
|
@ -212,7 +213,7 @@ export class Plugin
|
|||
title: featureTitle,
|
||||
description: featureDescription,
|
||||
icon: 'watchesApp',
|
||||
path: '/app/management/insightsAndAlerting/triggersActions',
|
||||
path: triggersActionsRoute,
|
||||
showOnHomePage: false,
|
||||
category: 'admin',
|
||||
});
|
||||
|
@ -221,7 +222,7 @@ export class Plugin
|
|||
title: connectorsFeatureTitle,
|
||||
description: connectorsFeatureDescription,
|
||||
icon: 'watchesApp',
|
||||
path: '/app/management/insightsAndAlerting/triggersActions',
|
||||
path: triggersActionsRoute,
|
||||
showOnHomePage: false,
|
||||
category: 'admin',
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue