[Custom threshold] Always pass allowLeadingWildcards as true to the KQL validation in the custom threshold rule API param validation (#190031)

Fixes #189072
Related #190029

## Summary

This PR updates the KQL validation on the server side by passing the
Kibana leadingWildcard setting as true during validation. This means
that even if this configuration is disabled in Kibana, we will still
allow saving such a filter in the rule, but it will fail during rule
execution.
I've created a separate ticket to discuss how to apply the KQL
validation correctly during API param validation.
([issue](https://github.com/elastic/kibana/issues/190029))

This fix will solve the following issues:
<img
src="https://github.com/user-attachments/assets/d99177cb-d4cd-4f33-9a60-8575d87372e3"
width=500 />


We also have [proper validation on the UI
side](https://github.com/elastic/kibana/blob/main/x-pack/plugins/observability_solution/observability/public/components/custom_threshold/components/validation.tsx#L60,L64)
that considers Kibana setting during validation:

|Error|Leading wildcard error|
|---|---|
|
![image](7719813d-ee7b-4eac-b04f-69a867a6dd89)|
This commit is contained in:
Maryam Saeidi 2024-08-14 12:38:53 +02:00 committed by GitHub
parent b67da82336
commit ae4d522b52
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 25 additions and 14 deletions

View file

@ -5619,12 +5619,6 @@ Object {
},
"name": "custom",
},
Object {
"args": Object {
"method": [Function],
},
"name": "custom",
},
],
"type": "string",
},
@ -5639,6 +5633,12 @@ Object {
},
"name": "custom",
},
Object {
"args": Object {
"method": [Function],
},
"name": "custom",
},
],
"type": "string",
},

View file

@ -56,10 +56,10 @@ export const MetricsRulesTypeAlertDefinition: IRuleTypeAlerts<CustomThresholdAle
export const searchConfigurationSchema = schema.object({
index: schema.oneOf([schema.string(), dataViewSpecSchema]),
query: schema.object({
language: schema.string({
language: schema.string(),
query: schema.string({
validate: validateKQLStringFilter,
}),
query: schema.string(),
}),
filter: schema.maybe(
schema.arrayOf(

View file

@ -62,12 +62,22 @@ describe('validateKQLStringFilter', () => {
// input, output
['', undefined],
['host.name:host-0', undefined],
[':*', 'filterQuery must be a valid KQL filter'],
];
const dataWithError = [
// input, output
[
':*',
'filterQuery must be a valid KQL filter (error: Expected "(", NOT, end of input, field name, value, whitespace but ":" found.',
],
];
test.each(data)('validateKQLStringFilter(%s): %o', (input: any, output: any) => {
expect(validateKQLStringFilter(input)).toEqual(output);
});
test.each(dataWithError)('validateKQLStringFilter(%s): %o', (input: any, output: any) => {
expect(validateKQLStringFilter(input)).toContain(output);
});
});
describe('getFormattedGroupBy', () => {

View file

@ -52,10 +52,14 @@ export const validateKQLStringFilter = (value: string) => {
}
try {
kbnBuildEsQuery(undefined, [{ query: value, language: 'kuery' }], []);
kbnBuildEsQuery(undefined, [{ query: value, language: 'kuery' }], [], {
allowLeadingWildcards: true,
queryStringOptions: {},
ignoreFilterIfFieldNotInIndex: false,
});
} catch (e) {
return i18n.translate('xpack.observability.customThreshold.rule.schema.invalidFilterQuery', {
defaultMessage: 'filterQuery must be a valid KQL filter',
defaultMessage: `filterQuery must be a valid KQL filter (error: ${e.message})`,
});
}
};

View file

@ -32674,7 +32674,6 @@
"xpack.observability.customThreshold.rule.reason.forTheLast": "durée : {duration}",
"xpack.observability.customThreshold.rule.reason.group": "groupe : {group}",
"xpack.observability.customThreshold.rule.reasonActionVariableDescription": "Une description concise de la raison du signalement",
"xpack.observability.customThreshold.rule.schema.invalidFilterQuery": "filterQuery doit être un filtre KQL valide",
"xpack.observability.customThreshold.rule.sourceConfiguration.missingHttp": "Échec de chargement de la source : Aucun client HTTP disponible.",
"xpack.observability.customThreshold.rule.sourceConfiguration.updateFailureBody": "Nous n'avons pas pu appliquer les modifications à la configuration des indicateurs. Réessayez plus tard.",
"xpack.observability.customThreshold.rule.sourceConfiguration.updateFailureTitle": "La mise à jour de la configuration a échoué",

View file

@ -32659,7 +32659,6 @@
"xpack.observability.customThreshold.rule.reason.forTheLast": "duration: {duration}",
"xpack.observability.customThreshold.rule.reason.group": "グループ:{group}",
"xpack.observability.customThreshold.rule.reasonActionVariableDescription": "アラートの理由の簡潔な説明",
"xpack.observability.customThreshold.rule.schema.invalidFilterQuery": "filterQueryは有効なKQLフィルターでなければなりません",
"xpack.observability.customThreshold.rule.sourceConfiguration.missingHttp": "ソースの読み込みに失敗しましたHTTPクライアントがありません。",
"xpack.observability.customThreshold.rule.sourceConfiguration.updateFailureBody": "変更をメトリック構成に適用できませんでした。しばらくたってから再試行してください。",
"xpack.observability.customThreshold.rule.sourceConfiguration.updateFailureTitle": "構成の更新が失敗しました",

View file

@ -32699,7 +32699,6 @@
"xpack.observability.customThreshold.rule.reason.forTheLast": "持续时间:{duration}",
"xpack.observability.customThreshold.rule.reason.group": "组:{group}",
"xpack.observability.customThreshold.rule.reasonActionVariableDescription": "告警原因的简洁描述",
"xpack.observability.customThreshold.rule.schema.invalidFilterQuery": "filterQuery 必须是有效的 KQL 筛选",
"xpack.observability.customThreshold.rule.sourceConfiguration.missingHttp": "无法加载源:无 HTTP 客户端可用。",
"xpack.observability.customThreshold.rule.sourceConfiguration.updateFailureBody": "无法对指标配置应用更改。请稍后重试。",
"xpack.observability.customThreshold.rule.sourceConfiguration.updateFailureTitle": "配置更新失败",