mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
[8.x] [ResponseOps][Alerting] Error when submit rule form when using AddFilterPopover in actions (#194600) (#195228)
# Backport This will backport the following commits from `main` to `8.x`: - [[ResponseOps][Alerting] Error when submit rule form when using AddFilterPopover in actions (#194600)](https://github.com/elastic/kibana/pull/194600) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Julia","email":"iuliia.guskova@elastic.co"},"sourceCommit":{"committedDate":"2024-10-07T11:23:25Z","message":"[ResponseOps][Alerting] Error when submit rule form when using AddFilterPopover in actions (#194600)\n\nResolve: https://github.com/elastic/kibana/issues/192847\r\n\r\nWhen user try to save the rule which has a conditional action with a\r\nfilter which contains AND or OR, it'll fail.\r\nError raises when a new rule SO object is going to be created.\r\nValidation fails because schema is wrong.\r\nI fixed it in this PR.\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n\r\n### How to test\r\n\r\n1. Go to Rules and try creating a new rule of any type\r\n2. Add an action to the rule\r\n3. Check the option If alert matches a query\r\n4. Click the + icon to add a filter\r\n5. Create a filter in the popover\r\n6. Click AND or OR\r\n7. Create another filter\r\n8. Click Add filter\r\n9. Try saving the rule\r\n10. Saving should be successful","sha":"02d0c9852f0efb15b67c06e240e1525220a701ec","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","backport","Feature:Alerting","release_note:skip","Team:ResponseOps","v9.0.0","backport:prev-minor","v8.16.0"],"title":"[ResponseOps][Alerting] Error when submit rule form when using AddFilterPopover in actions","number":194600,"url":"https://github.com/elastic/kibana/pull/194600","mergeCommit":{"message":"[ResponseOps][Alerting] Error when submit rule form when using AddFilterPopover in actions (#194600)\n\nResolve: https://github.com/elastic/kibana/issues/192847\r\n\r\nWhen user try to save the rule which has a conditional action with a\r\nfilter which contains AND or OR, it'll fail.\r\nError raises when a new rule SO object is going to be created.\r\nValidation fails because schema is wrong.\r\nI fixed it in this PR.\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n\r\n### How to test\r\n\r\n1. Go to Rules and try creating a new rule of any type\r\n2. Add an action to the rule\r\n3. Check the option If alert matches a query\r\n4. Click the + icon to add a filter\r\n5. Create a filter in the popover\r\n6. Click AND or OR\r\n7. Create another filter\r\n8. Click Add filter\r\n9. Try saving the rule\r\n10. Saving should be successful","sha":"02d0c9852f0efb15b67c06e240e1525220a701ec"}},"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/194600","number":194600,"mergeCommit":{"message":"[ResponseOps][Alerting] Error when submit rule form when using AddFilterPopover in actions (#194600)\n\nResolve: https://github.com/elastic/kibana/issues/192847\r\n\r\nWhen user try to save the rule which has a conditional action with a\r\nfilter which contains AND or OR, it'll fail.\r\nError raises when a new rule SO object is going to be created.\r\nValidation fails because schema is wrong.\r\nI fixed it in this PR.\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n\r\n\r\n### How to test\r\n\r\n1. Go to Rules and try creating a new rule of any type\r\n2. Add an action to the rule\r\n3. Check the option If alert matches a query\r\n4. Click the + icon to add a filter\r\n5. Create a filter in the popover\r\n6. Click AND or OR\r\n7. Create another filter\r\n8. Click Add filter\r\n9. Try saving the rule\r\n10. Saving should be successful","sha":"02d0c9852f0efb15b67c06e240e1525220a701ec"}},{"branch":"8.x","label":"v8.16.0","branchLabelMappingKey":"^v8.16.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Julia <iuliia.guskova@elastic.co>
This commit is contained in:
parent
a9c7c913d1
commit
c3012d8ff8
3 changed files with 94 additions and 2 deletions
|
@ -167,9 +167,10 @@ const rawRuleAlertsFilterSchema = schema.object({
|
|||
isMultiIndex: schema.maybe(schema.boolean()),
|
||||
type: schema.maybe(schema.string()),
|
||||
key: schema.maybe(schema.string()),
|
||||
params: schema.maybe(schema.recordOf(schema.string(), schema.any())), // better type?
|
||||
params: schema.maybe(schema.any()),
|
||||
value: schema.maybe(schema.string()),
|
||||
field: schema.maybe(schema.string()),
|
||||
relation: schema.maybe(schema.oneOf([schema.literal('OR'), schema.literal('AND')])),
|
||||
}),
|
||||
$state: schema.maybe(
|
||||
schema.object({
|
||||
|
|
|
@ -20,7 +20,7 @@ const filterQueryRequiredError = i18n.translate(
|
|||
export const validateActionFilterQuery = (actionItem: RuleUiAction): string | null => {
|
||||
if ('alertsFilter' in actionItem) {
|
||||
const query = actionItem?.alertsFilter?.query;
|
||||
if (query && !query.kql) {
|
||||
if (query && !(query.kql || query.filters.length)) {
|
||||
return filterQueryRequiredError;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,6 +253,97 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
|
||||
});
|
||||
|
||||
it('should create an alert with composite query in filter for conditional action', async () => {
|
||||
const alertName = generateUniqueKey();
|
||||
await rules.common.defineIndexThresholdAlert(alertName);
|
||||
|
||||
// filterKuery validation
|
||||
await testSubjects.setValue('filterKuery', 'group:');
|
||||
const filterKueryInput = await testSubjects.find('filterKuery');
|
||||
expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(true);
|
||||
await testSubjects.setValue('filterKuery', 'group: group-0');
|
||||
expect(await filterKueryInput.elementHasClass('euiFieldSearch-isInvalid')).to.eql(false);
|
||||
|
||||
await testSubjects.click('.slack-alerting-ActionTypeSelectOption');
|
||||
await testSubjects.click('addNewActionConnectorButton-.slack');
|
||||
const slackConnectorName = generateUniqueKey();
|
||||
await testSubjects.setValue('nameInput', slackConnectorName);
|
||||
await testSubjects.setValue('slackWebhookUrlInput', 'https://test.com');
|
||||
await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)');
|
||||
const createdConnectorToastTitle = await toasts.getTitleAndDismiss();
|
||||
expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`);
|
||||
await testSubjects.click('notifyWhenSelect');
|
||||
await testSubjects.click('onThrottleInterval');
|
||||
await testSubjects.setValue('throttleInput', '10');
|
||||
|
||||
// Alerts search bar (conditional actions)
|
||||
await testSubjects.click('alertsFilterQueryToggle');
|
||||
|
||||
await pageObjects.header.waitUntilLoadingHasFinished();
|
||||
await testSubjects.click('addFilter');
|
||||
// Add first part of query before AND
|
||||
await testSubjects.click('filterFieldSuggestionList');
|
||||
await comboBox.set('filterFieldSuggestionList', '_id');
|
||||
await comboBox.set('filterOperatorList', 'is not');
|
||||
await testSubjects.setValue('filterParams', 'fake-rule-id');
|
||||
await testSubjects.click('add-and-filter');
|
||||
// Add second part of query after AND
|
||||
const firstDropdown = await find.byCssSelector(
|
||||
'[data-test-subj="filter-0.1"] [data-test-subj="filterFieldSuggestionList"] [data-test-subj="comboBoxSearchInput"]'
|
||||
);
|
||||
await firstDropdown.click();
|
||||
await firstDropdown.type('kibana.alert.action_group');
|
||||
await find.clickByButtonText('kibana.alert.action_group');
|
||||
const secondDropdown = await find.byCssSelector(
|
||||
'[data-test-subj="filter-0.1"] [data-test-subj="filterOperatorList"] [data-test-subj="comboBoxSearchInput"]'
|
||||
);
|
||||
await secondDropdown.click();
|
||||
await secondDropdown.type('exists');
|
||||
await find.clickByButtonText('exists');
|
||||
await testSubjects.click('saveFilter');
|
||||
await testSubjects.setValue('queryInput', '_id: *');
|
||||
|
||||
const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]');
|
||||
expect(await messageTextArea.getAttribute('value')).to.eql(
|
||||
`Rule {{rule.name}} is active for group {{context.group}}:
|
||||
|
||||
- Value: {{context.value}}
|
||||
- Conditions Met: {{context.conditions}} over {{rule.params.timeWindowSize}}{{rule.params.timeWindowUnit}}
|
||||
- Timestamp: {{context.date}}`
|
||||
);
|
||||
await testSubjects.setValue('messageTextArea', 'test message ');
|
||||
await testSubjects.click('messageAddVariableButton');
|
||||
await testSubjects.click('variableMenuButton-alert.actionGroup');
|
||||
expect(await messageTextArea.getAttribute('value')).to.eql(
|
||||
'test message {{alert.actionGroup}}'
|
||||
);
|
||||
await messageTextArea.type(' some additional text ');
|
||||
|
||||
await testSubjects.click('messageAddVariableButton');
|
||||
await testSubjects.setValue('messageVariablesSelectableSearch', 'rule.id');
|
||||
await testSubjects.click('variableMenuButton-rule.id');
|
||||
|
||||
expect(await messageTextArea.getAttribute('value')).to.eql(
|
||||
'test message {{alert.actionGroup}} some additional text {{rule.id}}'
|
||||
);
|
||||
await testSubjects.click('saveRuleButton');
|
||||
const toastTitle = await toasts.getTitleAndDismiss();
|
||||
expect(toastTitle).to.eql(`Created rule "${alertName}"`);
|
||||
await pageObjects.triggersActionsUI.searchAlerts(alertName);
|
||||
const searchResultsAfterSave = await pageObjects.triggersActionsUI.getAlertsList();
|
||||
const searchResultAfterSave = searchResultsAfterSave[0];
|
||||
expect(omit(searchResultAfterSave, 'duration')).to.eql({
|
||||
name: `${alertName}Index threshold`,
|
||||
tags: '',
|
||||
interval: '1 min',
|
||||
});
|
||||
expect(searchResultAfterSave.duration).to.match(/\d{2,}:\d{2}/);
|
||||
|
||||
// clean up created alert
|
||||
const alertsToDelete = await getAlertsByName(alertName);
|
||||
await deleteAlerts(alertsToDelete.map((alertItem: { id: string }) => alertItem.id));
|
||||
});
|
||||
|
||||
it('should create an alert with actions in multiple groups', async () => {
|
||||
const alertName = generateUniqueKey();
|
||||
await defineAlwaysFiringAlert(alertName);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue