Fix email connector rule URL (#162954)

Closes #162953

## Summary

This PR fixes the issue of adding basePath (`/kibana` in the following
example) twice when generating the rule URL for the email connector.

**Before**
```
1. 48e02d00-3106-11ee-99f4-39221cc3f357
2. e36f8b70-3135-11ee-9808-139f80c124ca
```
**After**
```
1. 48e02d00-3106-11ee-99f4-39221cc3f357
2. e36f8b70-3135-11ee-9808-139f80c124ca
```
This commit is contained in:
Maryam Saeidi 2023-08-03 11:51:19 +02:00 committed by GitHub
parent 2069210002
commit bb68c20d99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 21 deletions

View file

@ -1647,7 +1647,13 @@ describe('Execution Handler', () => {
"val": "rule url: http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
},
"actionTypeId": "test",
"ruleUrl": "http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
"ruleUrl": Object {
"absoluteUrl": "http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
"basePathname": "",
"kibanaBaseUrl": "http://localhost:12345",
"relativePath": "/app/management/insightsAndAlerting/triggersActions/rule/1",
"spaceIdSegment": "/s/test1",
},
},
]
`);
@ -1699,7 +1705,7 @@ describe('Execution Handler', () => {
rule: summaryRuleWithUrl,
taskRunnerContext: {
...defaultExecutionParams.taskRunnerContext,
kibanaBaseUrl: 'http://localhost:12345',
kibanaBaseUrl: 'http://localhost:12345/basePath',
},
};
@ -1710,10 +1716,16 @@ describe('Execution Handler', () => {
Array [
Object {
"actionParams": Object {
"val": "rule url: http://localhost:12345/s/test1/app/test/rule/1?start=30000&end=90000",
"val": "rule url: http://localhost:12345/basePath/s/test1/app/test/rule/1?start=30000&end=90000",
},
"actionTypeId": "test",
"ruleUrl": "http://localhost:12345/s/test1/app/test/rule/1?start=30000&end=90000",
"ruleUrl": Object {
"absoluteUrl": "http://localhost:12345/basePath/s/test1/app/test/rule/1?start=30000&end=90000",
"basePathname": "/basePath",
"kibanaBaseUrl": "http://localhost:12345/basePath",
"relativePath": "/app/test/rule/1?start=30000&end=90000",
"spaceIdSegment": "/s/test1",
},
},
]
`);
@ -1742,7 +1754,13 @@ describe('Execution Handler', () => {
"val": "rule url: http://localhost:12345/app/management/insightsAndAlerting/triggersActions/rule/1",
},
"actionTypeId": "test",
"ruleUrl": "http://localhost:12345/app/management/insightsAndAlerting/triggersActions/rule/1",
"ruleUrl": Object {
"absoluteUrl": "http://localhost:12345/app/management/insightsAndAlerting/triggersActions/rule/1",
"basePathname": "",
"kibanaBaseUrl": "http://localhost:12345",
"relativePath": "/app/management/insightsAndAlerting/triggersActions/rule/1",
"spaceIdSegment": "",
},
},
]
`);
@ -1768,7 +1786,13 @@ describe('Execution Handler', () => {
"val": "rule url: http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
},
"actionTypeId": "test",
"ruleUrl": "http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
"ruleUrl": Object {
"absoluteUrl": "http://localhost:12345/s/test1/app/management/insightsAndAlerting/triggersActions/rule/1",
"basePathname": "",
"kibanaBaseUrl": "http://localhost:12345/",
"relativePath": "/app/management/insightsAndAlerting/triggersActions/rule/1",
"spaceIdSegment": "/s/test1",
},
},
]
`);
@ -1884,7 +1908,13 @@ describe('Execution Handler', () => {
"val": "rule url: http://localhost:12345/s/test1/app/management/some/other/place",
},
"actionTypeId": "test",
"ruleUrl": "http://localhost:12345/s/test1/app/management/some/other/place",
"ruleUrl": Object {
"absoluteUrl": "http://localhost:12345/s/test1/app/management/some/other/place",
"basePathname": "",
"kibanaBaseUrl": "http://localhost:12345",
"relativePath": "/app/management/some/other/place",
"spaceIdSegment": "/s/test1",
},
},
]
`);

View file

@ -53,6 +53,14 @@ export interface RunResult {
throttledSummaryActions: ThrottledActions;
}
export interface RuleUrl {
absoluteUrl?: string;
kibanaBaseUrl?: string;
basePathname?: string;
spaceIdSegment?: string;
relativePath?: string;
}
export class ExecutionHandler<
Params extends RuleTypeParams,
ExtractedParams extends RuleTypeParams,
@ -240,7 +248,7 @@ export class ExecutionHandler<
actionsPlugin,
actionTypeId,
kibanaBaseUrl: this.taskRunnerContext.kibanaBaseUrl,
ruleUrl,
ruleUrl: ruleUrl?.absoluteUrl,
}),
}),
};
@ -289,7 +297,7 @@ export class ExecutionHandler<
alertParams: this.rule.params,
actionParams: action.params,
flapping: alert.getFlapping(),
ruleUrl,
ruleUrl: ruleUrl?.absoluteUrl,
}),
}),
};
@ -437,7 +445,7 @@ export class ExecutionHandler<
return alert.getScheduledActionOptions()?.actionGroup || this.ruleType.recoveryActionGroup.id;
}
private buildRuleUrl(spaceId: string, start?: number, end?: number): string | undefined {
private buildRuleUrl(spaceId: string, start?: number, end?: number): RuleUrl | undefined {
if (!this.taskRunnerContext.kibanaBaseUrl) {
return;
}
@ -456,7 +464,13 @@ export class ExecutionHandler<
this.taskRunnerContext.kibanaBaseUrl
);
return ruleUrl.toString();
return {
absoluteUrl: ruleUrl.toString(),
kibanaBaseUrl: this.taskRunnerContext.kibanaBaseUrl,
basePathname: basePathnamePrefix,
spaceIdSegment,
relativePath,
};
} catch (error) {
this.logger.debug(
`Rule "${this.rule.id}" encountered an error while constructing the rule.url variable: ${error.message}`

View file

@ -23,16 +23,24 @@ describe('injectActionParams', () => {
`);
});
test('injects viewInKibanaPath and viewInKibanaText when actionTypeId is .email', () => {
test('injects viewInKibanaPath and viewInKibanaText when actionTypeId is .email and there is no basePathname', () => {
const actionParams = {
body: {
message: 'State: "{{state.value}}", Context: "{{context.value}}"',
},
};
const ruleUrl = {
absoluteUrl:
'http://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/1',
kibanaBaseUrl: 'http://localhost:5601',
basePathname: '',
spaceIdSegment: '',
relativePath: '/app/management/insightsAndAlerting/triggersActions/rule/1',
};
const result = injectActionParams({
actionParams,
actionTypeId: '.email',
ruleUrl: 'http://localhost:5601/app/management/insightsAndAlerting/triggersActions/rule/1',
ruleUrl,
});
expect(result).toMatchInlineSnapshot(`
Object {
@ -47,6 +55,39 @@ describe('injectActionParams', () => {
`);
});
test('injects viewInKibanaPath and viewInKibanaText when actionTypeId is .email with basePathname and spaceId', () => {
const actionParams = {
body: {
message: 'State: "{{state.value}}", Context: "{{context.value}}"',
},
};
const ruleUrl = {
absoluteUrl:
'http://localhost:5601/kibana/s/mary/app/management/insightsAndAlerting/triggersActions/rule/1',
kibanaBaseUrl: 'http://localhost:5601/kibana',
basePathname: '/kibana',
spaceIdSegment: '/s/mary',
relativePath: '/app/management/insightsAndAlerting/triggersActions/rule/1',
};
const result = injectActionParams({
actionParams,
actionTypeId: '.email',
ruleUrl,
});
// path in the snapshot should not include /kibana since it is part of kibanaBaseUrl already
expect(result).toMatchInlineSnapshot(`
Object {
"body": Object {
"message": "State: \\"{{state.value}}\\", Context: \\"{{context.value}}\\"",
},
"kibanaFooterLink": Object {
"path": "/s/mary/app/management/insightsAndAlerting/triggersActions/rule/1",
"text": "View rule in Kibana",
},
}
`);
});
test('injects viewInKibanaPath as empty string when the ruleUrl is undefined', () => {
const actionParams = {
body: {

View file

@ -7,27 +7,24 @@
import { i18n } from '@kbn/i18n';
import { RuleActionParams } from '../types';
import { RuleUrl } from './execution_handler';
export interface InjectActionParamsOpts {
actionTypeId: string;
actionParams: RuleActionParams;
ruleUrl?: string;
ruleUrl?: RuleUrl;
}
export function injectActionParams({
actionTypeId,
actionParams,
ruleUrl = '',
ruleUrl = {},
}: InjectActionParamsOpts) {
// Inject kibanaFooterLink if action type is email. This is used by the email action type
// to inject a "View alert in Kibana" with a URL in the email's footer.
if (actionTypeId === '.email') {
let path;
try {
path = new URL(ruleUrl).pathname;
} catch (e) {
path = '';
}
// path should not include basePathname since it is part of kibanaBaseUrl already
const path = [ruleUrl.spaceIdSegment ?? '', ruleUrl.relativePath ?? ''].join('');
return {
...actionParams,
kibanaFooterLink: {