From 2fcd323927e42b4e7648f2aaa1a38dd3c7ea3900 Mon Sep 17 00:00:00 2001
From: Elena Stoeva <59341489+ElenaStoeva@users.noreply.github.com>
Date: Wed, 4 Dec 2024 14:48:16 +0000
Subject: [PATCH 1/5] [Console] Add highlighting for painless language
(#202695)
Closes https://github.com/elastic/kibana/issues/201672?reload=1?reload=1
## Summary
This PR adds existing painless rules to the console language so that the
painless scripts are correctly highlighted. We are adding a painless
starting rule that matches a string `"*_script"`, `"inline"`, or
`"source"`, followed by a triple quote, in order to prevent clashing
with the existing rules for triple-quote strings.
Example request with a script:
```
POST _ingest/pipeline/_simulate
{
"pipeline": {
"processors": [
{
"script": {
"description": "Extract 'tags' from 'env' field",
"lang": "painless",
"source": """
String[] envSplit = ctx['env'].splitOnToken(params['delimiter']);
ArrayList tags = new ArrayList();
tags.add(envSplit[params['position']].trim());
ctx['tags'] = tags;
""",
"params": {
"delimiter": "-",
"position": 1
}
}
}
]
},
"docs": [
{
"_source": {
"env": "es01-prod"
}
}
]
}
```
---
.../console/lexer_rules/nested_painless.ts | 71 +++++++++++++++++++
.../src/console/lexer_rules/shared.ts | 14 ++++
2 files changed, 85 insertions(+)
create mode 100644 packages/kbn-monaco/src/console/lexer_rules/nested_painless.ts
diff --git a/packages/kbn-monaco/src/console/lexer_rules/nested_painless.ts b/packages/kbn-monaco/src/console/lexer_rules/nested_painless.ts
new file mode 100644
index 0000000000000..8b4fcda56a64a
--- /dev/null
+++ b/packages/kbn-monaco/src/console/lexer_rules/nested_painless.ts
@@ -0,0 +1,71 @@
+/*
+ * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
+ * License v3.0 only", or the "Server Side Public License, v 1".
+ */
+
+import { lexerRules as painlessLexerRules } from '../../painless/lexer_rules';
+
+/*
+ * This rule is used inside json root to start a painless highlighting sequence
+ */
+export const buildPainlessStartRule = (painlessRoot: string = 'painless_root') => {
+ return [
+ /("(?:[^"]*_)?script"|"inline"|"source")(\s*?)(:)(\s*?)(""")/,
+ [
+ 'variable',
+ 'whitespace',
+ 'punctuation.colon',
+ 'whitespace',
+ {
+ token: 'punctuation',
+ next: `@${painlessRoot}`,
+ },
+ ],
+ ];
+};
+
+/*
+ * This function creates a group of rules needed for painless highlighting in console.
+ * It reuses the lexer rules from the "painless" language, but since not all rules are referenced in the root
+ * tokenizer and to avoid conflicts with existing console rules, only selected rules are used.
+ */
+export const buildPainlessRules = (painlessRoot: string = 'painless_root') => {
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ const { root, comment, string_dq, string_sq } = painlessLexerRules.tokenizer;
+ return {
+ [painlessRoot]: [
+ // the rule to end painless highlighting and get back to the previous tokenizer state
+ [
+ /"""/,
+ {
+ token: 'punctuation',
+ next: '@pop',
+ },
+ ],
+ ...root,
+ ],
+ comment,
+ string_dq,
+ string_sq,
+ };
+};
+
+/*
+ * These language attributes need to be added to the console language definition for painless tokenizer
+ * to work correctly.
+ */
+export const painlessLanguageAttributes = {
+ keywords: painlessLexerRules.keywords,
+ primitives: painlessLexerRules.primitives,
+ constants: painlessLexerRules.constants,
+ operators: painlessLexerRules.operators,
+ symbols: painlessLexerRules.symbols,
+ digits: painlessLexerRules.digits,
+ octaldigits: painlessLexerRules.octaldigits,
+ binarydigits: painlessLexerRules.binarydigits,
+ hexdigits: painlessLexerRules.hexdigits,
+};
diff --git a/packages/kbn-monaco/src/console/lexer_rules/shared.ts b/packages/kbn-monaco/src/console/lexer_rules/shared.ts
index 62c8a28d31c65..b508d5954a3f7 100644
--- a/packages/kbn-monaco/src/console/lexer_rules/shared.ts
+++ b/packages/kbn-monaco/src/console/lexer_rules/shared.ts
@@ -8,6 +8,11 @@
*/
import { buildSqlRules, buildSqlStartRule, sqlLanguageAttributes } from './nested_sql';
+import {
+ buildPainlessRules,
+ buildPainlessStartRule,
+ painlessLanguageAttributes,
+} from './nested_painless';
import { monaco } from '../../..';
import { globals } from '../../common/lexer_rules';
import { buildXjsonRules } from '../../xjson/lexer_rules/xjson';
@@ -16,11 +21,13 @@ export const consoleSharedLanguageConfiguration: monaco.languages.LanguageConfig
brackets: [
['{', '}'],
['[', ']'],
+ ['(', ')'],
['"""', '"""\n'],
],
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
+ { open: '(', close: ')' },
{ open: '"', close: '"' },
{ open: '"""', close: '"""' },
],
@@ -100,10 +107,13 @@ xjsonRules.json_root = [
matchToken('variable.template', /("\${\w+}")/),
// @ts-expect-error include a rule to start sql highlighting
buildSqlStartRule(),
+ // @ts-expect-error include a rule to start painless highlighting
+ buildPainlessStartRule(),
...xjsonRules.json_root,
];
const sqlRules = buildSqlRules();
+const painlessRules = buildPainlessRules();
/*
Lexer rules that are shared between the Console editor and the Console output panel.
*/
@@ -111,6 +121,8 @@ export const consoleSharedLexerRules: monaco.languages.IMonarchLanguage = {
...(globals as any),
defaultToken: 'invalid',
...sqlLanguageAttributes,
+ ...painlessLanguageAttributes,
+ keywords: [...sqlLanguageAttributes.keywords, ...painlessLanguageAttributes.keywords],
tokenizer: {
root: [
// warning comment
@@ -138,5 +150,7 @@ export const consoleSharedLexerRules: monaco.languages.IMonarchLanguage = {
...xjsonRules,
// include sql rules
...sqlRules,
+ // include painless rules
+ ...painlessRules,
},
};
From 3923007251fa360b0d078c192500e91a31037fb6 Mon Sep 17 00:00:00 2001
From: Pierre Gayvallet
Date: Wed, 4 Dec 2024 15:48:38 +0100
Subject: [PATCH 2/5] Fix agents for on-merge AI-Infra test suite (#202946)
## Summary
Add missing explicit agent-targeting rules for newly added pipeline
step.
---
.buildkite/pipelines/on_merge.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.buildkite/pipelines/on_merge.yml b/.buildkite/pipelines/on_merge.yml
index adcd7ef37e6ac..2f1562ef1d741 100644
--- a/.buildkite/pipelines/on_merge.yml
+++ b/.buildkite/pipelines/on_merge.yml
@@ -179,6 +179,9 @@ steps:
timeout_in_minutes: 50
parallelism: 1
agents:
+ image: family/kibana-ubuntu-2004
+ imageProject: elastic-images-prod
+ provider: gcp
machineType: n2-standard-4
preemptible: true
retry:
From 2a7689e693424679c6e870b772e8510d9a25dbd0 Mon Sep 17 00:00:00 2001
From: Bena Kansara <69037875+benakansara@users.noreply.github.com>
Date: Wed, 4 Dec 2024 15:57:05 +0100
Subject: [PATCH 3/5] [RCA] [Events timeline] Show all events (#202235)
As part of https://github.com/elastic/kibana/issues/200799, this PR
removes filter (previously the filter was based on any group by field,
which was changed to focus only on `service.name` for kubecon demo) so
that all events are shown on events timeline.
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Faisal Kanout
---
.../components/events_timeline/events_timeline.tsx | 12 ------------
.../investigate_app/tsconfig.json | 1 -
2 files changed, 13 deletions(-)
diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/events_timeline/events_timeline.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/events_timeline/events_timeline.tsx
index c3f92139bd936..45b245f68b4b0 100644
--- a/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/events_timeline/events_timeline.tsx
+++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/details/components/events_timeline/events_timeline.tsx
@@ -11,9 +11,6 @@ import { Chart, Axis, AreaSeries, Position, ScaleType, Settings } from '@elastic
import { useActiveCursor } from '@kbn/charts-plugin/public';
import { EuiSkeletonText } from '@elastic/eui';
import { getBrushData } from '@kbn/observability-utils-browser/chart/utils';
-import { Group } from '@kbn/observability-alerting-rule-utils';
-import { ALERT_GROUP } from '@kbn/rule-data-utils';
-import { SERVICE_NAME } from '@kbn/observability-shared-plugin/common';
import { AnnotationEvent } from './annotation_event';
import { TIME_LINE_THEME } from './timeline_theme';
import { useFetchEvents } from '../../../../hooks/use_fetch_events';
@@ -27,19 +24,10 @@ export const EventsTimeLine = () => {
const baseTheme = dependencies.start.charts.theme.useChartsBaseTheme();
const { globalParams, updateInvestigationParams } = useInvestigation();
- const { alert } = useInvestigation();
-
- const filter = useMemo(() => {
- const group = (alert?.[ALERT_GROUP] as unknown as Group[])?.find(
- ({ field }) => field === SERVICE_NAME
- );
- return group ? `{"${SERVICE_NAME}":"${alert?.[SERVICE_NAME]}"}` : '';
- }, [alert]);
const { data: events, isLoading } = useFetchEvents({
rangeFrom: globalParams.timeRange.from,
rangeTo: globalParams.timeRange.to,
- filter,
});
const chartRef = useRef(null);
diff --git a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json
index 0851a13367091..bc67b591a57b8 100644
--- a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json
+++ b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json
@@ -66,7 +66,6 @@
"@kbn/calculate-auto",
"@kbn/ml-random-sampler-utils",
"@kbn/charts-plugin",
- "@kbn/observability-alerting-rule-utils",
"@kbn/observability-utils-browser",
"@kbn/usage-collection-plugin",
"@kbn/inference-common",
From 6a4fe4f73dbab778efcd4f329ba9a72a79cf9e3c Mon Sep 17 00:00:00 2001
From: Ying Mao
Date: Wed, 4 Dec 2024 10:09:30 -0500
Subject: [PATCH 4/5] [Response Ops][Alerting] Alerting event logger should not
throw error when ad hoc task runner cannot load saved object (#201637)
## Summary
The ad-hoc task runner loads the `ad_hoc_run` saved object that contains
rule information when it first starts running. If the saved object
cannot be loaded due to saved object not found (likely because the SO
was deleted), the alerting event logger was throwing an error because it
didn't have the rule information to populate the `execute-backfill`
event. This PR fixes it so we're not throwing an error and writes the
`execute-backfill` event with whatever information is available.
## To Verify
1. Modify the ad-hoc task runner to load a random saved object
```
--- a/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.ts
+++ b/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.ts
@@ -294,7 +294,8 @@ export class AdHocTaskRunner implements CancellableTask {
const adHocRunSO: SavedObject =
await this.context.encryptedSavedObjectsClient.getDecryptedAsInternalUser(
AD_HOC_RUN_SAVED_OBJECT_TYPE,
- adHocRunParamsId,
+ `abcdefgh`,
+ // adHocRunParamsId,
{ namespace }
```
2. Create a detection rule and then schedule backfill run for it. You
should see the execution fail with `Executing ad hoc run with id
\"7401d1f1-73fc-4483-acd5-edf6180028ce\" has resulted in Error: Saved
object [ad_hoc_run_params/abcdefgh] not found` but you should NOT see
any errors from task manager like `Task ad_hoc_run-backfill
"40fd4c52-411f-462c-b285-87e33520bd5b" failed: Error:
AlertingEventLogger not initialized`
Co-authored-by: Elastic Machine
---
.../alerting_event_logger.test.ts | 62 +++++++++++++++++++
.../alerting_event_logger.ts | 11 ++--
2 files changed, 67 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.test.ts b/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.test.ts
index 082d5ea6381df..a206f4e058eed 100644
--- a/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.test.ts
+++ b/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.test.ts
@@ -1148,6 +1148,68 @@ describe('AlertingEventLogger', () => {
expect(eventLogger.logEvent).toHaveBeenCalledWith(loggedEvent);
});
+ test('should set fields from backfill even when no rule data is provided', () => {
+ alertingEventLogger.initialize({
+ context: backfillContext,
+ runDate,
+ type: executionType.BACKFILL,
+ });
+
+ alertingEventLogger.done({
+ backfill: {
+ id: 'abc',
+ start: '2024-03-13T00:00:00.000Z',
+ interval: '1h',
+ },
+ status: {
+ lastExecutionDate: new Date('2022-05-05T15:59:54.480Z'),
+ status: 'error',
+ error: {
+ reason: RuleExecutionStatusErrorReasons.Execute,
+ message: 'something went wrong',
+ },
+ },
+ });
+
+ const event = initializeExecuteBackfillRecord(backfillContextWithScheduleDelay, [adHocRunSO]);
+ const loggedEvent = {
+ ...event,
+ event: {
+ ...event?.event,
+ outcome: 'failure',
+ reason: RuleExecutionStatusErrorReasons.Execute,
+ },
+ error: {
+ message: 'something went wrong',
+ },
+ message: 'def: execution failed',
+ kibana: {
+ ...event.kibana,
+ alert: {
+ ...event.kibana?.alert,
+ rule: {
+ ...event.kibana?.alert?.rule,
+ execution: {
+ ...event.kibana?.alert?.rule?.execution,
+ backfill: {
+ id: 'abc',
+ start: '2024-03-13T00:00:00.000Z',
+ interval: '1h',
+ },
+ },
+ },
+ },
+ alerting: {
+ outcome: 'failure',
+ status: 'error',
+ },
+ },
+ };
+
+ expect(alertingEventLogger.getEvent()).toEqual(loggedEvent);
+ expect(eventLogger.logEvent).toHaveBeenCalledWith(loggedEvent);
+ });
+
test('should set fields from execution metrics if provided', () => {
alertingEventLogger.initialize({ context: ruleContext, runDate, ruleData });
alertingEventLogger.done({
diff --git a/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.ts b/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.ts
index 1607f6090b10c..d344a8f2a240b 100644
--- a/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.ts
+++ b/x-pack/plugins/alerting/server/lib/alerting_event_logger/alerting_event_logger.ts
@@ -346,7 +346,7 @@ export class AlertingEventLogger {
}
public done({ status, metrics, timings, backfill }: DoneOpts) {
- if (!this.isInitialized || !this.event || !this.context || !this.ruleData) {
+ if (!this.isInitialized || !this.event || !this.context) {
throw new Error('AlertingEventLogger not initialized');
}
@@ -360,16 +360,15 @@ export class AlertingEventLogger {
updateEvent(this.event, { status: status.status });
if (status.error) {
+ const message = this.ruleData
+ ? `${this.ruleData.type?.id}:${this.context.savedObjectId}: execution failed`
+ : `${this.context.savedObjectId}: execution failed`;
updateEvent(this.event, {
outcome: 'failure',
alertingOutcome: 'failure',
reason: status.error?.reason || 'unknown',
error: this.event?.error?.message || status.error.message,
- ...(this.event.message && this.event.event?.outcome === 'failure'
- ? {}
- : {
- message: `${this.ruleData.type?.id}:${this.context.savedObjectId}: execution failed`,
- }),
+ ...(this.event.message && this.event.event?.outcome === 'failure' ? {} : { message }),
});
} else {
if (status.warning) {
From 72c906b25b8c8ebe430396a610ade0ad7f1d4baa Mon Sep 17 00:00:00 2001
From: Dzmitry Lemechko
Date: Wed, 4 Dec 2024 16:25:09 +0100
Subject: [PATCH 5/5] [skip CI] [ftr] add migration steps for
deployment-agnostic tests (#202913)
## Summary
This PR adds example of tests, that doesn't meet deployment-agnostic
criteria. I also added steps explaining how to migrate existing tests to
DA.
---
.../deployment_agnostic/README.md | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/x-pack/test/api_integration/deployment_agnostic/README.md b/x-pack/test/api_integration/deployment_agnostic/README.md
index 3bc1c70dda1ab..6064d52cdcf6b 100644
--- a/x-pack/test/api_integration/deployment_agnostic/README.md
+++ b/x-pack/test/api_integration/deployment_agnostic/README.md
@@ -9,6 +9,12 @@ A deployment-agnostic API integration test is a test suite that fulfills the fol
A deployment-agnostic test should be loaded in stateful and at least 1 serverless FTR config files.
+## Tests, that are not deployment-agnostic:
+- tests verifying Kibana behavior under a basic license.
+- tests dependent on ES/Kibana server arguments, that are not set in Elastic Cloud
+- tests requiring a custom plugin to be loaded specifically for testing purposes.
+- tests dependent on varying user privileges between serverless and stateful environments.
+
## Tests Design Requirements
A deployment-agnostic test is contained within a single test file and always utilizes the [DeploymentAgnosticFtrProviderContext](https://github.com/elastic/kibana/blob/main/x-pack/test/api_integration/deployment_agnostic/ftr_provider_context.d.ts) to load compatible FTR services. A compatible FTR service must support:
@@ -243,3 +249,15 @@ node scripts/functional_test_runner --config x-pack/test/api_integration/deploym
Since deployment-agnostic tests are designed to run both locally and on MKI/Cloud, we believe no extra tagging is required. If a test is not working on MKI/Cloud or both, there is most likely an issue with the FTR service or the configuration file it uses.
When a test fails on CI, automation will apply `.skip` to the top-level describe block. This means the test will be skipped in **both serverless and stateful environments**. If a test is unstable in a specific environment only, it is probably a sign that the test is not truly deployment-agnostic.
+
+## Migrating existing tests
+If your tests align with the outlined criteria and requirements, you can migrate them to deployment-agnostic by following these steps:
+
+1. Move your tests to the `x-pack/test/api_integration/deployment_agnostic/apis/` directory.
+2. Update each test file to use the `DeploymentAgnosticFtrProviderContext` context and load the required FTR services it provides.
+3. Ensure the `roleScopedSupertest` or `samlAuth` service is used instead for `supertest` for authentication and test API calls.
+4. Remove all usage of the `supertest` service. It is authenticated as system index superuser and often causes test failures on Cloud, where priveleges are more strict.
+5. Avoid modifying `config` files, as this could disrupt test runs in Cloud environments.
+6. Include your tests in both the platform and at least one solution index file.
+7. Execute your tests locally against a local environment.
+8. Verify your tests by running them locally against a real MKI project and an ESS deployment to ensure full compatibility.