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" } } ] } ``` Screenshot 2024-12-03 at 12 02 52 --- .../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.