From 462e4378100e8d5233e7379f9244da5609b7dd2c Mon Sep 17 00:00:00 2001 From: Drew Tate Date: Mon, 16 Sep 2024 02:24:55 -0600 Subject: [PATCH 001/139] [ES|QL] exclude inactive integration data stream suggestions (#192953) ## Summary Close https://github.com/elastic/kibana/issues/187247 https://github.com/user-attachments/assets/9f56d941-016a-442a-a2cb-b2240b280b54 Co-authored-by: Stratoula Kalafateli --- packages/kbn-text-based-editor/src/helpers.ts | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/kbn-text-based-editor/src/helpers.ts b/packages/kbn-text-based-editor/src/helpers.ts index f83d7a97342e6..fb541c4fe39be 100644 --- a/packages/kbn-text-based-editor/src/helpers.ts +++ b/packages/kbn-text-based-editor/src/helpers.ts @@ -249,20 +249,22 @@ const getIntegrations = async (core: CoreStart) => { // and this needs to be done in various places in the codebase which use the editor // https://github.com/elastic/kibana/issues/186061 const response = (await core.http - .get(INTEGRATIONS_API, { query: undefined, version: API_VERSION }) + .get(INTEGRATIONS_API, { query: { showOnlyActiveDataStreams: true }, version: API_VERSION }) .catch((error) => { // eslint-disable-next-line no-console console.error('Failed to fetch integrations', error); })) as IntegrationsResponse; return ( - response?.items?.map((source) => ({ - name: source.name, - hidden: false, - title: source.title, - dataStreams: source.dataStreams, - type: 'Integration', - })) ?? [] + response?.items + ?.filter(({ dataStreams }) => dataStreams.length) + .map((source) => ({ + name: source.name, + hidden: false, + title: source.title, + dataStreams: source.dataStreams, + type: 'Integration', + })) ?? [] ); }; From bce4a17f088969621ade141a8d19ff3fcde833b0 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Mon, 16 Sep 2024 10:43:12 +0200 Subject: [PATCH 002/139] [CI] Archive logs from `yarn es` docker runs (#189231) ## Summary The problem we're trying to solve here is to get access to `elasticsearch-serverless` logs when they're started in docker containers in the background (and `elasticsearch`, although currently we don't test against that in docker for now). ## Solution In essence: - we needed to remove the `--rm` flag, this would allow for the containers to stay present after they're done. - after this, we can run `docker logs ...` on FTR post-hooks, save these, then archive these files to buildkite - because the containers are not removed upon finishing, we need to clean up dangling containers before starting up Backporting is probably not necessary, because this is only applicable for serverless - and serverless is only supposed to run on main. Solves: https://github.com/elastic/kibana/issues/191505 --- .buildkite/scripts/lifecycle/post_command.sh | 1 + packages/kbn-es/src/utils/docker.test.ts | 6 +- packages/kbn-es/src/utils/docker.ts | 43 +++++++---- .../src/utils/extract_and_archive_logs.ts | 73 +++++++++++++++++++ packages/kbn-es/src/utils/index.ts | 1 + .../functional_tests/lib/run_elasticsearch.ts | 4 +- 6 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 packages/kbn-es/src/utils/extract_and_archive_logs.ts diff --git a/.buildkite/scripts/lifecycle/post_command.sh b/.buildkite/scripts/lifecycle/post_command.sh index 26578f9b9cce1..f90a4b451be1f 100755 --- a/.buildkite/scripts/lifecycle/post_command.sh +++ b/.buildkite/scripts/lifecycle/post_command.sh @@ -35,6 +35,7 @@ if [[ "$IS_TEST_EXECUTION_STEP" == "true" ]]; then buildkite-agent artifact upload 'x-pack/test/functional/failure_debug/html/*.html' buildkite-agent artifact upload '.es/**/*.hprof' buildkite-agent artifact upload 'data/es_debug_*.tar.gz' + buildkite-agent artifact upload '.es/es*.log' if [[ $BUILDKITE_COMMAND_EXIT_STATUS -ne 0 ]]; then if [[ $BUILDKITE_TRIGGERED_FROM_BUILD_PIPELINE_SLUG == 'elasticsearch-serverless-intake' ]]; then diff --git a/packages/kbn-es/src/utils/docker.test.ts b/packages/kbn-es/src/utils/docker.test.ts index a128db03d6ad2..93dee967ee8ac 100644 --- a/packages/kbn-es/src/utils/docker.test.ts +++ b/packages/kbn-es/src/utils/docker.test.ts @@ -665,12 +665,13 @@ describe('runServerlessCluster()', () => { // docker version (1) // docker ps (1) + // docker container rm (3) // docker network create (1) // docker pull (1) // docker inspect (1) // docker run (3) // docker logs (1) - expect(execa.mock.calls).toHaveLength(9); + expect(execa.mock.calls).toHaveLength(12); }); test(`should wait for serverless nodes to return 'green' status`, async () => { @@ -806,11 +807,12 @@ describe('runDockerContainer()', () => { await expect(runDockerContainer(log, {})).resolves.toBeUndefined(); // docker version (1) // docker ps (1) + // docker container rm (3) // docker network create (1) // docker pull (1) // docker inspect (1) // docker run (1) - expect(execa.mock.calls).toHaveLength(6); + expect(execa.mock.calls).toHaveLength(9); }); }); diff --git a/packages/kbn-es/src/utils/docker.ts b/packages/kbn-es/src/utils/docker.ts index c36ed5e8a4bae..6120cc2af0561 100644 --- a/packages/kbn-es/src/utils/docker.ts +++ b/packages/kbn-es/src/utils/docker.ts @@ -113,8 +113,6 @@ const DOCKER_REGISTRY = 'docker.elastic.co'; const DOCKER_BASE_CMD = [ 'run', - '--rm', - '-t', '--net', @@ -151,8 +149,6 @@ export const ES_SERVERLESS_DEFAULT_IMAGE = `${ES_SERVERLESS_REPO_KIBANA}:${ES_SE const SHARED_SERVERLESS_PARAMS = [ 'run', - '--rm', - '--detach', '--interactive', @@ -391,7 +387,6 @@ const RETRYABLE_DOCKER_PULL_ERROR_MESSAGES = [ ]; /** - * * Pull a Docker image if needed. Ensures latest image. * Stops serverless from pulling the same image in each node's promise and * gives better control of log output, instead of falling back to docker run. @@ -443,6 +438,24 @@ export async function printESImageInfo(log: ToolingLog, image: string) { log.info(`Using ES image: ${imageFullName} (${revisionUrl})`); } +export async function cleanUpDanglingContainers(log: ToolingLog) { + log.info(chalk.bold('Cleaning up dangling Docker containers.')); + + try { + const serverlessContainerNames = SERVERLESS_NODES.map(({ name }) => name); + + for (const name of serverlessContainerNames) { + await execa('docker', ['container', 'rm', name, '--force']).catch(() => { + // Ignore errors if the container doesn't exist + }); + } + + log.success('Cleaned up dangling Docker containers.'); + } catch (e) { + log.error(e); + } +} + export async function detectRunningNodes( log: ToolingLog, options: ServerlessOptions | DockerOptions @@ -454,19 +467,19 @@ export async function detectRunningNodes( }, []); const { stdout } = await execa('docker', ['ps', '--quiet'].concat(namesCmd)); - const runningNodes = stdout.split(/\r?\n/).filter((s) => s); + const runningNodeIds = stdout.split(/\r?\n/).filter((s) => s); - if (runningNodes.length) { + if (runningNodeIds.length) { if (options.kill) { log.info(chalk.bold('Killing running ES Nodes.')); - await execa('docker', ['kill'].concat(runningNodes)); - - return; + await execa('docker', ['kill'].concat(runningNodeIds)); + } else { + throw createCliError( + 'ES has already been started, pass --kill to automatically stop the nodes on startup.' + ); } - - throw createCliError( - 'ES has already been started, pass --kill to automatically stop the nodes on startup.' - ); + } else { + log.info('No running nodes detected.'); } } @@ -484,6 +497,7 @@ async function setupDocker({ }) { await verifyDockerInstalled(log); await detectRunningNodes(log, options); + await cleanUpDanglingContainers(log); await maybeCreateDockerNetwork(log); await maybePullDockerImage(log, image); await printESImageInfo(log, image); @@ -774,6 +788,7 @@ export async function runServerlessCluster(log: ToolingLog, options: ServerlessO const volumeCmd = await setupServerlessVolumes(log, options); const portCmd = resolvePort(options); + // This is where nodes are started const nodeNames = await Promise.all( SERVERLESS_NODES.map(async (node, i) => { await runServerlessEsNode(log, { diff --git a/packages/kbn-es/src/utils/extract_and_archive_logs.ts b/packages/kbn-es/src/utils/extract_and_archive_logs.ts new file mode 100644 index 0000000000000..28dde547f6b0d --- /dev/null +++ b/packages/kbn-es/src/utils/extract_and_archive_logs.ts @@ -0,0 +1,73 @@ +/* + * 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 type { ToolingLog } from '@kbn/tooling-log'; + +import execa from 'execa'; +import Fsp from 'fs/promises'; +import { join } from 'path'; + +import { REPO_ROOT } from '@kbn/repo-info'; + +/** + * Extracts logs from Docker nodes, writes them to files, and returns the file paths. + */ +export async function extractAndArchiveLogs({ + outputFolder, + log, + nodeNames, +}: { + log: ToolingLog; + nodeNames?: string[]; + outputFolder?: string; +}) { + outputFolder = outputFolder || join(REPO_ROOT, '.es'); + const logFiles: string[] = []; + + if (!nodeNames) { + const { stdout: nodeNamesString } = await execa('docker', [ + 'ps', + '-a', + '--format', + '{{.Names}}', + ]); + nodeNames = nodeNamesString.split('\n').filter(Boolean); + } + + if (!nodeNames.length) { + log.info('No Docker nodes found to extract logs from'); + return; + } else { + log.info(`Attempting to extract logs from Docker nodes to ${outputFolder}`); + } + + for (const name of nodeNames) { + const { stdout: nodeId } = await execa('docker', [ + 'ps', + '-a', + '--quiet', + '--filter', + `name=${name}`, + ]); + if (!nodeId) { + continue; + } + + const { stdout } = await execa('docker', ['logs', name]); + const targetFile = `${name}-${nodeId}.log`; + const targetPath = join(outputFolder, targetFile); + + await Fsp.writeFile(targetPath, stdout); + logFiles.push(targetFile); + + log.info(`Archived logs for ${name} to ${targetPath}`); + } + + return logFiles; +} diff --git a/packages/kbn-es/src/utils/index.ts b/packages/kbn-es/src/utils/index.ts index dd57c54d4a101..e1a51ecb44685 100644 --- a/packages/kbn-es/src/utils/index.ts +++ b/packages/kbn-es/src/utils/index.ts @@ -20,3 +20,4 @@ export * from './parse_timeout_to_ms'; export * from './docker'; export * from './serverless_file_realm'; export * from './read_roles_from_resource'; +export * from './extract_and_archive_logs'; diff --git a/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts b/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts index c87065fd1cdaf..724cf5bc2b25e 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts +++ b/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts @@ -13,7 +13,7 @@ import type { ToolingLog } from '@kbn/tooling-log'; import getPort from 'get-port'; import { REPO_ROOT } from '@kbn/repo-info'; import type { ArtifactLicense, ServerlessProjectType } from '@kbn/es'; -import { isServerlessProjectType } from '@kbn/es/src/utils'; +import { isServerlessProjectType, extractAndArchiveLogs } from '@kbn/es/src/utils'; import type { Config } from '../../functional_test_runner'; import { createTestEsCluster, esTestConfig } from '../../es'; @@ -91,6 +91,7 @@ export async function runElasticsearch( }); return async () => { await node.cleanup(); + await extractAndArchiveLogs({ outputFolder: logsDir, log }); }; } @@ -119,6 +120,7 @@ export async function runElasticsearch( return async () => { await localNode.cleanup(); await remoteNode.cleanup(); + await extractAndArchiveLogs({ outputFolder: logsDir, log }); }; } From 708a96cca8f636347fb37669b13e5b61cd5015d1 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 16 Sep 2024 10:44:55 +0200 Subject: [PATCH 003/139] [ES|QL] Set drop null columns param correctly for partial results (#192666) ## Summary Closes https://github.com/elastic/kibana/issues/192595 We were not setting the `drop_null_columns ` queryString for partial results and as a result it was returning the empty columns only for the initial request, resulting in the weirdness that is being described in the issue. --- .../esql_async_search_strategy.ts | 2 +- .../functional/apps/discover/group6/_sidebar.ts | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts b/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts index ac337d237c89b..83b67e5ecb4fd 100644 --- a/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts @@ -79,7 +79,7 @@ export const esqlAsyncSearchStrategyProvider = ( { method: 'GET', path: `/_query/async/${id}`, - querystring: { ...params }, + querystring: { ...params, drop_null_columns: dropNullColumns }, }, { ...options.transport, signal: options.abortSignal, meta: true } ) diff --git a/test/functional/apps/discover/group6/_sidebar.ts b/test/functional/apps/discover/group6/_sidebar.ts index 3e746a3726bcc..51066cd3c04e0 100644 --- a/test/functional/apps/discover/group6/_sidebar.ts +++ b/test/functional/apps/discover/group6/_sidebar.ts @@ -114,12 +114,17 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { options = await find.allByCssSelector('[data-test-subj*="typeFilter"]'); expect(options).to.have.length(6); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be('82 available fields.'); + expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + '76 available fields. 6 empty fields.' + ); await testSubjects.click('typeFilter-number'); await retry.waitFor('updates', async () => { - return (await unifiedFieldList.getSidebarAriaDescription()) === '6 available fields.'; + return ( + (await unifiedFieldList.getSidebarAriaDescription()) === + '4 available fields. 2 empty fields.' + ); }); }); @@ -446,12 +451,16 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await header.waitUntilLoadingHasFinished(); await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be('82 available fields.'); + expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + '76 available fields. 6 empty fields.' + ); await unifiedFieldList.clickFieldListItemRemove('extension'); await unifiedFieldList.waitUntilSidebarHasLoaded(); - expect(await unifiedFieldList.getSidebarAriaDescription()).to.be('82 available fields.'); + expect(await unifiedFieldList.getSidebarAriaDescription()).to.be( + '76 available fields. 6 empty fields.' + ); const testQuery = `from logstash-* | limit 10 | stats countB = count(bytes) by geo.dest | sort countB`; From 08b682fbd5f78ac82b42ddc7109e79f89e4ed961 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Mon, 16 Sep 2024 11:06:54 +0200 Subject: [PATCH 004/139] OpenAI: Ignore chunks with an empty `choices` list (bis) (#192961) ## Summary Follow-up of https://github.com/elastic/kibana/pull/192951 to address the missing bits (given I don't know how to grep) --- .../actions/server/lib/get_token_count_from_invoke_stream.ts | 4 +++- x-pack/plugins/elastic_assistant/server/lib/parse_stream.ts | 4 +++- .../common/utils/process_openai_stream.ts | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts b/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts index 604e623699136..909b7e09abda0 100644 --- a/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts +++ b/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts @@ -288,7 +288,9 @@ const parseOpenAIResponse = (responseBody: string) => delta: { content?: string; function_call?: { name?: string; arguments: string } }; }>; } => { - return 'object' in line && line.object === 'chat.completion.chunk'; + return ( + 'object' in line && line.object === 'chat.completion.chunk' && line.choices.length > 0 + ); } ) .reduce((prev, line) => { diff --git a/x-pack/plugins/elastic_assistant/server/lib/parse_stream.ts b/x-pack/plugins/elastic_assistant/server/lib/parse_stream.ts index 55be80cbb522d..3aef870be8116 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/parse_stream.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/parse_stream.ts @@ -85,7 +85,9 @@ const parseOpenAIResponse = (responseBody: string) => delta: { content?: string; function_call?: { name?: string; arguments: string } }; }>; } => { - return 'object' in line && line.object === 'chat.completion.chunk'; + return ( + 'object' in line && line.object === 'chat.completion.chunk' && line.choices.length > 0 + ); } ) .reduce((prev, line) => { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/process_openai_stream.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/process_openai_stream.ts index 11fe48721812c..184b4817abf64 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/process_openai_stream.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/utils/process_openai_stream.ts @@ -42,7 +42,7 @@ export function processOpenAiStream(logger: Logger) { }), filter( (line): line is CreateChatCompletionResponseChunk => - 'object' in line && line.object === 'chat.completion.chunk' + 'object' in line && line.object === 'chat.completion.chunk' && line.choices.length > 0 ), map((chunk): ChatCompletionChunkEvent => { const delta = chunk.choices[0].delta; From 2b12950e71f6cc7a616eeec1e787e76f3009575c Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Mon, 16 Sep 2024 11:51:49 +0200 Subject: [PATCH 005/139] [EDR Workflows][MKI] Skip event_filters.cy.ts in MKI (#192969) Skip due to interactions with internal indices which is not supported in MKI --- .../management/cypress/e2e/artifacts/event_filters.cy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/event_filters.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/event_filters.cy.ts index 469f3162a47df..af7310953e86e 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/event_filters.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/event_filters.cy.ts @@ -17,7 +17,8 @@ import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { login } from '../../tasks/login'; import type { ReturnTypeFromChainable } from '../../types'; -describe('Event Filters', { tags: ['@ess', '@serverless'] }, () => { +// Skipped in Serverless MKI due to interactions with internal indices +describe('Event Filters', { tags: ['@ess', '@serverless', '@skipInServerlessMKI'] }, () => { let endpointData: ReturnTypeFromChainable | undefined; const CONDITION_VALUE = 'valuesAutocompleteMatch'; From a581087f530ce4a9143d54d76147b7b645a39da4 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Mon, 16 Sep 2024 12:03:58 +0200 Subject: [PATCH 006/139] [ES|QL] Enable cursor sync for timeseries charts (#192837) ## Summary Syncs the cursor for timeseries charts powered by ES|QL ![meow](https://github.com/user-attachments/assets/62664b27-ce95-493d-863a-b5ecaa8006ed) ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Marco Vettorello --- .../active_cursor/active_cursor_utils.test.ts | 33 +++++++++++++++++++ .../active_cursor/active_cursor_utils.ts | 11 +++++++ src/plugins/charts/tsconfig.json | 1 + 3 files changed, 45 insertions(+) diff --git a/src/plugins/charts/public/services/active_cursor/active_cursor_utils.test.ts b/src/plugins/charts/public/services/active_cursor/active_cursor_utils.test.ts index 31f139eb41a4f..65b6ac7c408ee 100644 --- a/src/plugins/charts/public/services/active_cursor/active_cursor_utils.test.ts +++ b/src/plugins/charts/public/services/active_cursor/active_cursor_utils.test.ts @@ -137,6 +137,39 @@ describe('active_cursor_utils', () => { } `); }); + + test('should return isDateHistogram true in case the datatable is powered by ES|QL', () => { + expect( + parseSyncOptions({ + datatables: [ + { + columns: [ + { + id: 'timestamp', + meta: { + type: 'date', + }, + }, + { + id: 'count', + meta: { + type: 'number', + }, + }, + ], + meta: { + type: 'es_ql', + }, + }, + ] as unknown as Datatable[], + }) + ).toMatchInlineSnapshot(` + Object { + "accessors": Array [], + "isDateHistogram": true, + } + `); + }); }); }); }); diff --git a/src/plugins/charts/public/services/active_cursor/active_cursor_utils.ts b/src/plugins/charts/public/services/active_cursor/active_cursor_utils.ts index c2126e5efdc2b..8c7fd434a5c08 100644 --- a/src/plugins/charts/public/services/active_cursor/active_cursor_utils.ts +++ b/src/plugins/charts/public/services/active_cursor/active_cursor_utils.ts @@ -10,6 +10,7 @@ import { uniq } from 'lodash'; import type { Datatable } from '@kbn/expressions-plugin/public'; +import { ESQL_TABLE_TYPE } from '@kbn/data-plugin/common'; import type { ActiveCursorSyncOption, DateHistogramSyncOption } from './types'; import type { ActiveCursorPayload } from './types'; @@ -20,6 +21,16 @@ function isDateHistogramSyncOption( } const parseDatatable = (dataTables: Datatable[]) => { + const isEsqlMode = dataTables.some((t) => t?.meta?.type === ESQL_TABLE_TYPE); + + if (isEsqlMode) { + return { + isDateHistogram: + Boolean(dataTables.length) && + dataTables.every((t) => t.columns.some((c) => c.meta.type === 'date')), + accessors: [], + }; + } const isDateHistogram = Boolean(dataTables.length) && dataTables.every((dataTable) => diff --git a/src/plugins/charts/tsconfig.json b/src/plugins/charts/tsconfig.json index 42bbe987f45fa..8ad33a8517031 100644 --- a/src/plugins/charts/tsconfig.json +++ b/src/plugins/charts/tsconfig.json @@ -15,6 +15,7 @@ "@kbn/ui-theme", "@kbn/shared-ux-utility", "@kbn/config-schema", + "@kbn/data-plugin", ], "exclude": [ "target/**/*", From b89314ee70e35c0b4ea44dc4c581a9442f6e9431 Mon Sep 17 00:00:00 2001 From: "elastic-renovate-prod[bot]" <174716857+elastic-renovate-prod[bot]@users.noreply.github.com> Date: Mon, 16 Sep 2024 05:33:29 -0500 Subject: [PATCH 007/139] Update dependency @launchdarkly/node-server-sdk to ^9.5.4 (main) (#192138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@launchdarkly/node-server-sdk](https://togithub.com/launchdarkly/js-core/tree/main/packages/sdk/server-node) ([source](https://togithub.com/launchdarkly/js-core)) | dependencies | patch | [`^9.5.1` -> `^9.5.4`](https://renovatebot.com/diffs/npm/@launchdarkly%2fnode-server-sdk/9.5.1/9.5.4) | --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://togithub.com/renovatebot/renovate). Co-authored-by: elastic-renovate-prod[bot] <174716857+elastic-renovate-prod[bot]@users.noreply.github.com> Co-authored-by: Jean-Louis Leysens --- package.json | 2 +- yarn.lock | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 5aec5cd34dde8..760268042a27b 100644 --- a/package.json +++ b/package.json @@ -987,7 +987,7 @@ "@langchain/langgraph": "0.0.34", "@langchain/openai": "^0.1.3", "@langtrase/trace-attributes": "^3.0.8", - "@launchdarkly/node-server-sdk": "^9.5.1", + "@launchdarkly/node-server-sdk": "^9.5.4", "@loaders.gl/core": "^3.4.7", "@loaders.gl/json": "^3.4.7", "@loaders.gl/shapefile": "^3.4.7", diff --git a/yarn.lock b/yarn.lock index 41799c20a1def..b86acda2e0739 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7309,25 +7309,25 @@ dependencies: ncp "^2.0.0" -"@launchdarkly/js-sdk-common@2.6.0": - version "2.6.0" - resolved "https://registry.yarnpkg.com/@launchdarkly/js-sdk-common/-/js-sdk-common-2.6.0.tgz#3382051d282a413c8f30e10108eee25172fdbf22" - integrity sha512-3zbwXZ0JM9i9pktTbjp+CRFMSXf6tZPJPuW3QtqC/qUYbNS8/+JmanO4tfNgSZHar7HUXD9Vy0OTCBqSRw2LWg== +"@launchdarkly/js-sdk-common@2.8.0": + version "2.8.0" + resolved "https://registry.yarnpkg.com/@launchdarkly/js-sdk-common/-/js-sdk-common-2.8.0.tgz#f9a0c29864ba52e5dc19f273164780005be5c8ab" + integrity sha512-XLYhB0A0vec1gwbnVNU+rzMd1JxdtMJXSA76y3ASJ6X0cG0qTRKQdFba4n4RwIs0y1bX3rncFHJMhBjrXtyPhA== -"@launchdarkly/js-server-sdk-common@2.4.5": - version "2.4.5" - resolved "https://registry.yarnpkg.com/@launchdarkly/js-server-sdk-common/-/js-server-sdk-common-2.4.5.tgz#28ebd7838e1d90274bd50136ded965c36753a5fb" - integrity sha512-v4/g6SBO6NDFD9UyP/YKUkbxXNJyBn3Suu/zvz7dHDVlucsryPpGw9TBFkJC6V6i3ACfMAyW14eNulRFP2gvNA== +"@launchdarkly/js-server-sdk-common@2.6.1": + version "2.6.1" + resolved "https://registry.yarnpkg.com/@launchdarkly/js-server-sdk-common/-/js-server-sdk-common-2.6.1.tgz#e676641c83d8dcc0e9afa8620dd5142eae873127" + integrity sha512-PcyglkUi/P1fBT3GqwZ/K9MvLj2e5Rw5XLP/gC2qIIHJxIbni8oy8Zon+6bP890DYgZtqqeX6tKhAw/gwOYkhQ== dependencies: - "@launchdarkly/js-sdk-common" "2.6.0" + "@launchdarkly/js-sdk-common" "2.8.0" semver "7.5.4" -"@launchdarkly/node-server-sdk@^9.5.1": - version "9.5.1" - resolved "https://registry.yarnpkg.com/@launchdarkly/node-server-sdk/-/node-server-sdk-9.5.1.tgz#8c1dc68076c6d055ab39dfd0af55284149fb95db" - integrity sha512-EfxgCjtZk1wpiv/89pHG5WBeyRLhCFQIgBc2GMUwFTgE7otzrFM6te0YsRYYMJs1Xv2h9LVR6KXDbxL0R+g4VQ== +"@launchdarkly/node-server-sdk@^9.5.4": + version "9.5.4" + resolved "https://registry.yarnpkg.com/@launchdarkly/node-server-sdk/-/node-server-sdk-9.5.4.tgz#7d27456b503c72e05a917873289b94058b49e566" + integrity sha512-1cGKlRP9YY4kgoGhw5Lolv1CoGOH5ywBB++4iqy00PTinyIjbX3LeYrlCWFT3gFrVlmTuc2BoXJvo93qFgkGAA== dependencies: - "@launchdarkly/js-server-sdk-common" "2.4.5" + "@launchdarkly/js-server-sdk-common" "2.6.1" https-proxy-agent "^5.0.1" launchdarkly-eventsource "2.0.3" From 4d692ad25fdfb351a6f3eea6c1af604f7b1a66c2 Mon Sep 17 00:00:00 2001 From: Giorgos Bamparopoulos Date: Mon, 16 Sep 2024 14:25:54 +0300 Subject: [PATCH 008/139] Removing debug logs from setup and start functions (#192884) Removing debug logs from setup and start functions Co-authored-by: Elastic Machine --- .../observability_solution/dataset_quality/server/plugin.ts | 4 ---- .../observability_onboarding/server/plugin.ts | 3 --- 2 files changed, 7 deletions(-) diff --git a/x-pack/plugins/observability_solution/dataset_quality/server/plugin.ts b/x-pack/plugins/observability_solution/dataset_quality/server/plugin.ts index ff2826a30051e..5a1b7b947641e 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/server/plugin.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/server/plugin.ts @@ -27,8 +27,6 @@ export class DatasetQualityServerPlugin implements Plugin { core: CoreSetup, plugins: DatasetQualityPluginSetupDependencies ) { - this.logger.debug('dataset_quality: Setup'); - const resourcePlugins = mapValues(plugins, (value, key) => { return { setup: value, @@ -59,8 +57,6 @@ export class DatasetQualityServerPlugin implements Plugin { } start() { - this.logger.debug('dataset_quality: Started'); - return {}; } } diff --git a/x-pack/plugins/observability_solution/observability_onboarding/server/plugin.ts b/x-pack/plugins/observability_solution/observability_onboarding/server/plugin.ts index c686a500e86e3..ccb260a002cf2 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/server/plugin.ts +++ b/x-pack/plugins/observability_solution/observability_onboarding/server/plugin.ts @@ -53,7 +53,6 @@ export class ObservabilityOnboardingPlugin >, plugins: ObservabilityOnboardingPluginSetupDependencies ) { - this.logger.debug('observability_onboarding: Setup'); this.esLegacyConfigService.setup(core.elasticsearch.legacy.config$); core.savedObjects.registerType(observabilityOnboardingFlow); @@ -109,8 +108,6 @@ export class ObservabilityOnboardingPlugin } public start(core: CoreStart) { - this.logger.debug('observability_onboarding: Started'); - return {}; } From f3535e9838e675ded589f34d4b0839f1804b21b4 Mon Sep 17 00:00:00 2001 From: Marco Vettorello Date: Mon, 16 Sep 2024 13:30:24 +0200 Subject: [PATCH 009/139] [Lens][ColorMapping] Fix color mapping nitpicks (#192242) ## Summary Fixed the edit button color. I've removed completely the `cursor:pointer` and the click handler/capability over the color band (`EuiColorPaletteDisplay` component) because this component is not a button and is not keyboard accessible even with the click handler. It should be changed in EUI to button to be used correctly. fix https://github.com/elastic/kibana/issues/191878 --- .../shared_components/coloring/palette_panel_container.tsx | 7 ++++++- .../shared_components/setting_with_sibling_flyout.tsx | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx index 0b394ec638d69..2cd066acc6617 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx @@ -9,8 +9,9 @@ import { i18n } from '@kbn/i18n'; import React, { MutableRefObject } from 'react'; import { EuiButtonIcon, EuiFlexItem, EuiColorPaletteDisplay, EuiToolTip } from '@elastic/eui'; import { FIXED_PROGRESSION } from '@kbn/coloring'; -import { SettingWithSiblingFlyout } from '../setting_with_sibling_flyout'; +import { css } from '@emotion/react'; +import { SettingWithSiblingFlyout } from '../setting_with_sibling_flyout'; export function PalettePanelContainer(props: { palette: string[]; siblingRef: MutableRefObject; @@ -30,6 +31,9 @@ export function PalettePanelContainer(props: { palette={props.palette} type={FIXED_PROGRESSION} onClick={onClick} + css={css` + cursor: pointer; + `} /> @@ -46,6 +50,7 @@ export function PalettePanelContainer(props: { iconType="controlsHorizontal" onClick={onClick} size="xs" + color="text" /> diff --git a/x-pack/plugins/lens/public/shared_components/setting_with_sibling_flyout.tsx b/x-pack/plugins/lens/public/shared_components/setting_with_sibling_flyout.tsx index 2bcb6a71bf541..fed4702e697b9 100644 --- a/x-pack/plugins/lens/public/shared_components/setting_with_sibling_flyout.tsx +++ b/x-pack/plugins/lens/public/shared_components/setting_with_sibling_flyout.tsx @@ -64,7 +64,7 @@ export function SettingWithSiblingFlyout({ }, [isInlineEditing, isFlyoutOpen]); return ( - + {isFlyoutOpen && siblingRef.current && ( From f168fb4791eea611053683150329115def854826 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Mon, 16 Sep 2024 14:41:19 +0300 Subject: [PATCH 010/139] [Cloud Security] Populate Missing Fields in Vulnerabilities Flyout --- .../schemas/csp_vulnerability_finding.ts | 10 +-- .../_mocks_/vulnerability.mock.ts | 72 +++++++++++++++++++ .../pages/vulnerabilities/test_subjects.ts | 2 + .../vulnerability_finding_flyout.test.tsx | 23 +++++- .../vulnerability_overview_tab.tsx | 50 ++++++++----- 5 files changed, 130 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/csp_vulnerability_finding.ts b/x-pack/plugins/cloud_security_posture/common/schemas/csp_vulnerability_finding.ts index d47cef89d546e..10b3dbb96b1d3 100644 --- a/x-pack/plugins/cloud_security_posture/common/schemas/csp_vulnerability_finding.ts +++ b/x-pack/plugins/cloud_security_posture/common/schemas/csp_vulnerability_finding.ts @@ -71,15 +71,15 @@ export interface CspVulnerabilityFinding { commit_time: string; }; package: { - version: string; - name: string; + version?: string; + name?: string; fixed_version?: string; }; data_stream: { dataset: string }; } export interface Vulnerability { - published_date: string; + published_date?: string; score?: { version?: string; base?: number; @@ -89,12 +89,12 @@ export interface Vulnerability { title: string; reference: string; severity?: VulnSeverity; - cvss: { + cvss?: { nvd: VectorScoreBase; redhat?: VectorScoreBase; ghsa?: VectorScoreBase; }; - data_source: { + data_source?: { ID: string; Name: string; URL: string; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/_mocks_/vulnerability.mock.ts b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/_mocks_/vulnerability.mock.ts index 5df5f398b7fb6..e66f9b33d7e91 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/_mocks_/vulnerability.mock.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/_mocks_/vulnerability.mock.ts @@ -90,3 +90,75 @@ export const mockVulnerabilityHit: CspVulnerabilityFinding = { dataset: 'cloud_security_posture.vulnerabilities', }, }; +export const mockWizVulnerabilityHit: CspVulnerabilityFinding = { + '@timestamp': '2023-03-30T10:27:35.013Z', + resource: { name: '634yfsdg2.dkr.ecr.eu-central-1.amazon.stage', id: 'ami_12328' }, + agent: { + name: 'ip-172-31-33-74', + type: 'cloudbeat', + version: '8.8.0', + ephemeral_id: '49f19e6a-94e9-4f2b-81e3-2f3794a74068', + id: 'd0313a94-c168-4d95-b1f0-97a388dac29a', + }, + cloud: { + availability_zone: 'eu-west-1c', + service: { name: 'EC2' }, + account: { id: '704479110758' }, + image: { id: 'ami-02dc8dbcc971f2c74' }, + provider: 'aws', + instance: { id: 'i-0fb7759c6e5d400cf' }, + machine: { type: 'c6g.medium' }, + region: 'eu-west-1', + }, + package: { fixed_version: '0.4.0', version: 'v0.2.0', name: 'golang.org/x/net' }, + vulnerability: { + enumeration: 'CVE', + description: + 'An attacker can cause excessive memory growth in a Go server accepting HTTP/2 requests. HTTP/2 server connections contain a cache of HTTP header keys sent by the client. While the total number of entries in this cache is capped, an attacker sending very large keys can cause the server to allocate approximately 64 MiB per open connection.', + title: + 'golang: net/http: An attacker can cause excessive memory growth in a Go server accepting HTTP/2 requests', + reference: 'https://avd.aquasec.com/nvd/cve-2022-41717', + severity: 'MEDIUM', + scanner: { vendor: 'Trivy' }, + score: { base: 5.3, version: '3.0' }, + cwe: ['CWE-770'], + id: 'CVE-2022-41717', + classification: 'CVSS', + }, + cloudbeat: { + commit_sha: 'b5c4b728f0a9268e7f2d195c00dad0320c8a74e6', + commit_time: '2023-03-30T07:47:06Z', + version: '8.8.0', + }, + event: { + category: ['vulnerability'], + created: '2023-03-30T10:27:35.013537768Z', + id: '5cfbcbe5-7f90-47b8-b1d4-7f79313b2a6d', + kind: 'state', + sequence: 1680172055, + outcome: 'success', + type: ['info'], + }, + ecs: { version: '8.0.0' }, + host: { + os: { + kernel: '5.15.0-1028-aws', + codename: 'jammy', + type: 'linux', + platform: 'ubuntu', + version: '22.04.1 LTS (Jammy Jellyfish)', + family: 'debian', + name: 'Ubuntu', + }, + id: 'ec2644f440799ed0cf8aa595a9a105cc', + containerized: false, + name: 'ip-172-31-33-74', + ip: ['172.31.33.74', 'fe80::85d:f0ff:fe91:c01b'], + mac: ['0A-5D-F0-91-C0-1B'], + hostname: 'ip-172-31-33-74', + architecture: 'aarch64', + }, + data_stream: { + dataset: 'cloud_security_posture.vulnerabilities', + }, +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/test_subjects.ts b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/test_subjects.ts index d1020baecc8cc..b1eddf50f7c14 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/test_subjects.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/test_subjects.ts @@ -9,6 +9,8 @@ export const FINDINGS_VULNERABILITY_FLYOUT_DESCRIPTION_LIST = 'vulnerability-flyout-description-list'; export const JSON_TAB_VULNERABILITY_FLYOUT = 'vulnerability_json_tab_flyout'; export const OVERVIEW_TAB_VULNERABILITY_FLYOUT = 'vulnerability_overview_tab_flyout'; +export const DATA_SOURCE_VULNERABILITY_FLYOUT = 'vulnerability_flyout_data_source_display_box'; +export const PUBLISHED_DATE_VULNERABILITY_FLYOUT = 'vulnerability_flyout_date_display_box'; export const TAB_ID_VULNERABILITY_FLYOUT = (tabId: string) => `vulnerability-finding-flyout-tab-${tabId}`; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx index 06ddae969d431..081eff33c5c96 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_finding_flyout.test.tsx @@ -10,10 +10,15 @@ import { render, screen } from '@testing-library/react'; import '@kbn/code-editor-mock/jest_helper'; import { TestProvider } from '../../../test/test_provider'; import { VulnerabilityFindingFlyout } from './vulnerability_finding_flyout'; -import { mockVulnerabilityHit } from '../_mocks_/vulnerability.mock'; +import { mockVulnerabilityHit, mockWizVulnerabilityHit } from '../_mocks_/vulnerability.mock'; import { VulnerabilityOverviewTab } from './vulnerability_overview_tab'; import moment from 'moment'; -import { FINDINGS_VULNERABILITY_FLYOUT_DESCRIPTION_LIST } from '../test_subjects'; +import { + DATA_SOURCE_VULNERABILITY_FLYOUT, + FINDINGS_VULNERABILITY_FLYOUT_DESCRIPTION_LIST, + PUBLISHED_DATE_VULNERABILITY_FLYOUT, +} from '../test_subjects'; +import { EMPTY_VALUE } from '../../configurations/findings_flyout/findings_flyout'; const onPaginate = jest.fn(); @@ -65,7 +70,7 @@ describe('', () => { ); - getByText(mockVulnerabilityHit.vulnerability.data_source.ID); + getByText(mockVulnerabilityHit.vulnerability.data_source!.ID); getByText('Elastic CSP'); getByText(moment(mockVulnerabilityHit.vulnerability.published_date).format('LL').toString()); getByText(mockVulnerabilityHit.vulnerability.description); @@ -80,6 +85,18 @@ describe('', () => { ); }); + it('Overview Tab with Wiz vulnerability missing fields', () => { + const { getByTestId } = render( + + + + ); + const dataSource = getByTestId(DATA_SOURCE_VULNERABILITY_FLYOUT); + const publisedDate = getByTestId(PUBLISHED_DATE_VULNERABILITY_FLYOUT); + expect(dataSource.textContent).toEqual(`Data Source${EMPTY_VALUE}`); + expect(publisedDate.textContent).toEqual(`Published Date${EMPTY_VALUE}`); + }); + it('show empty state for no fixes', () => { const { getByText } = render( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx index 166b21e4f53ac..ecff474d5f50f 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/vulnerabilities/vulnerabilities_finding_flyout/vulnerability_overview_tab.tsx @@ -26,7 +26,11 @@ import { NvdLogo } from '../../../assets/icons/nvd_logo_svg'; import { CVSScoreBadge } from '../../../components/vulnerability_badges'; import { CVSScoreProps, Vendor } from '../types'; import { getVectorScoreList } from '../utils/get_vector_score_list'; -import { OVERVIEW_TAB_VULNERABILITY_FLYOUT } from '../test_subjects'; +import { + DATA_SOURCE_VULNERABILITY_FLYOUT, + OVERVIEW_TAB_VULNERABILITY_FLYOUT, + PUBLISHED_DATE_VULNERABILITY_FLYOUT, +} from '../test_subjects'; import redhatLogo from '../../../assets/icons/redhat_logo.svg'; import { VulnerabilityDetectionRuleCounter } from './vulnerability_detection_rule_counter'; @@ -164,38 +168,46 @@ const VulnerabilityOverviewTiles = ({ vulnerabilityRecord }: VulnerabilityTabPro )} - {vulnerability?.data_source?.ID && ( - + { + - - {vulnerability.data_source.ID} - + {vulnerability.data_source?.URL ? ( + + {vulnerability.data_source.ID} + + ) : ( + {EMPTY_VALUE} + )} - )} - {date && ( - + } + { + - - - + {vulnerability.data_source?.URL ? ( + + + + ) : ( + EMPTY_VALUE + )} - )} + } ); }; From 3de252e688515e9f84e199b73e5e4246f76b8c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:44:41 +0200 Subject: [PATCH 011/139] [Index Management] Added docs count and size for serverless (#191985) ## Summary Fixes https://github.com/elastic/kibana/issues/190131 This PR adds size and documents count to indices and data streams tables in Index Management on serverless. ### Screenrecording https://github.com/user-attachments/assets/51a933e2-e4ef-42a0-9c82-39bf6e194ee0 ### Screenshots Screenshot 2024-09-06 at 19 20 59 Screenshot 2024-09-06 at 19 21 06 Screenshot 2024-09-06 at 19 27 59 Screenshot 2024-09-06 at 19 28 12 ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../test_suites/core_plugins/rendering.ts | 1 + .../home/data_streams_tab.helpers.ts | 12 +- .../home/data_streams_tab.test.ts | 98 +++++++++++++--- .../home/indices_tab.test.tsx | 33 +++++- ...tion.test.ts => data_stream_utils.test.ts} | 4 +- .../common/lib/data_stream_utils.ts | 64 ++++++++++ .../index_management/common/lib/index.ts | 6 +- .../common/lib/template_serialization.ts | 2 +- .../common/types/data_streams.ts | 5 + .../component_template_create.test.tsx | 2 +- .../component_template_form.tsx | 5 +- .../template_form/template_form.tsx | 2 +- .../data_stream_detail_panel.tsx | 110 ++++++++++++------ .../data_stream_list/data_stream_list.tsx | 61 +++++----- .../data_stream_table/data_stream_table.tsx | 74 ++++++++---- .../details_page_overview.tsx | 5 +- .../size_doc_count_details.tsx | 79 +++++++++++++ .../index_list/index_table/index_table.js | 43 ++++--- .../template_details/tabs/tab_summary.tsx | 2 +- .../plugins/index_management/public/plugin.ts | 6 +- .../plugins/index_management/server/config.ts | 1 + .../lib/data_stream_serialization.ts | 68 ++--------- .../server/lib/fetch_indices.ts | 7 +- .../index_management/server/lib/types.ts | 12 ++ .../api/data_streams/register_get_route.ts | 41 ++++++- .../common/index_management/datastreams.ts | 3 + 26 files changed, 531 insertions(+), 215 deletions(-) rename x-pack/plugins/index_management/common/lib/{data_stream_serialization.test.ts => data_stream_utils.test.ts} (81%) create mode 100644 x-pack/plugins/index_management/common/lib/data_stream_utils.ts create mode 100644 x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/size_doc_count_details.tsx rename x-pack/plugins/index_management/{common => server}/lib/data_stream_serialization.ts (58%) create mode 100644 x-pack/plugins/index_management/server/lib/types.ts diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 9bd43504d7db1..a8c9fef0cfb96 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -295,6 +295,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.index_management.enableLegacyTemplates (boolean?|never)', 'xpack.index_management.enableIndexStats (boolean?|never)', 'xpack.index_management.enableDataStreamStats (boolean?|never)', + 'xpack.index_management.enableSizeAndDocCount (boolean?|never)', 'xpack.index_management.editableIndexSettings (all?|limited?|never)', 'xpack.index_management.enableMappingsSourceFieldSection (boolean?|never)', 'xpack.index_management.dev.enableSemanticText (boolean?)', diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index 8b97b24eadb7a..bd119a77378af 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -24,7 +24,7 @@ export interface DataStreamsTabTestBed extends TestBed { actions: { goToDataStreamsList: () => void; clickEmptyPromptIndexTemplateLink: () => void; - clickIncludeStatsSwitch: () => void; + clickIncludeStatsSwitch: () => Promise; toggleViewFilterAt: (index: number) => void; sortTableOnStorageSize: () => void; sortTableOnName: () => void; @@ -90,9 +90,13 @@ export const setup = async ( component.update(); }; - const clickIncludeStatsSwitch = () => { - const { find } = testBed; - find('includeStatsSwitch').simulate('click'); + const clickIncludeStatsSwitch = async () => { + const { find, component } = testBed; + + await act(async () => { + find('includeStatsSwitch').simulate('click'); + }); + component.update(); }; const toggleViewFilterAt = (index: number) => { diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts index 26eb9eab172b3..a4ea7b9296e28 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts @@ -156,6 +156,10 @@ describe('Data Streams tab', () => { name: 'dataStream1', storageSize: '5b', storageSizeBytes: 5, + // metering API mock + meteringStorageSize: '156kb', + meteringStorageSizeBytes: 156000, + meteringDocsCount: 10000, }); setLoadDataStreamsResponse([ @@ -164,6 +168,10 @@ describe('Data Streams tab', () => { name: 'dataStream2', storageSize: '1kb', storageSizeBytes: 1000, + // metering API mock + meteringStorageSize: '156kb', + meteringStorageSizeBytes: 156000, + meteringDocsCount: 10000, lifecycle: { enabled: true, data_retention: '7d', @@ -224,15 +232,12 @@ describe('Data Streams tab', () => { }); test('has a switch that will reload the data streams with additional stats when clicked', async () => { - const { exists, actions, table, component } = testBed; + const { exists, actions, table } = testBed; expect(exists('includeStatsSwitch')).toBe(true); // Changing the switch will automatically reload the data streams. - await act(async () => { - actions.clickIncludeStatsSwitch(); - }); - component.update(); + await actions.clickIncludeStatsSwitch(); expect(httpSetup.get).toHaveBeenLastCalledWith( `${API_BASE_PATH}/data_streams`, @@ -267,12 +272,9 @@ describe('Data Streams tab', () => { test('sorting on stats sorts by bytes value instead of human readable value', async () => { // Guards against regression of #86122. - const { actions, table, component } = testBed; + const { actions, table } = testBed; - await act(async () => { - actions.clickIncludeStatsSwitch(); - }); - component.update(); + await actions.clickIncludeStatsSwitch(); actions.sortTableOnStorageSize(); @@ -306,7 +308,7 @@ describe('Data Streams tab', () => { actions.sortTableOnName(); }); - test('hides stats toggle if enableDataStreamStats===false', async () => { + test(`doesn't hide stats toggle if enableDataStreamStats===false`, async () => { testBed = await setup(httpSetup, { config: { enableDataStreamStats: false, @@ -321,14 +323,82 @@ describe('Data Streams tab', () => { component.update(); - expect(exists('includeStatsSwitch')).toBeFalsy(); + expect(exists('includeStatsSwitch')).toBeTruthy(); + }); + + test('shows storage size and documents count if enableSizeAndDocCount===true, enableDataStreamStats==false', async () => { + testBed = await setup(httpSetup, { + config: { + enableSizeAndDocCount: true, + enableDataStreamStats: false, + }, + }); + + const { actions, component, table } = testBed; + + await act(async () => { + actions.goToDataStreamsList(); + }); + + component.update(); + + await actions.clickIncludeStatsSwitch(); + + const { tableCellsValues } = table.getMetaData('dataStreamTable'); + expect(tableCellsValues).toEqual([ + ['', 'dataStream1', 'green', '156kb', '10000', '1', '7 days', 'Delete'], + ['', 'dataStream2', 'green', '156kb', '10000', '1', '5 days ', 'Delete'], + ]); + }); + + test('shows last updated and storage size if enableDataStreamStats===true, enableSizeAndDocCount===false', async () => { + testBed = await setup(httpSetup, { + config: { + enableDataStreamStats: true, + enableSizeAndDocCount: false, + }, + }); + + const { actions, component, table } = testBed; + + await act(async () => { + actions.goToDataStreamsList(); + }); + + component.update(); + + await actions.clickIncludeStatsSwitch(); + + const { tableCellsValues } = table.getMetaData('dataStreamTable'); + expect(tableCellsValues).toEqual([ + [ + '', + 'dataStream1', + 'green', + 'December 31st, 1969 7:00:00 PM', + '5b', + '1', + '7 days', + 'Delete', + ], + [ + '', + 'dataStream2', + 'green', + 'December 31st, 1969 7:00:00 PM', + '1kb', + '1', + '5 days ', + 'Delete', + ], + ]); }); test('clicking the indices count navigates to the backing indices', async () => { const { table, actions } = testBed; await actions.clickIndicesAt(0); expect(table.getMetaData('indexTable').tableCellsValues).toEqual([ - ['', 'data-stream-index', '', '', '', '', '', '', 'dataStream1'], + ['', 'data-stream-index', '', '', '', '', '0', '', 'dataStream1'], ]); }); @@ -707,7 +777,7 @@ describe('Data Streams tab', () => { const { table, actions } = testBed; await actions.clickIndicesAt(0); expect(table.getMetaData('indexTable').tableCellsValues).toEqual([ - ['', 'data-stream-index', '', '', '', '', '', '', '%dataStream'], + ['', 'data-stream-index', '', '', '', '', '0', '', '%dataStream'], ]); }); }); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.tsx b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.tsx index 8a8a2fc23d54d..3af9b4b9a2f62 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.tsx +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.tsx @@ -394,7 +394,7 @@ describe('', () => { component.update(); }); - test('renders the table column with index stats by default', () => { + test('renders the table column with all index stats when enableIndexStats is true', () => { const { table } = testBed; const { tableCellsValues } = table.getMetaData('indexTable'); @@ -403,7 +403,7 @@ describe('', () => { ]); }); - describe('Disabled', () => { + describe('renders only size and docs count when enableIndexStats is false, enableSizeAndDocCount is true', () => { beforeEach(async () => { await act(async () => { testBed = await setup(httpSetup, { @@ -411,6 +411,7 @@ describe('', () => { enableLegacyTemplates: true, enableIndexActions: true, enableIndexStats: false, + enableSizeAndDocCount: true, }, }); }); @@ -420,7 +421,33 @@ describe('', () => { component.update(); }); - test('hides index stats information from table', async () => { + test('hides some index stats information from table', async () => { + const { table } = testBed; + const { tableCellsValues } = table.getMetaData('indexTable'); + + expect(tableCellsValues).toEqual([['', 'test', '10,000', '156kb', '']]); + }); + }); + + describe('renders no index stats when enableIndexStats is false, enableSizeAndDocCount is false', () => { + beforeEach(async () => { + await act(async () => { + testBed = await setup(httpSetup, { + config: { + enableLegacyTemplates: true, + enableIndexActions: true, + enableIndexStats: false, + enableSizeAndDocCount: false, + }, + }); + }); + + const { component } = testBed; + + component.update(); + }); + + test('hides all index stats information from table', async () => { const { table } = testBed; const { tableCellsValues } = table.getMetaData('indexTable'); diff --git a/x-pack/plugins/index_management/common/lib/data_stream_serialization.test.ts b/x-pack/plugins/index_management/common/lib/data_stream_utils.test.ts similarity index 81% rename from x-pack/plugins/index_management/common/lib/data_stream_serialization.test.ts rename to x-pack/plugins/index_management/common/lib/data_stream_utils.test.ts index 334e6bbf97de0..afbcf7835f764 100644 --- a/x-pack/plugins/index_management/common/lib/data_stream_serialization.test.ts +++ b/x-pack/plugins/index_management/common/lib/data_stream_utils.test.ts @@ -5,9 +5,9 @@ * 2.0. */ -import { splitSizeAndUnits } from './data_stream_serialization'; +import { splitSizeAndUnits } from './data_stream_utils'; -describe('Data stream serialization', () => { +describe('Data stream utils', () => { test('can split size and units from lifecycle string', () => { expect(splitSizeAndUnits('1h')).toEqual({ size: '1', unit: 'h' }); expect(splitSizeAndUnits('20micron')).toEqual({ size: '20', unit: 'micron' }); diff --git a/x-pack/plugins/index_management/common/lib/data_stream_utils.ts b/x-pack/plugins/index_management/common/lib/data_stream_utils.ts new file mode 100644 index 0000000000000..443373f8a6b4b --- /dev/null +++ b/x-pack/plugins/index_management/common/lib/data_stream_utils.ts @@ -0,0 +1,64 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DataStream, DataRetention } from '../types'; + +export const splitSizeAndUnits = (field: string): { size: string; unit: string } => { + let size = ''; + let unit = ''; + + const result = /(\d+)(\w+)/.exec(field); + if (result) { + size = result[1]; + unit = result[2]; + } + + return { + size, + unit, + }; +}; + +export const serializeAsESLifecycle = (lifecycle?: DataRetention): DataStream['lifecycle'] => { + if (!lifecycle || !lifecycle?.enabled) { + return undefined; + } + + const { infiniteDataRetention, value, unit } = lifecycle; + + if (infiniteDataRetention) { + return { + enabled: true, + }; + } + + return { + enabled: true, + data_retention: `${value}${unit}`, + }; +}; + +export const deserializeESLifecycle = (lifecycle?: DataStream['lifecycle']): DataRetention => { + if (!lifecycle || !lifecycle?.enabled) { + return { enabled: false }; + } + + if (!lifecycle.data_retention) { + return { + enabled: true, + infiniteDataRetention: true, + }; + } + + const { size, unit } = splitSizeAndUnits(lifecycle.data_retention as string); + + return { + enabled: true, + value: Number(size), + unit, + }; +}; diff --git a/x-pack/plugins/index_management/common/lib/index.ts b/x-pack/plugins/index_management/common/lib/index.ts index d46d3d8b6a1d4..da29f3289bcd4 100644 --- a/x-pack/plugins/index_management/common/lib/index.ts +++ b/x-pack/plugins/index_management/common/lib/index.ts @@ -6,10 +6,10 @@ */ export { - deserializeDataStream, - deserializeDataStreamList, splitSizeAndUnits, -} from './data_stream_serialization'; + serializeAsESLifecycle, + deserializeESLifecycle, +} from './data_stream_utils'; export { deserializeTemplate, diff --git a/x-pack/plugins/index_management/common/lib/template_serialization.ts b/x-pack/plugins/index_management/common/lib/template_serialization.ts index aacbc15aab3b8..f8b4ed47a22f7 100644 --- a/x-pack/plugins/index_management/common/lib/template_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/template_serialization.ts @@ -12,7 +12,7 @@ import { TemplateListItem, TemplateType, } from '../types'; -import { deserializeESLifecycle } from './data_stream_serialization'; +import { deserializeESLifecycle } from './data_stream_utils'; import { allowAutoCreateRadioValues, allowAutoCreateRadioIds } from '../constants'; const hasEntries = (data: object = {}) => Object.entries(data).length > 0; diff --git a/x-pack/plugins/index_management/common/types/data_streams.ts b/x-pack/plugins/index_management/common/types/data_streams.ts index 4e20252792d71..c44305edb9d8f 100644 --- a/x-pack/plugins/index_management/common/types/data_streams.ts +++ b/x-pack/plugins/index_management/common/types/data_streams.ts @@ -37,6 +37,8 @@ export interface EnhancedDataStreamFromEs extends IndicesDataStream { store_size?: IndicesDataStreamsStatsDataStreamsStatsItem['store_size']; store_size_bytes?: IndicesDataStreamsStatsDataStreamsStatsItem['store_size_bytes']; maximum_timestamp?: IndicesDataStreamsStatsDataStreamsStatsItem['maximum_timestamp']; + metering_size_in_bytes?: number; + metering_doc_count?: number; indices: DataStreamIndexFromEs[]; privileges: { delete_index: boolean; @@ -55,6 +57,9 @@ export interface DataStream { storageSize?: ByteSize; storageSizeBytes?: number; maxTimeStamp?: number; + meteringStorageSizeBytes?: number; + meteringStorageSize?: string; + meteringDocsCount?: number; _meta?: Metadata; privileges: Privileges; hidden: boolean; diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx index 729ca7680ad6c..787aa68907730 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/__jest__/client_integration/component_template_create.test.tsx @@ -12,7 +12,7 @@ import { breadcrumbService, IndexManagementBreadcrumb } from '../../../../servic import { setupEnvironment } from './helpers'; import { API_BASE_PATH } from './helpers/constants'; import { setup, ComponentTemplateCreateTestBed } from './helpers/component_template_create.helpers'; -import { serializeAsESLifecycle } from '../../../../../../common/lib/data_stream_serialization'; +import { serializeAsESLifecycle } from '../../../../../../common/lib'; jest.mock('@kbn/code-editor', () => { const original = jest.requireActual('@kbn/code-editor'); diff --git a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_form/component_template_form.tsx b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_form/component_template_form.tsx index 1cbc33fc05135..ca791311d2408 100644 --- a/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_form/component_template_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/component_templates/component_template_wizard/component_template_form/component_template_form.tsx @@ -19,10 +19,7 @@ import { StepMappingsContainer, StepAliasesContainer, } from '../../shared_imports'; -import { - serializeAsESLifecycle, - deserializeESLifecycle, -} from '../../../../../../common/lib/data_stream_serialization'; +import { serializeAsESLifecycle, deserializeESLifecycle } from '../../../../../../common/lib'; import { useComponentTemplatesContext } from '../../component_templates_context'; import { StepLogisticsContainer, StepReviewContainer } from './steps'; diff --git a/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx index ac247500e3248..2da3eef609a65 100644 --- a/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/template_form.tsx @@ -22,7 +22,7 @@ import { } from '../shared'; import { documentationService } from '../../services/documentation'; import { SectionError } from '../section_error'; -import { serializeAsESLifecycle } from '../../../../common/lib/data_stream_serialization'; +import { serializeAsESLifecycle } from '../../../../common/lib'; import { SimulateTemplateFlyoutContent, SimulateTemplateProps, diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx index da53b0241095d..974ba6f082042 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx @@ -52,13 +52,14 @@ import { useAppContext } from '../../../../app_context'; import { DataStreamsBadges } from '../data_stream_badges'; import { useIlmLocator } from '../../../../services/use_ilm_locator'; +interface Detail { + name: string; + toolTip: string; + content: any; + dataTestSubj: string; +} interface DetailsListProps { - details: Array<{ - name: string; - toolTip: string; - content: any; - dataTestSubj: string; - }>; + details: Detail[]; } const DetailsList: React.FunctionComponent = ({ details }) => { @@ -162,6 +163,8 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ ilmPolicyName, storageSize, maxTimeStamp, + meteringStorageSize, + meteringDocsCount, lifecycle, } = dataStream; @@ -222,7 +225,7 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ ); - const defaultDetails = [ + const defaultDetails: Detail[] = [ { name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.healthTitle', { defaultMessage: 'Health', @@ -233,34 +236,67 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ content: , dataTestSubj: 'healthDetail', }, - { - name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.maxTimeStampTitle', { - defaultMessage: 'Last updated', - }), - toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.maxTimeStampToolTip', { - defaultMessage: 'The most recent document to be added to the data stream.', - }), - content: maxTimeStamp ? ( - humanizeTimeStamp(maxTimeStamp) - ) : ( - - {i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.maxTimeStampNoneMessage', { - defaultMessage: `Never`, - })} - - ), - dataTestSubj: 'lastUpdatedDetail', - }, - { - name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.storageSizeTitle', { - defaultMessage: 'Storage size', - }), - toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.storageSizeToolTip', { - defaultMessage: `The total size of all shards in the data stream’s backing indices.`, - }), - content: storageSize, - dataTestSubj: 'storageSizeDetail', - }, + ]; + + // add either documents count and size or last updated and size + if (config.enableSizeAndDocCount) { + defaultDetails.push( + { + name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.meteringDocsCountTitle', { + defaultMessage: 'Documents count', + }), + toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.meteringDocsCountToolTip', { + defaultMessage: 'The number of documents in this data stream.', + }), + content: meteringDocsCount, + dataTestSubj: 'docsCountDetail', + }, + { + name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.storageSizeTitle', { + defaultMessage: 'Storage size', + }), + toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.storageSizeToolTip', { + defaultMessage: `The total size of all shards in the data stream’s backing indices.`, + }), + content: meteringStorageSize, + dataTestSubj: 'meteringStorageSizeDetail', + } + ); + } + if (config.enableDataStreamStats) { + defaultDetails.push( + { + name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.maxTimeStampTitle', { + defaultMessage: 'Last updated', + }), + toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.maxTimeStampToolTip', { + defaultMessage: 'The most recent document to be added to the data stream.', + }), + content: maxTimeStamp ? ( + humanizeTimeStamp(maxTimeStamp) + ) : ( + + {i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.maxTimeStampNoneMessage', { + defaultMessage: `Never`, + })} + + ), + dataTestSubj: 'lastUpdatedDetail', + }, + { + name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.storageSizeTitle', { + defaultMessage: 'Storage size', + }), + toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.storageSizeToolTip', { + defaultMessage: `The total size of all shards in the data stream’s backing indices.`, + }), + content: storageSize, + dataTestSubj: 'storageSizeDetail', + } + ); + } + + defaultDetails.push( { name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.indicesTitle', { defaultMessage: 'Indices', @@ -328,8 +364,8 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ ), dataTestSubj: 'dataRetentionDetail', - }, - ]; + } + ); // If both rentention types are available, we wanna surface to the user both if (lifecycle?.effective_retention && lifecycle?.data_retention) { diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx index 0103b51f1f51d..125f676897ffb 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_list.tsx @@ -60,11 +60,8 @@ export const DataStreamList: React.FunctionComponent - {isDataStreamStatsEnabled && ( - - - - setIsIncludeStatsChecked(e.target.checked)} - data-test-subj="includeStatsSwitch" - /> - + + + + setIsIncludeStatsChecked(e.target.checked)} + data-test-subj="includeStatsSwitch" + /> + - - - - - - )} + + + + + filters={filters} onChange={setFilters} /> diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index b4dbb663e0859..47b170babc5a6 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -104,31 +104,55 @@ export const DataStreamTable: React.FunctionComponent = ({ }); if (includeStats) { - columns.push({ - field: 'maxTimeStamp', - name: i18n.translate('xpack.idxMgmt.dataStreamList.table.maxTimeStampColumnTitle', { - defaultMessage: 'Last updated', - }), - truncateText: true, - sortable: true, - render: (maxTimeStamp: DataStream['maxTimeStamp']) => - maxTimeStamp - ? humanizeTimeStamp(maxTimeStamp) - : i18n.translate('xpack.idxMgmt.dataStreamList.table.maxTimeStampColumnNoneMessage', { - defaultMessage: 'Never', - }), - }); - - columns.push({ - field: 'storageSizeBytes', - name: i18n.translate('xpack.idxMgmt.dataStreamList.table.storageSizeColumnTitle', { - defaultMessage: 'Storage size', - }), - truncateText: true, - sortable: true, - render: (storageSizeBytes: DataStream['storageSizeBytes'], dataStream: DataStream) => - dataStream.storageSize, - }); + if (config.enableSizeAndDocCount) { + // datastreams stats from metering API on serverless + columns.push({ + field: 'meteringStorageSizeBytes', + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.storageSizeColumnTitle', { + defaultMessage: 'Storage size', + }), + truncateText: true, + sortable: true, + render: ( + meteringStorageSizeBytes: DataStream['meteringStorageSizeBytes'], + dataStream: DataStream + ) => dataStream.meteringStorageSize, + }); + columns.push({ + field: 'meteringDocsCount', + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.docsCountColumnTitle', { + defaultMessage: 'Documents count', + }), + truncateText: true, + sortable: true, + }); + } + if (config.enableDataStreamStats) { + columns.push({ + field: 'maxTimeStamp', + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.maxTimeStampColumnTitle', { + defaultMessage: 'Last updated', + }), + truncateText: true, + sortable: true, + render: (maxTimeStamp: DataStream['maxTimeStamp']) => + maxTimeStamp + ? humanizeTimeStamp(maxTimeStamp) + : i18n.translate('xpack.idxMgmt.dataStreamList.table.maxTimeStampColumnNoneMessage', { + defaultMessage: 'Never', + }), + }); + columns.push({ + field: 'storageSizeBytes', + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.storageSizeColumnTitle', { + defaultMessage: 'Storage size', + }), + truncateText: true, + sortable: true, + render: (storageSizeBytes: DataStream['storageSizeBytes'], dataStream: DataStream) => + dataStream.storageSize, + }); + } } columns.push({ diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx index c3e985a638fd5..a5fcb4a5c24a8 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/details_page_overview.tsx @@ -26,14 +26,15 @@ import { getLanguageDefinitionCodeSnippet, getConsoleRequest, } from '@kbn/search-api-panels'; -import { StatusDetails } from './status_details'; import type { Index } from '../../../../../../../common'; import { useAppContext } from '../../../../../app_context'; import { documentationService } from '../../../../../services'; import { languageDefinitions, curlDefinition } from './languages'; +import { StatusDetails } from './status_details'; import { DataStreamDetails } from './data_stream_details'; import { StorageDetails } from './storage_details'; import { AliasesDetails } from './aliases_details'; +import { SizeDocCountDetails } from './size_doc_count_details'; interface Props { indexDetails: Index; @@ -85,6 +86,8 @@ export const DetailsPageOverview: React.FunctionComponent = ({ indexDetai health={health} /> + + {dataStream && } diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/size_doc_count_details.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/size_doc_count_details.tsx new file mode 100644 index 0000000000000..40294d76b2698 --- /dev/null +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/details_page/details_page_overview/size_doc_count_details.tsx @@ -0,0 +1,79 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FunctionComponent } from 'react'; +import { css } from '@emotion/react'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText, EuiTextColor } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { euiThemeVars } from '@kbn/ui-theme'; +import type { Index } from '../../../../../../../common'; +import { useAppContext } from '../../../../../app_context'; +import { OverviewCard } from './overview_card'; + +export const SizeDocCountDetails: FunctionComponent<{ + size: Index['size']; + documents: Index['documents']; +}> = ({ size, documents }) => { + const { config } = useAppContext(); + if (!config.enableSizeAndDocCount) { + return null; + } + return ( + + + + {size} + + + + + {i18n.translate('xpack.idxMgmt.indexDetails.overviewTab.storage.totalSizeLabel', { + defaultMessage: 'Total', + })} + + + + ), + right: null, + }} + footer={{ + left: ( + + + + + {documents} + + + {i18n.translate( + 'xpack.idxMgmt.indexDetails.overviewTab.status.meteringDocumentsLabel', + { + defaultMessage: '{documents, plural, one {Document} other {Documents}}', + values: { + documents, + }, + } + )} + + + + ), + }} + /> + ); +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js index 89b14d3db05c9..bdc245fe57703 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table.js @@ -52,6 +52,7 @@ import { IndexTablePagination, PAGE_SIZE_OPTIONS } from './index_table_paginatio const getColumnConfigs = ({ showIndexStats, + showSizeAndDocCount, history, filterChanged, extensionsService, @@ -100,6 +101,28 @@ const getColumnConfigs = ({ }, ]; + // size and docs count enabled by either "enableIndexStats" or "enableSizeAndDocCount" configs + if (showIndexStats || showSizeAndDocCount) { + columns.push( + { + fieldName: 'documents', + label: i18n.translate('xpack.idxMgmt.indexTable.headers.documentsHeader', { + defaultMessage: 'Documents count', + }), + order: 60, + render: (index) => { + return Number(index.documents ?? 0).toLocaleString(); + }, + }, + { + fieldName: 'size', + label: i18n.translate('xpack.idxMgmt.indexTable.headers.storageSizeHeader', { + defaultMessage: 'Storage size', + }), + order: 70, + } + ); + } if (showIndexStats) { columns.push( { @@ -130,25 +153,6 @@ const getColumnConfigs = ({ defaultMessage: 'Replicas', }), order: 50, - }, - { - fieldName: 'documents', - label: i18n.translate('xpack.idxMgmt.indexTable.headers.documentsHeader', { - defaultMessage: 'Docs count', - }), - order: 60, - render: (index) => { - if (index.documents) { - return Number(index.documents).toLocaleString(); - } - }, - }, - { - fieldName: 'size', - label: i18n.translate('xpack.idxMgmt.indexTable.headers.storageSizeHeader', { - defaultMessage: 'Storage size', - }), - order: 70, } ); } @@ -533,6 +537,7 @@ export class IndexTable extends Component { const { extensionsService } = services; const columnConfigs = getColumnConfigs({ showIndexStats: config.enableIndexStats, + showSizeAndDocCount: config.enableSizeAndDocCount, extensionsService, filterChanged, history, diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx index c2aa548100b57..513377714ffe0 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx @@ -22,7 +22,7 @@ import { } from '@elastic/eui'; import { reactRouterNavigate } from '../../../../../../shared_imports'; import { useAppContext } from '../../../../../app_context'; -import { serializeAsESLifecycle } from '../../../../../../../common/lib/data_stream_serialization'; +import { serializeAsESLifecycle } from '../../../../../../../common/lib'; import { getLifecycleValue } from '../../../../../lib/data_streams'; import { TemplateDeserialized } from '../../../../../../../common'; import { ILM_PAGES_POLICY_EDIT } from '../../../../../constants'; diff --git a/x-pack/plugins/index_management/public/plugin.ts b/x-pack/plugins/index_management/public/plugin.ts index 49693bb0d9aa9..4efe613fc2a04 100644 --- a/x-pack/plugins/index_management/public/plugin.ts +++ b/x-pack/plugins/index_management/public/plugin.ts @@ -44,8 +44,8 @@ export class IndexMgmtUIPlugin enableIndexActions: boolean; enableLegacyTemplates: boolean; enableIndexStats: boolean; - enableSizeAndDocCount: boolean; enableDataStreamStats: boolean; + enableSizeAndDocCount: boolean; editableIndexSettings: 'all' | 'limited'; isIndexManagementUiEnabled: boolean; enableMappingsSourceFieldSection: boolean; @@ -63,8 +63,8 @@ export class IndexMgmtUIPlugin enableIndexActions, enableLegacyTemplates, enableIndexStats, - enableSizeAndDocCount, enableDataStreamStats, + enableSizeAndDocCount, editableIndexSettings, enableMappingsSourceFieldSection, enableTogglingDataRetention, @@ -75,8 +75,8 @@ export class IndexMgmtUIPlugin enableIndexActions: enableIndexActions ?? true, enableLegacyTemplates: enableLegacyTemplates ?? true, enableIndexStats: enableIndexStats ?? true, - enableSizeAndDocCount: enableSizeAndDocCount ?? true, enableDataStreamStats: enableDataStreamStats ?? true, + enableSizeAndDocCount: enableSizeAndDocCount ?? false, editableIndexSettings: editableIndexSettings ?? 'all', enableMappingsSourceFieldSection: enableMappingsSourceFieldSection ?? true, enableTogglingDataRetention: enableTogglingDataRetention ?? true, diff --git a/x-pack/plugins/index_management/server/config.ts b/x-pack/plugins/index_management/server/config.ts index 3480e380281e5..9bddc6417cc1b 100644 --- a/x-pack/plugins/index_management/server/config.ts +++ b/x-pack/plugins/index_management/server/config.ts @@ -83,6 +83,7 @@ const configLatest: PluginConfigDescriptor = { enableLegacyTemplates: true, enableIndexStats: true, enableDataStreamStats: true, + enableSizeAndDocCount: true, editableIndexSettings: true, enableMappingsSourceFieldSection: true, enableTogglingDataRetention: true, diff --git a/x-pack/plugins/index_management/common/lib/data_stream_serialization.ts b/x-pack/plugins/index_management/server/lib/data_stream_serialization.ts similarity index 58% rename from x-pack/plugins/index_management/common/lib/data_stream_serialization.ts rename to x-pack/plugins/index_management/server/lib/data_stream_serialization.ts index ceedd072139aa..ffe058907e000 100644 --- a/x-pack/plugins/index_management/common/lib/data_stream_serialization.ts +++ b/x-pack/plugins/index_management/server/lib/data_stream_serialization.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { DataStream, EnhancedDataStreamFromEs, Health, DataRetention } from '../types'; +import { ByteSizeValue } from '@kbn/config-schema'; +import type { DataStream, EnhancedDataStreamFromEs, Health } from '../../common'; export function deserializeDataStream(dataStreamFromEs: EnhancedDataStreamFromEs): DataStream { const { @@ -19,12 +20,18 @@ export function deserializeDataStream(dataStreamFromEs: EnhancedDataStreamFromEs store_size: storageSize, store_size_bytes: storageSizeBytes, maximum_timestamp: maxTimeStamp, + metering_size_in_bytes: meteringStorageSizeBytes, + metering_doc_count: meteringDocsCount, _meta, privileges, hidden, lifecycle, next_generation_managed_by: nextGenerationManagedBy, } = dataStreamFromEs; + const meteringStorageSize = + meteringStorageSizeBytes !== undefined + ? new ByteSizeValue(meteringStorageSizeBytes).toString() + : undefined; return { name, @@ -54,6 +61,9 @@ export function deserializeDataStream(dataStreamFromEs: EnhancedDataStreamFromEs storageSize, storageSizeBytes, maxTimeStamp, + meteringStorageSize, + meteringStorageSizeBytes, + meteringDocsCount, _meta, privileges, hidden, @@ -67,59 +77,3 @@ export function deserializeDataStreamList( ): DataStream[] { return dataStreamsFromEs.map((dataStream) => deserializeDataStream(dataStream)); } - -export const splitSizeAndUnits = (field: string): { size: string; unit: string } => { - let size = ''; - let unit = ''; - - const result = /(\d+)(\w+)/.exec(field); - if (result) { - size = result[1]; - unit = result[2]; - } - - return { - size, - unit, - }; -}; - -export const serializeAsESLifecycle = (lifecycle?: DataRetention): DataStream['lifecycle'] => { - if (!lifecycle || !lifecycle?.enabled) { - return undefined; - } - - const { infiniteDataRetention, value, unit } = lifecycle; - - if (infiniteDataRetention) { - return { - enabled: true, - }; - } - - return { - enabled: true, - data_retention: `${value}${unit}`, - }; -}; - -export const deserializeESLifecycle = (lifecycle?: DataStream['lifecycle']): DataRetention => { - if (!lifecycle || !lifecycle?.enabled) { - return { enabled: false }; - } - - if (!lifecycle.data_retention) { - return { - enabled: true, - infiniteDataRetention: true, - }; - } - - const { size, unit } = splitSizeAndUnits(lifecycle.data_retention as string); - - return { - enabled: true, - value: Number(size), - unit, - }; -}; diff --git a/x-pack/plugins/index_management/server/lib/fetch_indices.ts b/x-pack/plugins/index_management/server/lib/fetch_indices.ts index 1df453d1042cd..0e82f03f7308f 100644 --- a/x-pack/plugins/index_management/server/lib/fetch_indices.ts +++ b/x-pack/plugins/index_management/server/lib/fetch_indices.ts @@ -10,13 +10,10 @@ import { IScopedClusterClient } from '@kbn/core/server'; import { IndexDataEnricher } from '../services'; import { Index } from '..'; import { RouteDependencies } from '../types'; +import type { MeteringStats } from './types'; interface MeteringStatsResponse { - indices: Array<{ - name: string; - num_docs: number; - size_in_bytes: number; - }>; + indices: MeteringStats[]; } async function fetchIndicesCall( diff --git a/x-pack/plugins/index_management/server/lib/types.ts b/x-pack/plugins/index_management/server/lib/types.ts new file mode 100644 index 0000000000000..1657c4bbbb6e0 --- /dev/null +++ b/x-pack/plugins/index_management/server/lib/types.ts @@ -0,0 +1,12 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface MeteringStats { + name: string; + num_docs: number; + size_in_bytes: number; +} diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts index 11db019eacf6a..78c0328f52617 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts @@ -13,18 +13,27 @@ import { IndicesDataStreamsStatsDataStreamsStatsItem, SecurityHasPrivilegesResponse, } from '@elastic/elasticsearch/lib/api/types'; -import { deserializeDataStream, deserializeDataStreamList } from '../../../../common/lib'; +import type { MeteringStats } from '../../../lib/types'; +import { + deserializeDataStream, + deserializeDataStreamList, +} from '../../../lib/data_stream_serialization'; import { EnhancedDataStreamFromEs } from '../../../../common/types'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +interface MeteringStatsResponse { + datastreams: MeteringStats[]; +} const enhanceDataStreams = ({ dataStreams, dataStreamsStats, + meteringStats, dataStreamsPrivileges, }: { dataStreams: IndicesDataStream[]; dataStreamsStats?: IndicesDataStreamsStatsDataStreamsStatsItem[]; + meteringStats?: MeteringStats[]; dataStreamsPrivileges?: SecurityHasPrivilegesResponse; }): EnhancedDataStreamFromEs[] => { return dataStreams.map((dataStream) => { @@ -51,6 +60,14 @@ const enhanceDataStreams = ({ } } + if (meteringStats) { + const datastreamMeteringStats = meteringStats.find((s) => s.name === dataStream.name); + if (datastreamMeteringStats) { + enhancedDataStream.metering_size_in_bytes = datastreamMeteringStats.size_in_bytes; + enhancedDataStream.metering_doc_count = datastreamMeteringStats.num_docs; + } + } + return enhancedDataStream; }); }; @@ -70,6 +87,17 @@ const getDataStreamsStats = (client: IScopedClusterClient, name = '*') => { }); }; +const getMeteringStats = (client: IScopedClusterClient, name?: string) => { + let path = `/_metering/stats`; + if (name) { + path = `${path}/${name}`; + } + return client.asSecondaryAuthUser.transport.request({ + method: 'GET', + path, + }); +}; + const getDataStreamsPrivileges = (client: IScopedClusterClient, names: string[]) => { return client.asCurrentUser.security.hasPrivileges({ body: { @@ -99,10 +127,14 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: let dataStreamsStats; let dataStreamsPrivileges; + let meteringStats; if (includeStats && config.isDataStreamStatsEnabled !== false) { ({ data_streams: dataStreamsStats } = await getDataStreamsStats(client)); } + if (includeStats && config.isSizeAndDocCountEnabled !== false) { + ({ datastreams: meteringStats } = await getMeteringStats(client)); + } if (config.isSecurityEnabled() && dataStreams.length > 0) { dataStreamsPrivileges = await getDataStreamsPrivileges( @@ -114,6 +146,7 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: const enhancedDataStreams = enhanceDataStreams({ dataStreams, dataStreamsStats, + meteringStats, dataStreamsPrivileges, }); @@ -138,6 +171,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: const { name } = request.params as TypeOf; const { client } = (await context.core).elasticsearch; let dataStreamsStats; + let meteringStats; try { const { data_streams: dataStreams } = await getDataStreams(client, name); @@ -146,6 +180,10 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: ({ data_streams: dataStreamsStats } = await getDataStreamsStats(client, name)); } + if (config.isSizeAndDocCountEnabled !== false) { + ({ datastreams: meteringStats } = await getMeteringStats(client, name)); + } + if (dataStreams[0]) { let dataStreamsPrivileges; @@ -156,6 +194,7 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: const enhancedDataStreams = enhanceDataStreams({ dataStreams, dataStreamsStats, + meteringStats, dataStreamsPrivileges, }); const body = deserializeDataStream(enhancedDataStreams[0]); diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts index 961c9a73bdf47..de3a92587d6b9 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts @@ -118,6 +118,9 @@ export default function ({ getService }: FtrProviderContext) { lifecycle: { enabled: true, }, + meteringDocsCount: 0, + meteringStorageSize: '0b', + meteringStorageSizeBytes: 0, }); }); }); From c26ee22db69059d1908cb7bf3982db13a354b77a Mon Sep 17 00:00:00 2001 From: Tiago Vila Verde Date: Mon, 16 Sep 2024 14:07:03 +0200 Subject: [PATCH 012/139] [Entity Manager] Extract the entity manager out of Observability solution (#190304) ## Summary Moving the Entity Manager out of Observability and into a Kibana plugin as per [this ticket](https://github.com/elastic/security-team/issues/10156) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .github/CODEOWNERS | 2 +- docs/developer/plugin-list.asciidoc | 2 +- package.json | 2 +- tsconfig.base.json | 4 ++-- .../entity_manager/README.md | 0 .../entity_manager/common/config.ts | 0 .../entity_manager/common/constants_entities.ts | 0 .../entity_manager/common/debug_log.ts | 0 .../entity_manager/common/errors.ts | 0 .../entity_manager/common/types_api.ts | 0 .../entity_manager/docs/entity_definitions.md | 0 .../entity_manager/jest.config.js | 9 ++++----- .../entity_manager/kibana.jsonc | 0 .../entity_manager/public/index.ts | 0 .../entity_manager/public/lib/entity_client.ts | 0 .../entity_manager/public/lib/errors.ts | 0 .../entity_manager/public/plugin.ts | 0 .../entity_manager/public/types.ts | 0 .../entity_manager/server/index.ts | 0 .../entity_manager/server/lib/auth/api_key/api_key.ts | 0 .../server/lib/auth/api_key/saved_object.ts | 0 .../entity_manager/server/lib/auth/index.ts | 0 .../entity_manager/server/lib/auth/privileges.ts | 0 .../entity_manager/server/lib/client/index.ts | 0 .../server/lib/entities/built_in/constants.ts | 0 .../entity_manager/server/lib/entities/built_in/index.ts | 0 .../server/lib/entities/built_in/services.ts | 0 .../lib/entities/create_and_install_ingest_pipeline.ts | 0 .../server/lib/entities/create_and_install_transform.ts | 0 .../server/lib/entities/delete_entity_definition.ts | 0 .../entity_manager/server/lib/entities/delete_index.ts | 0 .../server/lib/entities/delete_ingest_pipeline.ts | 0 .../server/lib/entities/delete_transforms.ts | 0 .../lib/entities/errors/entity_definition_id_invalid.ts | 0 .../lib/entities/errors/entity_id_conflict_error.ts | 0 .../server/lib/entities/errors/entity_not_found.ts | 0 .../lib/entities/errors/entity_security_exception.ts | 0 .../lib/entities/errors/invalid_transform_error.ts | 0 .../server/lib/entities/find_entity_definition.ts | 0 .../server/lib/entities/helpers/calculate_offset.ts | 0 .../helpers/fixtures/builtin_entity_definition.ts | 0 .../lib/entities/helpers/fixtures/entity_definition.ts | 0 .../helpers/fixtures/entity_definition_with_backfill.ts | 0 .../server/lib/entities/helpers/fixtures/index.ts | 0 .../server/lib/entities/helpers/generate_component_id.ts | 0 .../entities/helpers/get_elasticsearch_query_or_throw.ts | 0 .../ingest_pipeline_script_processor_helpers.test.ts | 0 .../helpers/ingest_pipeline_script_processor_helpers.ts | 0 .../server/lib/entities/helpers/is_backfill_enabled.ts | 0 .../server/lib/entities/helpers/is_builtin_definition.ts | 0 .../lib/entities/helpers/merge_definition_update.ts | 0 .../entity_manager/server/lib/entities/helpers/retry.ts | 0 .../generate_history_processors.test.ts.snap | 0 .../generate_latest_processors.test.ts.snap | 0 .../ingest_pipeline/generate_history_processors.test.ts | 0 .../ingest_pipeline/generate_history_processors.ts | 0 .../ingest_pipeline/generate_latest_processors.test.ts | 0 .../ingest_pipeline/generate_latest_processors.ts | 0 .../lib/entities/install_entity_definition.test.ts | 0 .../server/lib/entities/install_entity_definition.ts | 0 .../server/lib/entities/read_entity_definition.ts | 0 .../server/lib/entities/save_entity_definition.ts | 0 .../server/lib/entities/start_transforms.ts | 0 .../server/lib/entities/stop_transforms.ts | 0 .../__snapshots__/entities_history_template.test.ts.snap | 0 .../__snapshots__/entities_latest_template.test.ts.snap | 0 .../entities/templates/entities_history_template.test.ts | 0 .../lib/entities/templates/entities_history_template.ts | 0 .../entities/templates/entities_latest_template.test.ts | 0 .../lib/entities/templates/entities_latest_template.ts | 0 .../generate_history_transform.test.ts.snap | 0 .../__snapshots__/generate_latest_transform.test.ts.snap | 0 .../transform/generate_history_transform.test.ts | 0 .../lib/entities/transform/generate_history_transform.ts | 0 .../entities/transform/generate_identity_aggregations.ts | 0 .../entities/transform/generate_latest_transform.test.ts | 0 .../lib/entities/transform/generate_latest_transform.ts | 0 .../transform/generate_metadata_aggregations.test.ts | 0 .../entities/transform/generate_metadata_aggregations.ts | 0 .../entities/transform/generate_metric_aggregations.ts | 0 .../entities/transform/validate_transform_ids.test.ts | 0 .../lib/entities/transform/validate_transform_ids.ts | 0 .../entity_manager/server/lib/entities/types.ts | 0 .../server/lib/entities/uninstall_entity_definition.ts | 0 .../server/lib/entities/upgrade_entity_definition.ts | 0 .../entity_manager/server/lib/entity_client.ts | 0 .../entity_manager/server/lib/errors.ts | 0 .../entity_manager/server/lib/manage_index_templates.ts | 0 .../entity_manager/server/lib/utils.ts | 0 .../server/lib/validators/validate_date_range.ts | 0 .../server/lib/validators/validation_error.ts | 0 .../entity_manager/server/plugin.ts | 0 .../server/routes/create_entity_manager_server_route.ts | 0 .../entity_manager/server/routes/enablement/check.ts | 0 .../entity_manager/server/routes/enablement/disable.ts | 0 .../entity_manager/server/routes/enablement/enable.ts | 0 .../entity_manager/server/routes/enablement/index.ts | 0 .../entity_manager/server/routes/entities/create.ts | 0 .../entity_manager/server/routes/entities/delete.ts | 0 .../entity_manager/server/routes/entities/get.ts | 0 .../entity_manager/server/routes/entities/index.ts | 0 .../entity_manager/server/routes/entities/reset.ts | 0 .../entity_manager/server/routes/entities/update.ts | 0 .../entity_manager/server/routes/index.ts | 0 .../entity_manager/server/routes/types.ts | 0 .../server/saved_objects/entity_definition.ts | 0 .../server/saved_objects/entity_discovery_api_key.ts | 0 .../entity_manager/server/saved_objects/index.ts | 0 .../server/templates/components/base_history.ts | 0 .../server/templates/components/base_latest.ts | 0 .../entity_manager/server/templates/components/entity.ts | 0 .../entity_manager/server/templates/components/event.ts | 0 .../server/templates/components/helpers.test.ts | 0 .../server/templates/components/helpers.ts | 0 .../entity_manager/server/types.ts | 0 .../entity_manager/tsconfig.json | 6 ++++-- yarn.lock | 2 +- 117 files changed, 14 insertions(+), 13 deletions(-) rename x-pack/plugins/{observability_solution => }/entity_manager/README.md (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/common/config.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/common/constants_entities.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/common/debug_log.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/common/errors.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/common/types_api.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/docs/entity_definitions.md (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/jest.config.js (52%) rename x-pack/plugins/{observability_solution => }/entity_manager/kibana.jsonc (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/public/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/public/lib/entity_client.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/public/lib/errors.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/public/plugin.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/public/types.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/auth/api_key/api_key.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/auth/api_key/saved_object.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/auth/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/auth/privileges.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/client/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/built_in/constants.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/built_in/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/built_in/services.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/create_and_install_transform.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/delete_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/delete_index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/delete_ingest_pipeline.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/delete_transforms.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/errors/entity_definition_id_invalid.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/errors/entity_id_conflict_error.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/errors/entity_not_found.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/errors/entity_security_exception.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/errors/invalid_transform_error.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/find_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/calculate_offset.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/fixtures/builtin_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/fixtures/entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/fixtures/entity_definition_with_backfill.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/fixtures/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/generate_component_id.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/get_elasticsearch_query_or_throw.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/is_backfill_enabled.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/is_builtin_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/merge_definition_update.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/helpers/retry.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/install_entity_definition.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/install_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/read_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/save_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/start_transforms.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/stop_transforms.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/templates/__snapshots__/entities_history_template.test.ts.snap (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/templates/__snapshots__/entities_latest_template.test.ts.snap (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/templates/entities_history_template.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/templates/entities_history_template.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/templates/entities_latest_template.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/templates/entities_latest_template.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_history_transform.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_history_transform.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_identity_aggregations.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_latest_transform.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_latest_transform.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/generate_metric_aggregations.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/validate_transform_ids.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/transform/validate_transform_ids.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/types.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/uninstall_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entities/upgrade_entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/entity_client.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/errors.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/manage_index_templates.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/utils.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/validators/validate_date_range.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/lib/validators/validation_error.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/plugin.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/create_entity_manager_server_route.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/enablement/check.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/enablement/disable.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/enablement/enable.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/enablement/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/entities/create.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/entities/delete.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/entities/get.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/entities/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/entities/reset.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/entities/update.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/routes/types.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/saved_objects/entity_definition.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/saved_objects/entity_discovery_api_key.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/saved_objects/index.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/templates/components/base_history.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/templates/components/base_latest.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/templates/components/entity.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/templates/components/event.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/templates/components/helpers.test.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/templates/components/helpers.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/server/types.ts (100%) rename x-pack/plugins/{observability_solution => }/entity_manager/tsconfig.json (90%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3a4306292b8f9..9adb05cb22ecc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -402,7 +402,7 @@ x-pack/plugins/enterprise_search @elastic/search-kibana x-pack/plugins/observability_solution/entities_data_access @elastic/obs-entities x-pack/packages/kbn-entities-schema @elastic/obs-entities x-pack/test/api_integration/apis/entity_manager/fixture_plugin @elastic/obs-entities -x-pack/plugins/observability_solution/entity_manager @elastic/obs-entities +x-pack/plugins/entity_manager @elastic/obs-entities examples/error_boundary @elastic/appex-sharedux packages/kbn-es @elastic/kibana-operations packages/kbn-es-archiver @elastic/kibana-operations @elastic/appex-qa diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc index 0010045ab3c92..7e31cd50aeb81 100644 --- a/docs/developer/plugin-list.asciidoc +++ b/docs/developer/plugin-list.asciidoc @@ -570,7 +570,7 @@ security and spaces filtering. |Exposes services to access entities data. -|{kib-repo}blob/{branch}/x-pack/plugins/observability_solution/entity_manager/README.md[entityManager] +|{kib-repo}blob/{branch}/x-pack/plugins/entity_manager/README.md[entityManager] |This plugin provides access to observed entity data, such as information about hosts, pods, containers, services, and more. diff --git a/package.json b/package.json index 760268042a27b..5b9e8fac1fb31 100644 --- a/package.json +++ b/package.json @@ -464,7 +464,7 @@ "@kbn/entities-data-access-plugin": "link:x-pack/plugins/observability_solution/entities_data_access", "@kbn/entities-schema": "link:x-pack/packages/kbn-entities-schema", "@kbn/entity-manager-fixture-plugin": "link:x-pack/test/api_integration/apis/entity_manager/fixture_plugin", - "@kbn/entityManager-plugin": "link:x-pack/plugins/observability_solution/entity_manager", + "@kbn/entityManager-plugin": "link:x-pack/plugins/entity_manager", "@kbn/error-boundary-example-plugin": "link:examples/error_boundary", "@kbn/es-errors": "link:packages/kbn-es-errors", "@kbn/es-query": "link:packages/kbn-es-query", diff --git a/tsconfig.base.json b/tsconfig.base.json index f931b2e3ea28d..ae8b6c2c2a95f 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -798,8 +798,8 @@ "@kbn/entities-schema/*": ["x-pack/packages/kbn-entities-schema/*"], "@kbn/entity-manager-fixture-plugin": ["x-pack/test/api_integration/apis/entity_manager/fixture_plugin"], "@kbn/entity-manager-fixture-plugin/*": ["x-pack/test/api_integration/apis/entity_manager/fixture_plugin/*"], - "@kbn/entityManager-plugin": ["x-pack/plugins/observability_solution/entity_manager"], - "@kbn/entityManager-plugin/*": ["x-pack/plugins/observability_solution/entity_manager/*"], + "@kbn/entityManager-plugin": ["x-pack/plugins/entity_manager"], + "@kbn/entityManager-plugin/*": ["x-pack/plugins/entity_manager/*"], "@kbn/error-boundary-example-plugin": ["examples/error_boundary"], "@kbn/error-boundary-example-plugin/*": ["examples/error_boundary/*"], "@kbn/es": ["packages/kbn-es"], diff --git a/x-pack/plugins/observability_solution/entity_manager/README.md b/x-pack/plugins/entity_manager/README.md similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/README.md rename to x-pack/plugins/entity_manager/README.md diff --git a/x-pack/plugins/observability_solution/entity_manager/common/config.ts b/x-pack/plugins/entity_manager/common/config.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/common/config.ts rename to x-pack/plugins/entity_manager/common/config.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/common/constants_entities.ts b/x-pack/plugins/entity_manager/common/constants_entities.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/common/constants_entities.ts rename to x-pack/plugins/entity_manager/common/constants_entities.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/common/debug_log.ts b/x-pack/plugins/entity_manager/common/debug_log.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/common/debug_log.ts rename to x-pack/plugins/entity_manager/common/debug_log.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/common/errors.ts b/x-pack/plugins/entity_manager/common/errors.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/common/errors.ts rename to x-pack/plugins/entity_manager/common/errors.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/common/types_api.ts b/x-pack/plugins/entity_manager/common/types_api.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/common/types_api.ts rename to x-pack/plugins/entity_manager/common/types_api.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/docs/entity_definitions.md b/x-pack/plugins/entity_manager/docs/entity_definitions.md similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/docs/entity_definitions.md rename to x-pack/plugins/entity_manager/docs/entity_definitions.md diff --git a/x-pack/plugins/observability_solution/entity_manager/jest.config.js b/x-pack/plugins/entity_manager/jest.config.js similarity index 52% rename from x-pack/plugins/observability_solution/entity_manager/jest.config.js rename to x-pack/plugins/entity_manager/jest.config.js index 29fb7c37260fb..615d1c851895b 100644 --- a/x-pack/plugins/observability_solution/entity_manager/jest.config.js +++ b/x-pack/plugins/entity_manager/jest.config.js @@ -7,12 +7,11 @@ module.exports = { preset: '@kbn/test', - rootDir: '../../../..', - roots: ['/x-pack/plugins/observability_solution/entity_manager'], - coverageDirectory: - '/target/kibana-coverage/jest/x-pack/plugins/observability_solution/entity_manager', + rootDir: '../../..', + roots: ['/x-pack/plugins/entity_manager'], + coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/entity_manager', coverageReporters: ['text', 'html'], collectCoverageFrom: [ - '/x-pack/plugins/observability_solution/entity_manager/{common,public,server}/**/*.{js,ts,tsx}', + '/x-pack/plugins/entity_manager/{common,public,server}/**/*.{js,ts,tsx}', ], }; diff --git a/x-pack/plugins/observability_solution/entity_manager/kibana.jsonc b/x-pack/plugins/entity_manager/kibana.jsonc similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/kibana.jsonc rename to x-pack/plugins/entity_manager/kibana.jsonc diff --git a/x-pack/plugins/observability_solution/entity_manager/public/index.ts b/x-pack/plugins/entity_manager/public/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/public/index.ts rename to x-pack/plugins/entity_manager/public/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/public/lib/entity_client.ts b/x-pack/plugins/entity_manager/public/lib/entity_client.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/public/lib/entity_client.ts rename to x-pack/plugins/entity_manager/public/lib/entity_client.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/public/lib/errors.ts b/x-pack/plugins/entity_manager/public/lib/errors.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/public/lib/errors.ts rename to x-pack/plugins/entity_manager/public/lib/errors.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/public/plugin.ts b/x-pack/plugins/entity_manager/public/plugin.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/public/plugin.ts rename to x-pack/plugins/entity_manager/public/plugin.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/public/types.ts b/x-pack/plugins/entity_manager/public/types.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/public/types.ts rename to x-pack/plugins/entity_manager/public/types.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/index.ts b/x-pack/plugins/entity_manager/server/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/index.ts rename to x-pack/plugins/entity_manager/server/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts b/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts rename to x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/saved_object.ts b/x-pack/plugins/entity_manager/server/lib/auth/api_key/saved_object.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/saved_object.ts rename to x-pack/plugins/entity_manager/server/lib/auth/api_key/saved_object.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/index.ts b/x-pack/plugins/entity_manager/server/lib/auth/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/auth/index.ts rename to x-pack/plugins/entity_manager/server/lib/auth/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/privileges.ts b/x-pack/plugins/entity_manager/server/lib/auth/privileges.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/auth/privileges.ts rename to x-pack/plugins/entity_manager/server/lib/auth/privileges.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/client/index.ts b/x-pack/plugins/entity_manager/server/lib/client/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/client/index.ts rename to x-pack/plugins/entity_manager/server/lib/client/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/constants.ts b/x-pack/plugins/entity_manager/server/lib/entities/built_in/constants.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/constants.ts rename to x-pack/plugins/entity_manager/server/lib/entities/built_in/constants.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/index.ts b/x-pack/plugins/entity_manager/server/lib/entities/built_in/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/index.ts rename to x-pack/plugins/entity_manager/server/lib/entities/built_in/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/services.ts b/x-pack/plugins/entity_manager/server/lib/entities/built_in/services.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/built_in/services.ts rename to x-pack/plugins/entity_manager/server/lib/entities/built_in/services.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts b/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts rename to x-pack/plugins/entity_manager/server/lib/entities/create_and_install_ingest_pipeline.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/create_and_install_transform.ts b/x-pack/plugins/entity_manager/server/lib/entities/create_and_install_transform.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/create_and_install_transform.ts rename to x-pack/plugins/entity_manager/server/lib/entities/create_and_install_transform.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/delete_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/delete_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_index.ts b/x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_index.ts rename to x-pack/plugins/entity_manager/server/lib/entities/delete_index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_ingest_pipeline.ts b/x-pack/plugins/entity_manager/server/lib/entities/delete_ingest_pipeline.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_ingest_pipeline.ts rename to x-pack/plugins/entity_manager/server/lib/entities/delete_ingest_pipeline.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_transforms.ts b/x-pack/plugins/entity_manager/server/lib/entities/delete_transforms.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/delete_transforms.ts rename to x-pack/plugins/entity_manager/server/lib/entities/delete_transforms.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_definition_id_invalid.ts b/x-pack/plugins/entity_manager/server/lib/entities/errors/entity_definition_id_invalid.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_definition_id_invalid.ts rename to x-pack/plugins/entity_manager/server/lib/entities/errors/entity_definition_id_invalid.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_id_conflict_error.ts b/x-pack/plugins/entity_manager/server/lib/entities/errors/entity_id_conflict_error.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_id_conflict_error.ts rename to x-pack/plugins/entity_manager/server/lib/entities/errors/entity_id_conflict_error.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_not_found.ts b/x-pack/plugins/entity_manager/server/lib/entities/errors/entity_not_found.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_not_found.ts rename to x-pack/plugins/entity_manager/server/lib/entities/errors/entity_not_found.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_security_exception.ts b/x-pack/plugins/entity_manager/server/lib/entities/errors/entity_security_exception.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/entity_security_exception.ts rename to x-pack/plugins/entity_manager/server/lib/entities/errors/entity_security_exception.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/invalid_transform_error.ts b/x-pack/plugins/entity_manager/server/lib/entities/errors/invalid_transform_error.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/errors/invalid_transform_error.ts rename to x-pack/plugins/entity_manager/server/lib/entities/errors/invalid_transform_error.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/find_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/find_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/find_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/find_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/calculate_offset.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/calculate_offset.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/calculate_offset.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/calculate_offset.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/builtin_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/builtin_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/builtin_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/builtin_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/entity_definition_with_backfill.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/entity_definition_with_backfill.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/entity_definition_with_backfill.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/entity_definition_with_backfill.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/index.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/fixtures/index.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/fixtures/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/generate_component_id.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/generate_component_id.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/generate_component_id.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/generate_component_id.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/get_elasticsearch_query_or_throw.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/get_elasticsearch_query_or_throw.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/get_elasticsearch_query_or_throw.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/get_elasticsearch_query_or_throw.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/ingest_pipeline_script_processor_helpers.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/is_backfill_enabled.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/is_backfill_enabled.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/is_backfill_enabled.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/is_backfill_enabled.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/is_builtin_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/is_builtin_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/is_builtin_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/is_builtin_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/merge_definition_update.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/merge_definition_update.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/merge_definition_update.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/merge_definition_update.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/retry.ts b/x-pack/plugins/entity_manager/server/lib/entities/helpers/retry.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/helpers/retry.ts rename to x-pack/plugins/entity_manager/server/lib/entities/helpers/retry.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap rename to x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_history_processors.test.ts.snap diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap rename to x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/__snapshots__/generate_latest_processors.test.ts.snap diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts rename to x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_history_processors.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts b/x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts rename to x-pack/plugins/entity_manager/server/lib/entities/ingest_pipeline/generate_latest_processors.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/install_entity_definition.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/install_entity_definition.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/install_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/install_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/install_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/read_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/read_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/read_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/read_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/save_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/save_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/save_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/save_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/start_transforms.ts b/x-pack/plugins/entity_manager/server/lib/entities/start_transforms.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/start_transforms.ts rename to x-pack/plugins/entity_manager/server/lib/entities/start_transforms.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/stop_transforms.ts b/x-pack/plugins/entity_manager/server/lib/entities/stop_transforms.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/stop_transforms.ts rename to x-pack/plugins/entity_manager/server/lib/entities/stop_transforms.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/__snapshots__/entities_history_template.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/templates/__snapshots__/entities_history_template.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/__snapshots__/entities_history_template.test.ts.snap rename to x-pack/plugins/entity_manager/server/lib/entities/templates/__snapshots__/entities_history_template.test.ts.snap diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/__snapshots__/entities_latest_template.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/templates/__snapshots__/entities_latest_template.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/__snapshots__/entities_latest_template.test.ts.snap rename to x-pack/plugins/entity_manager/server/lib/entities/templates/__snapshots__/entities_latest_template.test.ts.snap diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_history_template.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/templates/entities_history_template.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_history_template.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/templates/entities_history_template.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_history_template.ts b/x-pack/plugins/entity_manager/server/lib/entities/templates/entities_history_template.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_history_template.ts rename to x-pack/plugins/entity_manager/server/lib/entities/templates/entities_history_template.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_latest_template.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/templates/entities_latest_template.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_latest_template.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/templates/entities_latest_template.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_latest_template.ts b/x-pack/plugins/entity_manager/server/lib/entities/templates/entities_latest_template.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/templates/entities_latest_template.ts rename to x-pack/plugins/entity_manager/server/lib/entities/templates/entities_latest_template.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap rename to x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_history_transform.test.ts.snap diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap b/x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap rename to x-pack/plugins/entity_manager/server/lib/entities/transform/__snapshots__/generate_latest_transform.test.ts.snap diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_history_transform.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_history_transform.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_history_transform.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_history_transform.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_history_transform.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_history_transform.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_history_transform.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_history_transform.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_identity_aggregations.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_identity_aggregations.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_identity_aggregations.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_identity_aggregations.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_latest_transform.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_latest_transform.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_latest_transform.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_latest_transform.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_latest_transform.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_metadata_aggregations.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_metric_aggregations.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/generate_metric_aggregations.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/generate_metric_aggregations.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/generate_metric_aggregations.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/validate_transform_ids.test.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/validate_transform_ids.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/validate_transform_ids.test.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/validate_transform_ids.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/validate_transform_ids.ts b/x-pack/plugins/entity_manager/server/lib/entities/transform/validate_transform_ids.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/transform/validate_transform_ids.ts rename to x-pack/plugins/entity_manager/server/lib/entities/transform/validate_transform_ids.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/types.ts b/x-pack/plugins/entity_manager/server/lib/entities/types.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/types.ts rename to x-pack/plugins/entity_manager/server/lib/entities/types.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/uninstall_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/uninstall_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/uninstall_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/uninstall_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entities/upgrade_entity_definition.ts b/x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entities/upgrade_entity_definition.ts rename to x-pack/plugins/entity_manager/server/lib/entities/upgrade_entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/entity_client.ts b/x-pack/plugins/entity_manager/server/lib/entity_client.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/entity_client.ts rename to x-pack/plugins/entity_manager/server/lib/entity_client.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/errors.ts b/x-pack/plugins/entity_manager/server/lib/errors.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/errors.ts rename to x-pack/plugins/entity_manager/server/lib/errors.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/manage_index_templates.ts b/x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/manage_index_templates.ts rename to x-pack/plugins/entity_manager/server/lib/manage_index_templates.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/utils.ts b/x-pack/plugins/entity_manager/server/lib/utils.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/utils.ts rename to x-pack/plugins/entity_manager/server/lib/utils.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/validators/validate_date_range.ts b/x-pack/plugins/entity_manager/server/lib/validators/validate_date_range.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/validators/validate_date_range.ts rename to x-pack/plugins/entity_manager/server/lib/validators/validate_date_range.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/lib/validators/validation_error.ts b/x-pack/plugins/entity_manager/server/lib/validators/validation_error.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/lib/validators/validation_error.ts rename to x-pack/plugins/entity_manager/server/lib/validators/validation_error.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/plugin.ts b/x-pack/plugins/entity_manager/server/plugin.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/plugin.ts rename to x-pack/plugins/entity_manager/server/plugin.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/create_entity_manager_server_route.ts b/x-pack/plugins/entity_manager/server/routes/create_entity_manager_server_route.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/create_entity_manager_server_route.ts rename to x-pack/plugins/entity_manager/server/routes/create_entity_manager_server_route.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/check.ts b/x-pack/plugins/entity_manager/server/routes/enablement/check.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/check.ts rename to x-pack/plugins/entity_manager/server/routes/enablement/check.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/disable.ts b/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/disable.ts rename to x-pack/plugins/entity_manager/server/routes/enablement/disable.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/enable.ts b/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/enable.ts rename to x-pack/plugins/entity_manager/server/routes/enablement/enable.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/index.ts b/x-pack/plugins/entity_manager/server/routes/enablement/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/index.ts rename to x-pack/plugins/entity_manager/server/routes/enablement/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/entities/create.ts b/x-pack/plugins/entity_manager/server/routes/entities/create.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/entities/create.ts rename to x-pack/plugins/entity_manager/server/routes/entities/create.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/entities/delete.ts b/x-pack/plugins/entity_manager/server/routes/entities/delete.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/entities/delete.ts rename to x-pack/plugins/entity_manager/server/routes/entities/delete.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/entities/get.ts b/x-pack/plugins/entity_manager/server/routes/entities/get.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/entities/get.ts rename to x-pack/plugins/entity_manager/server/routes/entities/get.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/entities/index.ts b/x-pack/plugins/entity_manager/server/routes/entities/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/entities/index.ts rename to x-pack/plugins/entity_manager/server/routes/entities/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/entities/reset.ts b/x-pack/plugins/entity_manager/server/routes/entities/reset.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/entities/reset.ts rename to x-pack/plugins/entity_manager/server/routes/entities/reset.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/entities/update.ts b/x-pack/plugins/entity_manager/server/routes/entities/update.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/entities/update.ts rename to x-pack/plugins/entity_manager/server/routes/entities/update.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/index.ts b/x-pack/plugins/entity_manager/server/routes/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/index.ts rename to x-pack/plugins/entity_manager/server/routes/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/routes/types.ts b/x-pack/plugins/entity_manager/server/routes/types.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/routes/types.ts rename to x-pack/plugins/entity_manager/server/routes/types.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/saved_objects/entity_definition.ts b/x-pack/plugins/entity_manager/server/saved_objects/entity_definition.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/saved_objects/entity_definition.ts rename to x-pack/plugins/entity_manager/server/saved_objects/entity_definition.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/saved_objects/entity_discovery_api_key.ts b/x-pack/plugins/entity_manager/server/saved_objects/entity_discovery_api_key.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/saved_objects/entity_discovery_api_key.ts rename to x-pack/plugins/entity_manager/server/saved_objects/entity_discovery_api_key.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/saved_objects/index.ts b/x-pack/plugins/entity_manager/server/saved_objects/index.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/saved_objects/index.ts rename to x-pack/plugins/entity_manager/server/saved_objects/index.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/templates/components/base_history.ts b/x-pack/plugins/entity_manager/server/templates/components/base_history.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/templates/components/base_history.ts rename to x-pack/plugins/entity_manager/server/templates/components/base_history.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/templates/components/base_latest.ts b/x-pack/plugins/entity_manager/server/templates/components/base_latest.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/templates/components/base_latest.ts rename to x-pack/plugins/entity_manager/server/templates/components/base_latest.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/templates/components/entity.ts b/x-pack/plugins/entity_manager/server/templates/components/entity.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/templates/components/entity.ts rename to x-pack/plugins/entity_manager/server/templates/components/entity.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/templates/components/event.ts b/x-pack/plugins/entity_manager/server/templates/components/event.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/templates/components/event.ts rename to x-pack/plugins/entity_manager/server/templates/components/event.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/templates/components/helpers.test.ts b/x-pack/plugins/entity_manager/server/templates/components/helpers.test.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/templates/components/helpers.test.ts rename to x-pack/plugins/entity_manager/server/templates/components/helpers.test.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/templates/components/helpers.ts b/x-pack/plugins/entity_manager/server/templates/components/helpers.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/templates/components/helpers.ts rename to x-pack/plugins/entity_manager/server/templates/components/helpers.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/server/types.ts b/x-pack/plugins/entity_manager/server/types.ts similarity index 100% rename from x-pack/plugins/observability_solution/entity_manager/server/types.ts rename to x-pack/plugins/entity_manager/server/types.ts diff --git a/x-pack/plugins/observability_solution/entity_manager/tsconfig.json b/x-pack/plugins/entity_manager/tsconfig.json similarity index 90% rename from x-pack/plugins/observability_solution/entity_manager/tsconfig.json rename to x-pack/plugins/entity_manager/tsconfig.json index 7d1c0f378854f..29c100ee4c9d2 100644 --- a/x-pack/plugins/observability_solution/entity_manager/tsconfig.json +++ b/x-pack/plugins/entity_manager/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../../tsconfig.base.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "outDir": "target/types" }, @@ -10,7 +10,9 @@ "public/**/*", "types/**/*" ], - "exclude": ["target/**/*"], + "exclude": [ + "target/**/*" + ], "kbn_references": [ "@kbn/config-schema", "@kbn/entities-schema", diff --git a/yarn.lock b/yarn.lock index b86acda2e0739..408d93ad5ee99 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4874,7 +4874,7 @@ version "0.0.0" uid "" -"@kbn/entityManager-plugin@link:x-pack/plugins/observability_solution/entity_manager": +"@kbn/entityManager-plugin@link:x-pack/plugins/entity_manager": version "0.0.0" uid "" From ca8e53fb3a85ba8abfcf9cc247cdcfcf30a79cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Efe=20G=C3=BCrkan=20YALAMAN?= Date: Mon, 16 Sep 2024 14:31:38 +0200 Subject: [PATCH 013/139] [Search Playground] Search Preview and Document Viewer (#192096) ## Summary Adds Search preview functionality to Search Playground Adds Unified Document Viewer flyout to the Search Playground All of these code are under the same UI setting that we had for Search Playground. https://github.com/user-attachments/assets/cd590414-b22f-4cde-a7e1-ca139aefe178 This introduces new dependencies to the plugin, locally there was no problem visible (i.e. no warnings or something weird in Kibana logs) ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [x] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Potential breaking in Chat Playground Need to be tested | Low | Medium | It should be tested by at least another person feature flag off in Chat playground both Stack and Serverless | --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/search_playground/common/index.ts | 8 ++ .../plugins/search_playground/common/types.ts | 7 + x-pack/plugins/search_playground/kibana.jsonc | 4 +- .../public/components/header.tsx | 2 +- .../components/search_mode/empty_results.tsx | 34 +++++ .../components/search_mode/result_list.tsx | 133 +++++++++++++----- .../components/search_mode/search_mode.tsx | 80 +++++++++-- .../public/components/toolbar.tsx | 7 +- .../view_code/examples/dev_tools.tsx | 30 ++++ .../components/view_code/view_code_action.tsx | 10 +- .../components/view_code/view_code_flyout.tsx | 67 +++++---- .../public/hooks/use_search_preview.ts | 87 ++++++++++++ .../public/providers/form_provider.test.tsx | 2 + .../public/providers/form_provider.tsx | 10 +- .../plugins/search_playground/public/types.ts | 8 +- .../public/utils/pagination_helper.ts | 20 +++ .../search_playground/server/routes.ts | 65 +++++++++ .../plugins/search_playground/tsconfig.json | 6 +- 18 files changed, 493 insertions(+), 87 deletions(-) create mode 100644 x-pack/plugins/search_playground/public/components/search_mode/empty_results.tsx create mode 100644 x-pack/plugins/search_playground/public/components/view_code/examples/dev_tools.tsx create mode 100644 x-pack/plugins/search_playground/public/hooks/use_search_preview.ts create mode 100644 x-pack/plugins/search_playground/public/utils/pagination_helper.ts diff --git a/x-pack/plugins/search_playground/common/index.ts b/x-pack/plugins/search_playground/common/index.ts index 533dfa612ee44..95624681b6193 100644 --- a/x-pack/plugins/search_playground/common/index.ts +++ b/x-pack/plugins/search_playground/common/index.ts @@ -5,8 +5,16 @@ * 2.0. */ +import { Pagination } from './types'; + export const PLUGIN_ID = 'searchPlayground'; export const PLUGIN_NAME = 'Playground'; export const PLUGIN_PATH = '/app/search_playground'; export const SEARCH_MODE_FEATURE_FLAG_ID = 'searchPlayground:searchModeEnabled'; + +export const DEFAULT_PAGINATION: Pagination = { + from: 0, + size: 10, + total: 0, +}; diff --git a/x-pack/plugins/search_playground/common/types.ts b/x-pack/plugins/search_playground/common/types.ts index deeec8156a988..c0e3300fe7dff 100644 --- a/x-pack/plugins/search_playground/common/types.ts +++ b/x-pack/plugins/search_playground/common/types.ts @@ -50,6 +50,7 @@ export enum APIRoutes { POST_CHAT_MESSAGE = '/internal/search_playground/chat', POST_QUERY_SOURCE_FIELDS = '/internal/search_playground/query_source_fields', GET_INDICES = '/internal/search_playground/indices', + POST_SEARCH_QUERY = '/internal/search_playground/search', } export enum LLMs { @@ -82,3 +83,9 @@ export interface ModelProvider { promptTokenLimit: number; provider: LLMs; } + +export interface Pagination { + from: number; + size: number; + total: number; +} diff --git a/x-pack/plugins/search_playground/kibana.jsonc b/x-pack/plugins/search_playground/kibana.jsonc index f1913dbd0f345..e9dedf0fe716f 100644 --- a/x-pack/plugins/search_playground/kibana.jsonc +++ b/x-pack/plugins/search_playground/kibana.jsonc @@ -12,6 +12,7 @@ ], "requiredPlugins": [ "actions", + "data", "encryptedSavedObjects", "navigation", "share", @@ -25,7 +26,8 @@ "usageCollection", ], "requiredBundles": [ - "kibanaReact" + "kibanaReact", + "unifiedDocViewer" ] } } diff --git a/x-pack/plugins/search_playground/public/components/header.tsx b/x-pack/plugins/search_playground/public/components/header.tsx index b5ef4b2b3024f..0d6d48a903462 100644 --- a/x-pack/plugins/search_playground/public/components/header.tsx +++ b/x-pack/plugins/search_playground/public/components/header.tsx @@ -115,7 +115,7 @@ export const Header: React.FC = ({ {showDocs && } - + diff --git a/x-pack/plugins/search_playground/public/components/search_mode/empty_results.tsx b/x-pack/plugins/search_playground/public/components/search_mode/empty_results.tsx new file mode 100644 index 0000000000000..ab5779e85ddd5 --- /dev/null +++ b/x-pack/plugins/search_playground/public/components/search_mode/empty_results.tsx @@ -0,0 +1,34 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiEmptyPrompt } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +export interface EmptyResultsArgs { + query?: string; +} + +export const EmptyResults: React.FC = ({ query }) => { + return ( + + {query + ? i18n.translate('xpack.searchPlayground.resultList.emptyWithQuery.text', { + defaultMessage: 'No result found for: {query}', + values: { query }, + }) + : i18n.translate('xpack.searchPlayground.resultList.empty.text', { + defaultMessage: 'No results found', + })} +

+ } + /> + ); +}; diff --git a/x-pack/plugins/search_playground/public/components/search_mode/result_list.tsx b/x-pack/plugins/search_playground/public/components/search_mode/result_list.tsx index ca6bc48549ada..02e1193e22332 100644 --- a/x-pack/plugins/search_playground/public/components/search_mode/result_list.tsx +++ b/x-pack/plugins/search_playground/public/components/search_mode/result_list.tsx @@ -5,54 +5,117 @@ * 2.0. */ +import React, { useEffect, useState } from 'react'; + import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, + EuiPagination, EuiPanel, EuiText, EuiTitle, } from '@elastic/eui'; -import React from 'react'; -const DEMO_DATA = [ - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, - { id: '123321', name: 'John Doe', age: 25 }, -]; +import { UnifiedDocViewerFlyout } from '@kbn/unified-doc-viewer-plugin/public'; + +import type { DataView } from '@kbn/data-views-plugin/public'; +import type { EsHitRecord } from '@kbn/discover-utils/types'; +import type { SearchHit } from '@elastic/elasticsearch/lib/api/types'; +import { buildDataTableRecord } from '@kbn/discover-utils'; +import { i18n } from '@kbn/i18n'; +import { Pagination } from '../../types'; +import { getPageCounts } from '../../utils/pagination_helper'; +import { EmptyResults } from './empty_results'; +import { useKibana } from '../../hooks/use_kibana'; + +export interface ResultListArgs { + searchResults: SearchHit[]; + pagination: Pagination; + onPaginationChange: (nextPage: number) => void; + searchQuery?: string; +} -export const ResultList: React.FC = () => { +export const ResultList: React.FC = ({ + searchResults, + pagination, + onPaginationChange, + searchQuery = '', +}) => { + const { + services: { data }, + } = useKibana(); + const [dataView, setDataView] = useState(null); + useEffect(() => { + data.dataViews.getDefaultDataView().then((d) => setDataView(d)); + }, [data]); + const [flyoutDocId, setFlyoutDocId] = useState(undefined); + const { totalPage, page } = getPageCounts(pagination); + const hit = + flyoutDocId && + buildDataTableRecord(searchResults.find((item) => item._id === flyoutDocId) as EsHitRecord); return ( - {DEMO_DATA.map((item, index) => { - return ( - <> - - - - -

{item.id}

-
-
- - -

{item.name}

-
-
-
-
- {index !== DEMO_DATA.length - 1 && } - - ); - })} + {searchResults.length === 0 && ( + + + + )} + {searchResults.length !== 0 && + searchResults.map((item, index) => { + return ( + <> + setFlyoutDocId(item._id)} + grow + > + + + +

ID:{item._id}

+
+
+ + +

+ {i18n.translate('xpack.searchPlayground.resultList.result.score', { + defaultMessage: 'Document score: {score}', + values: { score: item._score }, + })} +

+
+
+
+
+ {index !== searchResults.length - 1 && } + + ); + })} + {searchResults.length !== 0 && ( + + + + )} + {flyoutDocId && dataView && hit && ( + setFlyoutDocId(undefined)} + isEsqlQuery={false} + columns={[]} + hit={hit} + dataView={dataView} + onAddColumn={() => {}} + onRemoveColumn={() => {}} + setExpandedDoc={() => {}} + flyoutType="overlay" + /> + )}
); diff --git a/x-pack/plugins/search_playground/public/components/search_mode/search_mode.tsx b/x-pack/plugins/search_playground/public/components/search_mode/search_mode.tsx index ed6b2ed70c188..967c5786eed63 100644 --- a/x-pack/plugins/search_playground/public/components/search_mode/search_mode.tsx +++ b/x-pack/plugins/search_playground/public/components/search_mode/search_mode.tsx @@ -6,20 +6,50 @@ */ import { - EuiButton, EuiEmptyPrompt, + EuiFieldText, EuiFlexGroup, EuiFlexItem, - EuiSearchBar, + EuiForm, useEuiTheme, } from '@elastic/eui'; import React from 'react'; import { css } from '@emotion/react'; +import { Controller, useController, useFormContext } from 'react-hook-form'; +import { i18n } from '@kbn/i18n'; +import { useQueryClient } from '@tanstack/react-query'; +import { DEFAULT_PAGINATION } from '../../../common'; import { ResultList } from './result_list'; +import { ChatForm, ChatFormFields, Pagination } from '../../types'; +import { useSearchPreview } from '../../hooks/use_search_preview'; +import { getPaginationFromPage } from '../../utils/pagination_helper'; export const SearchMode: React.FC = () => { const { euiTheme } = useEuiTheme(); - const showResults = true; // TODO demo + const { control, handleSubmit } = useFormContext(); + const { + field: { value: searchBarValue }, + formState: { isSubmitting }, + } = useController({ + name: ChatFormFields.searchQuery, + }); + + const [searchQuery, setSearchQuery] = React.useState<{ + query: string; + pagination: Pagination; + }>({ query: searchBarValue, pagination: DEFAULT_PAGINATION }); + + const { results, pagination } = useSearchPreview(searchQuery); + + const queryClient = useQueryClient(); + const handleSearch = async (query = searchBarValue, paginationParam = DEFAULT_PAGINATION) => { + queryClient.resetQueries({ queryKey: ['search-preview-results'] }); + setSearchQuery({ query, pagination: paginationParam }); + }; + + const onPagination = (page: number) => { + handleSearch(searchBarValue, getPaginationFromPage(page, pagination.size, pagination)); + }; return ( @@ -31,25 +61,55 @@ export const SearchMode: React.FC = () => { > - + handleSearch())}> + ( + + )} + /> + - {showResults ? ( - + {searchQuery.query ? ( + ) : ( Ready to search} + title={ +

+ {i18n.translate('xpack.searchPlayground.searchMode.readyToSearch', { + defaultMessage: 'Ready to search', + })} +

+ } body={

- Type in a query in the search bar above or view the query we automatically - created for you. + {i18n.translate('xpack.searchPlayground.searchMode.searchPrompt', { + defaultMessage: + 'Type in a query in the search bar above or view the query we automatically created for you.', + })}

} - actions={View the query} /> )}
diff --git a/x-pack/plugins/search_playground/public/components/toolbar.tsx b/x-pack/plugins/search_playground/public/components/toolbar.tsx index 31ea3345cdcbe..80889bee833db 100644 --- a/x-pack/plugins/search_playground/public/components/toolbar.tsx +++ b/x-pack/plugins/search_playground/public/components/toolbar.tsx @@ -9,12 +9,15 @@ import { EuiFlexGroup } from '@elastic/eui'; import React from 'react'; import { DataActionButton } from './data_action_button'; import { ViewCodeAction } from './view_code/view_code_action'; +import { PlaygroundPageMode } from '../types'; -export const Toolbar: React.FC = () => { +export const Toolbar: React.FC<{ selectedPageMode: PlaygroundPageMode }> = ({ + selectedPageMode = PlaygroundPageMode.chat, +}) => { return ( - + ); }; diff --git a/x-pack/plugins/search_playground/public/components/view_code/examples/dev_tools.tsx b/x-pack/plugins/search_playground/public/components/view_code/examples/dev_tools.tsx new file mode 100644 index 0000000000000..9059d58db821e --- /dev/null +++ b/x-pack/plugins/search_playground/public/components/view_code/examples/dev_tools.tsx @@ -0,0 +1,30 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiCodeBlock } from '@elastic/eui'; +import { useFormContext } from 'react-hook-form'; +import { ChatFormFields } from '../../../types'; + +export const DevToolsCode: React.FC = () => { + const { getValues } = useFormContext(); + const query = getValues(ChatFormFields.elasticsearchQuery) ?? ''; + const indices = getValues(ChatFormFields.indices) ?? []; + const searchQuery = getValues(ChatFormFields.searchQuery) ?? ''; + const replacedQuery = searchQuery + ? JSON.stringify(query, null, 2).replace(/\"{query}\"/g, JSON.stringify(searchQuery)) + : JSON.stringify(query, null, 2); + + return ( + + {`POST ${indices.join(',')}/_search +${replacedQuery} +`} + + ); +}; diff --git a/x-pack/plugins/search_playground/public/components/view_code/view_code_action.tsx b/x-pack/plugins/search_playground/public/components/view_code/view_code_action.tsx index 13b6a2119757a..768d176a337f0 100644 --- a/x-pack/plugins/search_playground/public/components/view_code/view_code_action.tsx +++ b/x-pack/plugins/search_playground/public/components/view_code/view_code_action.tsx @@ -9,17 +9,21 @@ import React, { useState } from 'react'; import { EuiButton } from '@elastic/eui'; import { useFormContext } from 'react-hook-form'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ChatForm, ChatFormFields } from '../../types'; +import { ChatForm, ChatFormFields, PlaygroundPageMode } from '../../types'; import { ViewCodeFlyout } from './view_code_flyout'; -export const ViewCodeAction: React.FC = () => { +export const ViewCodeAction: React.FC<{ selectedPageMode: PlaygroundPageMode }> = ({ + selectedPageMode = PlaygroundPageMode.chat, +}) => { const { watch } = useFormContext(); const [showFlyout, setShowFlyout] = useState(false); const selectedIndices = watch(ChatFormFields.indices); return ( <> - {showFlyout && setShowFlyout(false)} />} + {showFlyout && ( + setShowFlyout(false)} /> + )} void; + selectedPageMode: PlaygroundPageMode; } export const ES_CLIENT_DETAILS = (cloud: CloudSetup | undefined) => { @@ -50,7 +52,7 @@ es_client = Elasticsearch( `; }; -export const ViewCodeFlyout: React.FC = ({ onClose }) => { +export const ViewCodeFlyout: React.FC = ({ onClose, selectedPageMode }) => { const usageTracker = useUsageTracker(); const [selectedLanguage, setSelectedLanguage] = useState('py-es-client'); const { getValues } = useFormContext(); @@ -101,34 +103,43 @@ export const ViewCodeFlyout: React.FC = ({ onClose }) => { - - - - - - - + + - - - + + + + + + + + )}
- {steps[selectedLanguage]} + {selectedPageMode === PlaygroundPageMode.chat && ( + {steps[selectedLanguage]} + )} + {selectedPageMode === PlaygroundPageMode.search && ( + + + + )}
diff --git a/x-pack/plugins/search_playground/public/hooks/use_search_preview.ts b/x-pack/plugins/search_playground/public/hooks/use_search_preview.ts new file mode 100644 index 0000000000000..54566563fcee5 --- /dev/null +++ b/x-pack/plugins/search_playground/public/hooks/use_search_preview.ts @@ -0,0 +1,87 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SearchHit } from '@elastic/elasticsearch/lib/api/types'; +import { useQuery } from '@tanstack/react-query'; +import { useFormContext } from 'react-hook-form'; +import { APIRoutes, ChatForm, ChatFormFields, Pagination } from '../types'; +import { useKibana } from './use_kibana'; +import { DEFAULT_PAGINATION } from '../../common'; + +export interface FetchSearchResultsArgs { + query: string; + pagination: Pagination; + indices: ChatForm[ChatFormFields.indices]; + elasticsearchQuery: ChatForm[ChatFormFields.elasticsearchQuery]; + http: ReturnType['services']['http']; +} + +interface UseSearchPreviewData { + results: SearchHit[]; + pagination: Pagination; +} + +export interface UseSearchPreviewResponse { + fetchSearchResults: (args: FetchSearchResultsArgs) => Promise; + data: UseSearchPreviewData; +} + +export const DEFAULT_SEARCH_PREVIEW_DATA: UseSearchPreviewData = { + results: [], + pagination: DEFAULT_PAGINATION, +}; + +export const fetchSearchResults = async ({ + query, + indices, + elasticsearchQuery, + pagination: paginationParam = DEFAULT_PAGINATION, + http, +}: FetchSearchResultsArgs): Promise => { + const { results, pagination: paginationResult } = await http.post<{ + results: SearchHit[]; + pagination: Pagination; + }>(APIRoutes.POST_SEARCH_QUERY, { + body: JSON.stringify({ + search_query: query, + elasticsearch_query: JSON.stringify(elasticsearchQuery), + indices, + size: paginationParam.size, + from: paginationParam.from, + }), + }); + return { results, pagination: paginationResult }; +}; + +export const useSearchPreview = ({ + query, + pagination, +}: { + query: string; + pagination: Pagination; +}) => { + const { services } = useKibana(); + const { getValues } = useFormContext(); + const { http } = services; + const indices = getValues(ChatFormFields.indices); + const elasticsearchQuery = getValues(ChatFormFields.elasticsearchQuery); + + const { data } = useQuery({ + queryKey: ['search-preview-results', query, indices, elasticsearchQuery, pagination], + queryFn: () => fetchSearchResults({ query, pagination, http, indices, elasticsearchQuery }), + initialData: DEFAULT_SEARCH_PREVIEW_DATA, + enabled: !!query, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, + }); + + return { + pagination: data.pagination, + results: data.results, + }; +}; diff --git a/x-pack/plugins/search_playground/public/providers/form_provider.test.tsx b/x-pack/plugins/search_playground/public/providers/form_provider.test.tsx index c946555e16f95..96c86ad184931 100644 --- a/x-pack/plugins/search_playground/public/providers/form_provider.test.tsx +++ b/x-pack/plugins/search_playground/public/providers/form_provider.test.tsx @@ -66,6 +66,7 @@ describe('FormProvider', () => { doc_size: 3, indices: [], prompt: 'You are an assistant for question-answering tasks.', + search_query: '', source_fields: {}, summarization_model: undefined, }); @@ -171,6 +172,7 @@ describe('FormProvider', () => { prompt: 'Loaded prompt', doc_size: 3, source_fields: {}, + search_query: '', indices: [], summarization_model: undefined, }); diff --git a/x-pack/plugins/search_playground/public/providers/form_provider.tsx b/x-pack/plugins/search_playground/public/providers/form_provider.tsx index 1c804663af9e6..f352688fe89f1 100644 --- a/x-pack/plugins/search_playground/public/providers/form_provider.tsx +++ b/x-pack/plugins/search_playground/public/providers/form_provider.tsx @@ -37,8 +37,8 @@ const getLocalSession = (storage: Storage): PartialChatForm => { }; const setLocalSession = (formState: PartialChatForm, storage: Storage) => { - // omit question from the session state - const { question, ...state } = formState; + // omit question and search_query from the session state + const { question, search_query: searchQuery, ...state } = formState; storage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(state)); }; @@ -56,7 +56,11 @@ export const FormProvider: React.FC> const index = useMemo(() => searchParams.get('default-index'), [searchParams]); const sessionState = useMemo(() => getLocalSession(storage), [storage]); const form = useForm({ - defaultValues: { ...sessionState, indices: index ? [index] : sessionState.indices }, + defaultValues: { + ...sessionState, + indices: index ? [index] : sessionState.indices, + search_query: '', + }, }); useLoadFieldsByIndices({ watch: form.watch, setValue: form.setValue, getValues: form.getValues }); diff --git a/x-pack/plugins/search_playground/public/types.ts b/x-pack/plugins/search_playground/public/types.ts index dd690c935312c..ff9c56ffb553e 100644 --- a/x-pack/plugins/search_playground/public/types.ts +++ b/x-pack/plugins/search_playground/public/types.ts @@ -21,6 +21,7 @@ import { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui- import { AppMountParameters } from '@kbn/core/public'; import { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; import type { ConsolePluginStart } from '@kbn/console-plugin/public'; +import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { ChatRequestData, MessageRole } from '../common/types'; import type { App } from './components/app'; import type { PlaygroundProvider as PlaygroundProviderComponent } from './providers/playground_provider'; @@ -52,6 +53,7 @@ export interface AppPluginStartDependencies { triggersActionsUi: TriggersAndActionsUIPublicPluginStart; share: SharePluginStart; console?: ConsolePluginStart; + data: DataPublicPluginStart; } export interface AppServicesContext { @@ -62,9 +64,7 @@ export interface AppServicesContext { triggersActionsUi: TriggersAndActionsUIPublicPluginStart; usageCollection?: UsageCollectionStart; console?: ConsolePluginStart; - featureFlags: { - searchPlaygroundEnabled: boolean; - }; + data: DataPublicPluginStart; } export enum ChatFormFields { @@ -77,6 +77,7 @@ export enum ChatFormFields { sourceFields = 'source_fields', docSize = 'doc_size', queryFields = 'query_fields', + searchQuery = 'search_query', } export interface ChatForm { @@ -89,6 +90,7 @@ export interface ChatForm { [ChatFormFields.sourceFields]: { [index: string]: string[] }; [ChatFormFields.docSize]: number; [ChatFormFields.queryFields]: { [index: string]: string[] }; + [ChatFormFields.searchQuery]: string; } export interface Message { diff --git a/x-pack/plugins/search_playground/public/utils/pagination_helper.ts b/x-pack/plugins/search_playground/public/utils/pagination_helper.ts new file mode 100644 index 0000000000000..1379bbc257bd4 --- /dev/null +++ b/x-pack/plugins/search_playground/public/utils/pagination_helper.ts @@ -0,0 +1,20 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Pagination } from '../../common/types'; + +export const getPageCounts = (pagination: Pagination) => { + const { total, from, size } = pagination; + const totalPage = Math.ceil(total / size); + const page = Math.floor(from / size); + return { totalPage, total, page, size }; +}; + +export const getPaginationFromPage = (page: number, size: number, previousValue: Pagination) => { + const from = page < 0 ? 0 : page * size; + return { ...previousValue, from, size, page }; +}; diff --git a/x-pack/plugins/search_playground/server/routes.ts b/x-pack/plugins/search_playground/server/routes.ts index 8d7769020f445..d30904214d8df 100644 --- a/x-pack/plugins/search_playground/server/routes.ts +++ b/x-pack/plugins/search_playground/server/routes.ts @@ -240,4 +240,69 @@ export function defineRoutes({ }); }) ); + + router.post( + { + path: APIRoutes.POST_SEARCH_QUERY, + validate: { + body: schema.object({ + search_query: schema.string(), + elasticsearch_query: schema.string(), + indices: schema.arrayOf(schema.string()), + size: schema.maybe(schema.number({ defaultValue: 10, min: 0 })), + from: schema.maybe(schema.number({ defaultValue: 0, min: 0 })), + }), + }, + }, + errorHandler(logger)(async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const { elasticsearch_query: elasticsearchQuery, indices, size, from } = request.body; + + try { + if (indices.length === 0) { + return response.badRequest({ + body: { + message: 'Indices cannot be empty', + }, + }); + } + + const retriever = createRetriever(elasticsearchQuery)(request.body.search_query); + const searchResult = await client.asCurrentUser.search({ + index: indices, + retriever: retriever.retriever, + from, + size, + }); + const total = searchResult.hits.total + ? typeof searchResult.hits.total === 'object' + ? searchResult.hits.total.value + : searchResult.hits.total + : 0; + + return response.ok({ + body: { + results: searchResult.hits.hits, + pagination: { + from, + size, + total, + }, + }, + }); + } catch (e) { + logger.error('Failed to search the query', e); + + if (typeof e === 'object' && e.message) { + return response.badRequest({ + body: { + message: e.message, + }, + }); + } + + throw e; + } + }) + ); } diff --git a/x-pack/plugins/search_playground/tsconfig.json b/x-pack/plugins/search_playground/tsconfig.json index dc481d35327f2..eebfd0df9a7b3 100644 --- a/x-pack/plugins/search_playground/tsconfig.json +++ b/x-pack/plugins/search_playground/tsconfig.json @@ -40,7 +40,11 @@ "@kbn/usage-collection-plugin", "@kbn/console-plugin", "@kbn/utility-types", - "@kbn/kibana-utils-plugin" + "@kbn/kibana-utils-plugin", + "@kbn/unified-doc-viewer-plugin", + "@kbn/data-views-plugin", + "@kbn/discover-utils", + "@kbn/data-plugin" ], "exclude": [ "target/**/*", From 61fcb0f0722afab8f546315ae5e1dd75a730b741 Mon Sep 17 00:00:00 2001 From: Irene Blanco Date: Mon, 16 Sep 2024 14:34:40 +0200 Subject: [PATCH 014/139] [APM[Services] Add custom events to new ServiceTabEmptyState (#192385) ## Summary Closes https://github.com/elastic/kibana/issues/190770. With the new empty state added for certain tabs when a service only has log signals, we're introducing telemetry to track its usage and impact. The events being implemented have been defined [here](https://github.com/elastic/observability-dev/issues/3462#issuecomment-2324980335) and agreed upon with product. |Button/Link|Sent event| |-|-| |Add APM|![Screenshot 2024-09-09 at 17 33 50](https://github.com/user-attachments/assets/a0331727-1b32-41bf-85fe-322d5b519f8b)| |Try it|![Screenshot 2024-09-09 at 17 34 10](https://github.com/user-attachments/assets/c92633b1-adfc-4787-a147-44c76f50a07b)| |Learn more|![Screenshot 2024-09-09 at 17 34 22](https://github.com/user-attachments/assets/9a8eae57-f810-4414-968e-6968c65029d6)| --------- Co-authored-by: Katerina Co-authored-by: Caue Marcondes --- .../components/app/service_overview/index.tsx | 4 +-- .../app/service_tab_empty_state/constants.ts | 2 +- .../app/service_tab_empty_state/index.tsx | 35 ++++++++++++++++++- .../services/telemetry/telemetry_client.ts | 9 +++++ .../services/telemetry/telemetry_events.ts | 28 +++++++++++++++ .../apm/public/services/telemetry/types.ts | 11 +++++- 6 files changed, 84 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_overview/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/service_overview/index.tsx index e406eba65f678..3475f622edebe 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_overview/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_overview/index.tsx @@ -60,10 +60,10 @@ export function ServiceOverview() { const hasSignal = serviceEntitySummary?.dataStreamTypes && serviceEntitySummary?.dataStreamTypes?.length > 0; - const hasLogsSignal = hasSignal && isLogsSignal(serviceEntitySummary.dataStreamTypes); - const hasLogsOnlySignal = hasSignal && isLogsOnlySignal(serviceEntitySummary.dataStreamTypes); + const hasLogsSignal = hasSignal && isLogsSignal(serviceEntitySummary.dataStreamTypes); + // Shows APM overview when entity has APM signal or when Entity centric is not enabled const hasApmSignal = hasSignal && isApmSignal(serviceEntitySummary.dataStreamTypes); diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/constants.ts b/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/constants.ts index 8165ad991cfe2..8551745238e43 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/constants.ts +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/constants.ts @@ -38,7 +38,7 @@ export const emptyStateDefinitions: Record = { }), content: i18n.translate('xpack.apm.serviceTabEmptyState.dependenciesContent', { defaultMessage: - 'See your services dependencies on both internal and third-party services by instrumenting with APM.', + "See your service's dependencies on both internal and third-party services by instrumenting with APM.", }), imgName: 'service_tab_empty_state_dependencies.png', }, diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/index.tsx index 8f4f86e2b92ed..a8962fcc1d2f7 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/app/service_tab_empty_state/index.tsx @@ -4,6 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + +/* eslint-disable @elastic/eui/href-or-on-click */ + import { EuiButton, EuiButtonIcon, @@ -19,6 +22,9 @@ import { } from '@elastic/eui'; import React from 'react'; import { i18n } from '@kbn/i18n'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { EmptyStateClickParams, EntityInventoryAddDataParams } from '../../../services/telemetry'; +import { ApmPluginStartDeps, ApmServices } from '../../../plugin'; import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { useKibanaUrl } from '../../../hooks/use_kibana_url'; import { AddApmData } from '../../shared/add_data_buttons/buttons'; @@ -44,9 +50,17 @@ const learnMoreLink = { }; const baseImgFolder = '/plugins/apm/assets/service_tab_empty_state'; +const defaultAddDataTelemetryParams: EntityInventoryAddDataParams = { + view: 'add_apm_cta', +}; + +const defaultClickTelemetryParams: EmptyStateClickParams = { + view: 'add_apm_cta', +}; export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStateProps) { const { euiTheme } = useEuiTheme(); + const { services } = useKibana(); const { core } = useApmPluginContext(); const imgFolder = `${baseImgFolder}/${ @@ -57,6 +71,18 @@ export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStatePro `${imgFolder}/${imgName ? imgName : 'service_tab_empty_state_overview.png'}` ); + function handleAddAPMClick() { + services.telemetry.reportEntityInventoryAddData(defaultAddDataTelemetryParams); + } + + function handleTryItClick() { + services.telemetry.reportTryItClick(defaultClickTelemetryParams); + } + + function handleLearnMoreClick() { + services.telemetry.reportLearnMoreClick(defaultClickTelemetryParams); + } + return ( <> @@ -70,7 +96,12 @@ export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStatePro - + {tryItNowButton.label} @@ -86,6 +118,7 @@ export function ServiceTabEmptyState({ id, onDissmiss }: ServiceTabEmptyStatePro { this.analytics.reportEvent(TelemetryEventTypes.ENTITY_INVENTORY_ADD_DATA, params); }; + + public reportTryItClick = (params: EmptyStateClickParams) => { + this.analytics.reportEvent(TelemetryEventTypes.TRY_IT_CLICK, params); + }; + + public reportLearnMoreClick = (params: EmptyStateClickParams) => { + this.analytics.reportEvent(TelemetryEventTypes.LEARN_MORE_CLICK, params); + }; } diff --git a/x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_events.ts b/x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_events.ts index 9cc3cc772a621..2d00970a2b128 100644 --- a/x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_events.ts +++ b/x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_events.ts @@ -78,9 +78,37 @@ const entityInventoryAddDataEventType: TelemetryEvent = { }, }; +const tryItClickEventType: TelemetryEvent = { + eventType: TelemetryEventTypes.TRY_IT_CLICK, + schema: { + view: { + type: 'keyword', + _meta: { + description: + 'Where the action was initiated (empty_state or add_data_button or add_apm_cta)', + }, + }, + }, +}; + +const learnMoreClickEventType: TelemetryEvent = { + eventType: TelemetryEventTypes.LEARN_MORE_CLICK, + schema: { + view: { + type: 'keyword', + _meta: { + description: + 'Where the action was initiated (empty_state or add_data_button or add_apm_cta)', + }, + }, + }, +}; + export const apmTelemetryEventBasedTypes = [ searchQuerySubmittedEventType, entityExperienceStatusEventType, entityInventoryPageStateEventType, entityInventoryAddDataEventType, + tryItClickEventType, + learnMoreClickEventType, ]; diff --git a/x-pack/plugins/observability_solution/apm/public/services/telemetry/types.ts b/x-pack/plugins/observability_solution/apm/public/services/telemetry/types.ts index 173831bbf0d7c..665f3c59d7612 100644 --- a/x-pack/plugins/observability_solution/apm/public/services/telemetry/types.ts +++ b/x-pack/plugins/observability_solution/apm/public/services/telemetry/types.ts @@ -34,17 +34,24 @@ export interface EntityInventoryAddDataParams { journey?: 'add_apm_agent' | 'associate_existing_service_logs' | 'collect_new_service_logs'; } +export interface EmptyStateClickParams { + view: Extract; +} + export type TelemetryEventParams = | SearchQuerySubmittedParams | EntityExperienceStatusParams | EntityInventoryPageStateParams - | EntityInventoryAddDataParams; + | EntityInventoryAddDataParams + | EmptyStateClickParams; export interface ITelemetryClient { reportSearchQuerySubmitted(params: SearchQuerySubmittedParams): void; reportEntityExperienceStatusChange(params: EntityExperienceStatusParams): void; reportEntityInventoryPageState(params: EntityInventoryPageStateParams): void; reportEntityInventoryAddData(params: EntityInventoryAddDataParams): void; + reportTryItClick(params: EmptyStateClickParams): void; + reportLearnMoreClick(params: EmptyStateClickParams): void; } export enum TelemetryEventTypes { @@ -52,6 +59,8 @@ export enum TelemetryEventTypes { ENTITY_EXPERIENCE_STATUS = 'entity_experience_status', ENTITY_INVENTORY_PAGE_STATE = 'entity_inventory_page_state', ENTITY_INVENTORY_ADD_DATA = 'entity_inventory_add_data', + TRY_IT_CLICK = 'try_it_click', + LEARN_MORE_CLICK = 'learn_more_click', } export interface TelemetryEvent { From a0973d600212096ac9e530c179a87c14b7409db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Mon, 16 Sep 2024 08:36:57 -0400 Subject: [PATCH 015/139] Make task manager code use the same logger (#192574) In this PR, I'm making the sub-loggers within task manager use the main logger so we can observe the logs under `log.logger:"plugin.taskManager"`. To preserve separation, I moved the sub-logger name within a tag so we can still filter the logs via `tags:"taskClaimer"`. The wrapped_logger.ts file is copied from `x-pack/plugins/alerting/server/task_runner/lib/task_runner_logger.ts`. --------- Co-authored-by: Elastic Machine --- .../lib/setup_test_servers.ts | 8 -- .../server/lib/wrapped_logger.test.ts | 98 +++++++++++++++++++ .../task_manager/server/lib/wrapped_logger.ts | 74 ++++++++++++++ .../server/metrics/metrics_stream.ts | 3 +- .../server/queries/task_claiming.test.ts | 3 +- .../server/queries/task_claiming.ts | 3 +- .../task_manager/server/routes/metrics.ts | 11 +-- .../task_claimers/strategy_mget.test.ts | 33 ++++--- .../server/task_claimers/strategy_mget.ts | 22 ++--- .../server/task_running/task_runner.ts | 3 +- 10 files changed, 205 insertions(+), 53 deletions(-) create mode 100644 x-pack/plugins/task_manager/server/lib/wrapped_logger.test.ts create mode 100644 x-pack/plugins/task_manager/server/lib/wrapped_logger.ts diff --git a/x-pack/plugins/task_manager/server/integration_tests/lib/setup_test_servers.ts b/x-pack/plugins/task_manager/server/integration_tests/lib/setup_test_servers.ts index 5ec8e724ae819..6abcac64c1d13 100644 --- a/x-pack/plugins/task_manager/server/integration_tests/lib/setup_test_servers.ts +++ b/x-pack/plugins/task_manager/server/integration_tests/lib/setup_test_servers.ts @@ -21,14 +21,6 @@ function createRoot(settings = {}) { name: 'plugins.taskManager', level: 'all', }, - { - name: 'plugins.taskManager.metrics-debugger', - level: 'warn', - }, - { - name: 'plugins.taskManager.metrics-subscribe-debugger', - level: 'warn', - }, ], }, }, diff --git a/x-pack/plugins/task_manager/server/lib/wrapped_logger.test.ts b/x-pack/plugins/task_manager/server/lib/wrapped_logger.test.ts new file mode 100644 index 0000000000000..12857c3fef845 --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/wrapped_logger.test.ts @@ -0,0 +1,98 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { LogLevel, LogRecord } from '@kbn/logging'; +import { createWrappedLogger } from './wrapped_logger'; + +describe('createWrappedLogger', () => { + test('should inject baseline tags into log messages', () => { + const logger: ReturnType = + loggingSystemMock.createLogger(); + const taskRunnerLogger = createWrappedLogger({ logger, tags: ['tag-1', 'tag-2'] }); + + taskRunnerLogger.trace('test trace message', { tags: ['tag-3'] }); + taskRunnerLogger.debug('test debug message', { tags: ['tag-4'] }); + taskRunnerLogger.info('test info message', { tags: ['tag-5'] }); + taskRunnerLogger.warn('test warn message', { tags: ['tag-6'] }); + taskRunnerLogger.error('test error message', { tags: ['tag-7'] }); + taskRunnerLogger.fatal('test fatal message', { tags: ['tag-8'] }); + + expect(logger.trace).toHaveBeenCalledWith('test trace message', { + tags: ['tag-1', 'tag-2', 'tag-3'], + }); + expect(logger.debug).toHaveBeenCalledWith('test debug message', { + tags: ['tag-1', 'tag-2', 'tag-4'], + }); + expect(logger.info).toHaveBeenCalledWith('test info message', { + tags: ['tag-1', 'tag-2', 'tag-5'], + }); + expect(logger.warn).toHaveBeenCalledWith('test warn message', { + tags: ['tag-1', 'tag-2', 'tag-6'], + }); + expect(logger.error).toHaveBeenCalledWith('test error message', { + tags: ['tag-1', 'tag-2', 'tag-7'], + }); + expect(logger.fatal).toHaveBeenCalledWith('test fatal message', { + tags: ['tag-1', 'tag-2', 'tag-8'], + }); + }); + + test('should pass through other meta fields', () => { + const logger: ReturnType = + loggingSystemMock.createLogger(); + const taskRunnerLogger = createWrappedLogger({ logger, tags: ['tag-1', 'tag-2'] }); + + taskRunnerLogger.trace('test trace message', { labels: { foo: 'bar' } }); + taskRunnerLogger.debug('test debug message', { tags: ['tag-4'], host: { cpu: { usage: 3 } } }); + taskRunnerLogger.info('test info message'); + taskRunnerLogger.warn('test warn message', { user: { email: 'abc@124.com' } }); + taskRunnerLogger.error('test error message', { agent: { id: 'agent-1' } }); + taskRunnerLogger.fatal('test fatal message'); + + expect(logger.trace).toHaveBeenCalledWith('test trace message', { + tags: ['tag-1', 'tag-2'], + labels: { foo: 'bar' }, + }); + expect(logger.debug).toHaveBeenCalledWith('test debug message', { + tags: ['tag-1', 'tag-2', 'tag-4'], + host: { cpu: { usage: 3 } }, + }); + expect(logger.info).toHaveBeenCalledWith('test info message', { tags: ['tag-1', 'tag-2'] }); + expect(logger.warn).toHaveBeenCalledWith('test warn message', { + tags: ['tag-1', 'tag-2'], + user: { email: 'abc@124.com' }, + }); + expect(logger.error).toHaveBeenCalledWith('test error message', { + tags: ['tag-1', 'tag-2'], + agent: { id: 'agent-1' }, + }); + expect(logger.fatal).toHaveBeenCalledWith('test fatal message', { tags: ['tag-1', 'tag-2'] }); + }); + + test('should pass through other functions', () => { + const logger: ReturnType = + loggingSystemMock.createLogger(); + const taskRunnerLogger = createWrappedLogger({ logger, tags: ['tag-1', 'tag-2'] }); + + taskRunnerLogger.isLevelEnabled('debug'); + expect(logger.isLevelEnabled).toHaveBeenCalledWith('debug'); + + taskRunnerLogger.get('prefix', 'another'); + expect(logger.get).toHaveBeenCalledWith('prefix', 'another'); + + const logRecord: LogRecord = { + timestamp: new Date(), + level: LogLevel.Info, + context: 'context', + message: 'message', + pid: 1, + }; + taskRunnerLogger.log(logRecord); + expect(logger.log).toHaveBeenCalledWith(logRecord); + }); +}); diff --git a/x-pack/plugins/task_manager/server/lib/wrapped_logger.ts b/x-pack/plugins/task_manager/server/lib/wrapped_logger.ts new file mode 100644 index 0000000000000..a1182924d8bee --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/wrapped_logger.ts @@ -0,0 +1,74 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger, LogMeta } from '@kbn/core/server'; +import { LogLevelId, LogMessageSource, LogRecord } from '@kbn/logging'; + +interface WrappedLoggerOpts { + logger: Logger; + tags: string[]; +} + +export function createWrappedLogger(opts: WrappedLoggerOpts): Logger { + return new WrappedLogger(opts); +} + +class WrappedLogger implements Logger { + private loggerMetaTags: string[] = []; + + constructor(private readonly opts: WrappedLoggerOpts) { + this.loggerMetaTags = opts.tags; + } + + trace(message: LogMessageSource, meta?: Meta) { + this.opts.logger.trace(message, { ...meta, tags: this.combineTags(meta?.tags) }); + } + + debug(message: LogMessageSource, meta?: Meta) { + this.opts.logger.debug(message, { ...meta, tags: this.combineTags(meta?.tags) }); + } + + info(message: LogMessageSource, meta?: Meta) { + this.opts.logger.info(message, { ...meta, tags: this.combineTags(meta?.tags) }); + } + + warn(errorOrMessage: LogMessageSource | Error, meta?: Meta) { + this.opts.logger.warn(errorOrMessage, { ...meta, tags: this.combineTags(meta?.tags) }); + } + + error(errorOrMessage: LogMessageSource | Error, meta?: Meta) { + this.opts.logger.error(errorOrMessage, { ...meta, tags: this.combineTags(meta?.tags) }); + } + + fatal(errorOrMessage: LogMessageSource | Error, meta?: Meta) { + this.opts.logger.fatal(errorOrMessage, { ...meta, tags: this.combineTags(meta?.tags) }); + } + + log(record: LogRecord) { + this.opts.logger.log(record); + } + + isLevelEnabled(level: LogLevelId): boolean { + return this.opts.logger.isLevelEnabled(level); + } + + get(...childContextPaths: string[]): Logger { + return this.opts.logger.get(...childContextPaths); + } + + private combineTags(tags?: string[] | string): string[] { + if (!tags) { + return this.loggerMetaTags; + } + + if (typeof tags === 'string') { + return [...new Set([...this.loggerMetaTags, tags])]; + } + + return [...new Set([...this.loggerMetaTags, ...tags])]; + } +} diff --git a/x-pack/plugins/task_manager/server/metrics/metrics_stream.ts b/x-pack/plugins/task_manager/server/metrics/metrics_stream.ts index 2c56e84104b1d..b9df16b95f2d7 100644 --- a/x-pack/plugins/task_manager/server/metrics/metrics_stream.ts +++ b/x-pack/plugins/task_manager/server/metrics/metrics_stream.ts @@ -12,6 +12,7 @@ import { Logger } from '@kbn/core/server'; import { TaskLifecycleEvent, TaskPollingLifecycle } from '../polling_lifecycle'; import { TaskManagerConfig } from '../config'; import { AggregatedStatProvider } from '../lib/runtime_statistics_aggregator'; +import { createWrappedLogger } from '../lib/wrapped_logger'; import { isTaskManagerStatEvent, isTaskManagerMetricEvent, @@ -52,7 +53,7 @@ export function createMetricsAggregators({ taskManagerMetricsCollector, }: CreateMetricsAggregatorsOpts): AggregatedStatProvider { const aggregators: AggregatedStatProvider[] = []; - const debugLogger = logger.get('metrics-debugger'); + const debugLogger = createWrappedLogger({ logger, tags: ['metrics-debugger'] }); if (taskPollingLifecycle) { aggregators.push( createAggregator({ diff --git a/x-pack/plugins/task_manager/server/queries/task_claiming.test.ts b/x-pack/plugins/task_manager/server/queries/task_claiming.test.ts index c4b9b6dd5836e..437af8e007bdb 100644 --- a/x-pack/plugins/task_manager/server/queries/task_claiming.test.ts +++ b/x-pack/plugins/task_manager/server/queries/task_claiming.test.ts @@ -91,7 +91,8 @@ describe('TaskClaiming', () => { }); expect(taskManagerLogger.warn).toHaveBeenCalledWith( - 'Unknown task claiming strategy "non-default", falling back to update_by_query' + 'Unknown task claiming strategy "non-default", falling back to update_by_query', + { tags: ['taskClaiming'] } ); }); diff --git a/x-pack/plugins/task_manager/server/queries/task_claiming.ts b/x-pack/plugins/task_manager/server/queries/task_claiming.ts index f5ef18452509b..5116c25c38f3f 100644 --- a/x-pack/plugins/task_manager/server/queries/task_claiming.ts +++ b/x-pack/plugins/task_manager/server/queries/task_claiming.ts @@ -28,6 +28,7 @@ import { getTaskClaimer, } from '../task_claimers'; import { TaskPartitioner } from '../lib/task_partitioner'; +import { createWrappedLogger } from '../lib/wrapped_logger'; export type { ClaimOwnershipResult } from '../task_claimers'; export interface TaskClaimingOpts { @@ -107,7 +108,7 @@ export class TaskClaiming { this.maxAttempts = opts.maxAttempts; this.taskStore = opts.taskStore; this.getAvailableCapacity = opts.getAvailableCapacity; - this.logger = opts.logger.get('taskClaiming'); + this.logger = createWrappedLogger({ logger: opts.logger, tags: ['taskClaiming'] }); this.taskClaimingBatchesByType = this.partitionIntoClaimingBatches(this.definitions); this.taskMaxAttempts = Object.fromEntries(this.normalizeMaxAttempts(this.definitions)); this.excludedTaskTypes = opts.excludedTaskTypes; diff --git a/x-pack/plugins/task_manager/server/routes/metrics.ts b/x-pack/plugins/task_manager/server/routes/metrics.ts index 490cb869ba109..808675f25818b 100644 --- a/x-pack/plugins/task_manager/server/routes/metrics.ts +++ b/x-pack/plugins/task_manager/server/routes/metrics.ts @@ -37,15 +37,12 @@ const QuerySchema = schema.object({ }); export function metricsRoute(params: MetricsRouteParams) { - const { router, logger, metrics$, resetMetrics$, taskManagerId } = params; + const { router, metrics$, resetMetrics$, taskManagerId } = params; - const debugLogger = logger.get(`metrics-debugger`); - const additionalDebugLogger = logger.get(`metrics-subscribe-debugger`); let lastMetrics: NodeMetrics | null = null; metrics$.subscribe((metrics) => { lastMetrics = { process_uuid: taskManagerId, timestamp: new Date().toISOString(), ...metrics }; - additionalDebugLogger.debug(() => `subscribed metrics ${JSON.stringify(metrics)}`); }); router.get( @@ -68,12 +65,6 @@ export function metricsRoute(params: MetricsRouteParams) { req: KibanaRequest, unknown>, res: KibanaResponseFactory ): Promise { - debugLogger.debug( - () => - `/api/task_manager/metrics route accessed with reset=${req.query.reset} - metrics ${ - lastMetrics ? JSON.stringify(lastMetrics) : 'not available' - }` - ); if (req.query.reset) { resetMetrics$.next(true); } diff --git a/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.test.ts b/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.test.ts index cd1433d2e4009..3919860d27061 100644 --- a/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.test.ts +++ b/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.test.ts @@ -387,7 +387,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 3; stale: 0; conflicts: 0; missing: 0; capacity reached: 3; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -497,7 +497,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 1; stale: 0; conflicts: 0; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 2;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -604,11 +604,11 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.warn).toHaveBeenCalledWith( 'Error updating task id-2:task to mark as unrecognized during claim: {"type":"document_missing_exception","reason":"[5]: document missing","index_uuid":"aAsFqTI0Tc2W0LCWgPNrOA","shard":"0","index":".kibana_task_manager_8.16.0_001"}', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 1; stale: 0; conflicts: 0; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 1;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -701,11 +701,11 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.warn).toHaveBeenCalledWith( 'Error updating tasks to mark as unrecognized during claim: Error: Oh no', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 1; stale: 0; conflicts: 0; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -855,7 +855,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 2; stale: 0; conflicts: 0; missing: 1; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -948,7 +948,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 2; stale: 0; conflicts: 0; missing: 1; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -1041,7 +1041,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 2; stale: 1; conflicts: 1; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -1140,7 +1140,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 4; stale: 0; conflicts: 0; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -1271,11 +1271,11 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 3; stale: 0; conflicts: 0; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 1; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(taskManagerLogger.error).toHaveBeenCalledWith( 'Error getting full task id-2:task during claim: Oh no', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -1511,11 +1511,11 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 3; stale: 0; conflicts: 0; missing: 0; capacity reached: 0; updateErrors: 1; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(taskManagerLogger.error).toHaveBeenCalledWith( 'Error updating task id-2:task during claim: {"type":"document_missing_exception","reason":"[5]: document missing","index_uuid":"aAsFqTI0Tc2W0LCWgPNrOA","shard":"0","index":".kibana_task_manager_8.16.0_001"}', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(store.msearch.mock.calls[0][0]?.[0]).toMatchObject({ @@ -1644,7 +1644,7 @@ describe('TaskClaiming', () => { expect(taskManagerLogger.debug).toHaveBeenCalledWith( 'task claimer claimed: 3; stale: 0; conflicts: 1; missing: 0; capacity reached: 0; updateErrors: 0; getErrors: 0; removed: 0;', - { tags: ['claimAvailableTasksMget'] } + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(taskManagerLogger.error).not.toHaveBeenCalled(); @@ -2000,7 +2000,8 @@ describe('TaskClaiming', () => { ] = claimedResults; expect(taskManagerLogger.warn).toHaveBeenCalledWith( - 'Background task node "test" has no assigned partitions, claiming against all partitions' + 'Background task node "test" has no assigned partitions, claiming against all partitions', + { tags: ['taskClaiming', 'claimAvailableTasksMget'] } ); expect(query).toMatchInlineSnapshot(` Object { diff --git a/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.ts b/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.ts index 1fd35d408a3ec..432d7f183ce39 100644 --- a/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.ts +++ b/x-pack/plugins/task_manager/server/task_claimers/strategy_mget.ts @@ -15,6 +15,7 @@ import apm, { Logger } from 'elastic-apm-node'; import { Subject, Observable } from 'rxjs'; +import { createWrappedLogger } from '../lib/wrapped_logger'; import { TaskTypeDictionary } from '../task_type_dictionary'; import { @@ -105,9 +106,7 @@ async function claimAvailableTasksApm(opts: TaskClaimerOpts): Promise { const { getCapacity, claimOwnershipUntil, batches, events$, taskStore, taskPartitioner } = opts; const { definitions, unusedTypes, excludedTaskTypes, taskMaxAttempts } = opts; - const { logger } = opts; - const loggerTag = claimAvailableTasksMget.name; - const logMeta = { tags: [loggerTag] }; + const logger = createWrappedLogger({ logger: opts.logger, tags: [claimAvailableTasksMget.name] }); const initialCapacity = getCapacity(); const stopTaskTimer = startTaskTimer(); @@ -227,10 +226,7 @@ async function claimAvailableTasks(opts: TaskClaimerOpts): Promise> { const { task } = this.instance; - const debugLogger = this.logger.get(`metrics-debugger`); + const debugLogger = createWrappedLogger({ logger: this.logger, tags: [`metrics-debugger`] }); const taskHasExpired = this.isExpired; From 0a385f30fd9b9ab509b3be091d5e1add789cadeb Mon Sep 17 00:00:00 2001 From: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Date: Mon, 16 Sep 2024 14:18:22 +0100 Subject: [PATCH 016/139] [DOCS][Playground] Mention local model compatibility (#192911) Note about openai sdk compatible local models + links to examples --- docs/playground/index.asciidoc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/docs/playground/index.asciidoc b/docs/playground/index.asciidoc index f475c3e2747a2..efb9b6261d8dd 100644 --- a/docs/playground/index.asciidoc +++ b/docs/playground/index.asciidoc @@ -89,6 +89,17 @@ a| |=== +[[playground-local-llms]] +[TIP] +==== +You can also use locally hosted LLMs that are compatible with the OpenAI SDK. +Once you've set up your LLM, you can connect to it using the OpenAI connector. +Refer to the following for examples: + +* {security-guide}/connect-to-byo-llm.html[Using LM Studio] +* https://www.elastic.co/search-labs/blog/localai-for-text-embeddings[LocalAI with `docker-compose`] +==== + [float] [[playground-getting-started]] == Getting started @@ -101,13 +112,15 @@ image::get-started.png[width=600] === Connect to LLM provider To get started with {x}, you need to create a <> for your LLM provider. -Follow these steps on the {x} landing page: +You can also connect to <> which are compatible with the OpenAI API, by using the OpenAI connector. + +To connect to an LLM provider, follow these steps on the {x} landing page: . Under *Connect to an LLM*, click *Create connector*. . Select your *LLM provider*. . *Name* your connector. . Select a *URL endpoint* (or use the default). -. Enter *access credentials* for your LLM provider. +. Enter *access credentials* for your LLM provider. (If you're running a locally hosted LLM using the OpenAI connector, you must input a value in the API key form, but the specific value doesn't matter.) [TIP] ==== From f4587149987aa21ec9345e887bc7121d75792ea5 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Mon, 16 Sep 2024 15:18:49 +0200 Subject: [PATCH 017/139] [ci] skip tests that fail on chrome 128+ (#192830) ## Summary Currently `google-chrome-stable` is pinned to `v127.x.x` as with `v128.x.x` we get a few FTR breakages (some of them on visual inaccuracies, some other). We'd like to unpin chrome, and move on to 128, and start fixing these test failures. So we're skipping the failures temporarily, bumping chrome to 128, then allow for unskipping and fixing these. --- test/functional/apps/dashboard/group5/embed_mode.ts | 6 ++++-- test/functional/apps/kibana_overview/_analytics.ts | 2 +- x-pack/test/functional/apps/lens/group6/workspace_size.ts | 3 ++- .../apps/maps/group1/documents_source/search_hits.js | 3 ++- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/test/functional/apps/dashboard/group5/embed_mode.ts b/test/functional/apps/dashboard/group5/embed_mode.ts index 965f448b38a3f..5bba11d3b574a 100644 --- a/test/functional/apps/dashboard/group5/embed_mode.ts +++ b/test/functional/apps/dashboard/group5/embed_mode.ts @@ -57,7 +57,8 @@ export default function ({ await browser.setWindowSize(1300, 900); }); - describe('default URL params', () => { + // Fails in with chrome 128+ https://github.com/elastic/kibana/issues/163207 + describe.skip('default URL params', () => { it('hides the chrome', async () => { const globalNavShown = await globalNav.exists(); expect(globalNavShown).to.be(true); @@ -91,7 +92,8 @@ export default function ({ }); }); - describe('non-default URL params', () => { + // Fails in with chrome 128+ https://github.com/elastic/kibana/issues/163207 + describe.skip('non-default URL params', () => { it('shows or hides elements based on URL params', async () => { const currentUrl = await browser.getCurrentUrl(); const newUrl = [currentUrl].concat(urlParamExtensions).join('&'); diff --git a/test/functional/apps/kibana_overview/_analytics.ts b/test/functional/apps/kibana_overview/_analytics.ts index b8c7e9ac47f8c..bd504e4d7a829 100644 --- a/test/functional/apps/kibana_overview/_analytics.ts +++ b/test/functional/apps/kibana_overview/_analytics.ts @@ -17,7 +17,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'header']); - // Failing: See https://github.com/elastic/kibana/issues/192509 + // Fails in chrome 128+: See https://github.com/elastic/kibana/issues/192509 describe.skip('overview page - Analytics apps', function describeIndexTests() { before(async () => { await esArchiver.load('test/functional/fixtures/es_archiver/logstash_functional'); diff --git a/x-pack/test/functional/apps/lens/group6/workspace_size.ts b/x-pack/test/functional/apps/lens/group6/workspace_size.ts index cda1631873033..9c5e7fec773f0 100644 --- a/x-pack/test/functional/apps/lens/group6/workspace_size.ts +++ b/x-pack/test/functional/apps/lens/group6/workspace_size.ts @@ -268,7 +268,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await assertWorkspaceDimensions('600px', '375px'); }); - it('gauge size (absolute pixels) - major arc', async () => { + // Fails in chrome 128+ + it.skip('gauge size (absolute pixels) - major arc', async () => { await lens.openVisualOptions(); await lens.setGaugeShape('Major arc'); await assertWorkspaceDimensions('600px', '430px'); diff --git a/x-pack/test/functional/apps/maps/group1/documents_source/search_hits.js b/x-pack/test/functional/apps/maps/group1/documents_source/search_hits.js index 488f9e3ab9e5a..f9e856d0d0ee4 100644 --- a/x-pack/test/functional/apps/maps/group1/documents_source/search_hits.js +++ b/x-pack/test/functional/apps/maps/group1/documents_source/search_hits.js @@ -108,7 +108,8 @@ export default function ({ getPageObjects, getService }) { expect(hits).to.equal('2'); }); - it('should apply layer query to fit to bounds', async () => { + // Fails in chrome 128+: https://github.com/elastic/kibana/issues/175378 + it.skip('should apply layer query to fit to bounds', async () => { // Set view to other side of world so no matching results await maps.setView(-15, -100, 6); await maps.clickFitToBounds('logstash'); From 7a0fe2e83683cf38c537694daa88a3a75bfe3e57 Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Mon, 16 Sep 2024 09:22:44 -0400 Subject: [PATCH 018/139] [Response Ops][Alerting] Creating global service for fetching and caching rules settings (#192404) Resolves https://github.com/elastic/kibana/issues/184321 and https://github.com/elastic/kibana/issues/149884 ## Summary Created a `RulesSettingsService` that caches flapping and query delay settings per space for 1 minute so rules are not accessing the SO index with every execution. Also moved all classes related to the rules settings into the `rules_settings` folder so some of these changes are just renaming changes. ## To Verify 1. Add some logging to `x-pack/plugins/alerting/server/rules_settings/rules_settings_service.ts` to indicate when settings are being fetched and when they're returning from the cache. 2. Create and run some rules in different spaces to see that flapping and query delay settings are being returned from the cache when the cache has not expired. --------- Co-authored-by: Elastic Machine --- x-pack/plugins/alerting/server/config.test.ts | 3 + x-pack/plugins/alerting/server/config.ts | 4 + x-pack/plugins/alerting/server/plugin.ts | 48 ++-- .../server/routes/_mock_handler_arguments.ts | 5 +- .../routes/get_flapping_settings.test.ts | 5 +- .../apis/get/get_query_delay_settings.test.ts | 2 +- .../update_query_delay_settings.test.ts | 2 +- .../routes/update_flapping_settings.test.ts | 5 +- .../rules_settings_flapping_client.test.ts | 0 .../rules_settings_flapping_client.ts | 0 .../index.ts | 3 + .../rules_settings_query_delay_client.test.ts | 0 .../rules_settings_query_delay_client.ts | 0 .../rules_settings_client.mock.ts | 2 +- .../rules_settings_client.test.ts | 0 .../rules_settings_client.ts | 0 .../rules_settings_client_factory.test.ts | 2 +- .../rules_settings_client_factory.ts | 2 +- .../rules_settings_feature.test.ts | 0 .../rules_settings_feature.ts | 2 +- .../rules_settings_service.mock.ts | 23 ++ .../rules_settings_service.test.ts | 241 ++++++++++++++++++ .../rules_settings/rules_settings_service.ts | 112 ++++++++ .../schemas/flapping_schema.ts | 0 .../schemas/index.ts | 0 .../schemas/query_delay_schema.ts | 0 .../task_runner/ad_hoc_task_runner.test.ts | 11 +- .../server/task_runner/task_runner.test.ts | 56 ++-- .../server/task_runner/task_runner.ts | 11 +- .../task_runner_alerts_client.test.ts | 56 ++-- .../task_runner/task_runner_cancel.test.ts | 58 ++--- .../task_runner/task_runner_factory.test.ts | 45 ++-- .../alerting/server/task_runner/types.ts | 6 +- .../alerting/server/test_utils/index.ts | 1 + x-pack/plugins/alerting/server/types.ts | 2 +- .../alerting_api_integration/common/config.ts | 1 + .../group4/alerts_as_data/alerts_as_data.ts | 3 + .../alerts_as_data/alerts_as_data_flapping.ts | 9 + 38 files changed, 563 insertions(+), 157 deletions(-) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/flapping/rules_settings_flapping_client.test.ts (100%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/flapping/rules_settings_flapping_client.ts (100%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/index.ts (75%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/query_delay/rules_settings_query_delay_client.test.ts (100%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/query_delay/rules_settings_query_delay_client.ts (100%) rename x-pack/plugins/alerting/server/{ => rules_settings}/rules_settings_client.mock.ts (98%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/rules_settings_client.test.ts (100%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/rules_settings_client.ts (100%) rename x-pack/plugins/alerting/server/{ => rules_settings}/rules_settings_client_factory.test.ts (98%) rename x-pack/plugins/alerting/server/{ => rules_settings}/rules_settings_client_factory.ts (97%) rename x-pack/plugins/alerting/server/{ => rules_settings}/rules_settings_feature.test.ts (100%) rename x-pack/plugins/alerting/server/{ => rules_settings}/rules_settings_feature.ts (99%) create mode 100644 x-pack/plugins/alerting/server/rules_settings/rules_settings_service.mock.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings/rules_settings_service.test.ts create mode 100644 x-pack/plugins/alerting/server/rules_settings/rules_settings_service.ts rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/schemas/flapping_schema.ts (100%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/schemas/index.ts (100%) rename x-pack/plugins/alerting/server/{rules_settings_client => rules_settings}/schemas/query_delay_schema.ts (100%) diff --git a/x-pack/plugins/alerting/server/config.test.ts b/x-pack/plugins/alerting/server/config.test.ts index 9e2d2d089ac62..fe5657bc7f0ea 100644 --- a/x-pack/plugins/alerting/server/config.test.ts +++ b/x-pack/plugins/alerting/server/config.test.ts @@ -37,6 +37,9 @@ describe('config validation', () => { }, }, }, + "rulesSettings": Object { + "cacheInterval": 60000, + }, } `); }); diff --git a/x-pack/plugins/alerting/server/config.ts b/x-pack/plugins/alerting/server/config.ts index ccacc6440b03a..cbe1328bdef5f 100644 --- a/x-pack/plugins/alerting/server/config.ts +++ b/x-pack/plugins/alerting/server/config.ts @@ -7,6 +7,7 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { validateDurationSchema, parseDuration } from './lib'; +import { DEFAULT_CACHE_INTERVAL_MS } from './rules_settings'; export const DEFAULT_MAX_ALERTS = 1000; const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000; @@ -74,6 +75,9 @@ export const configSchema = schema.object({ enableFrameworkAlerts: schema.boolean({ defaultValue: true }), cancelAlertsOnRuleTimeout: schema.boolean({ defaultValue: true }), rules: rulesSchema, + rulesSettings: schema.object({ + cacheInterval: schema.number({ defaultValue: DEFAULT_CACHE_INTERVAL_MS }), + }), }); export type AlertingConfig = TypeOf; diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 447dab2b94715..a7595eb4c5bac 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -66,7 +66,11 @@ import { ServerlessPluginSetup } from '@kbn/serverless/server'; import { RuleTypeRegistry } from './rule_type_registry'; import { TaskRunnerFactory } from './task_runner'; import { RulesClientFactory } from './rules_client_factory'; -import { RulesSettingsClientFactory } from './rules_settings_client_factory'; +import { + RulesSettingsClientFactory, + RulesSettingsService, + getRulesSettingsFeature, +} from './rules_settings'; import { MaintenanceWindowClientFactory } from './maintenance_window_client_factory'; import { ILicenseState, LicenseState } from './lib/license_state'; import { AlertingRequestHandlerContext, ALERTING_FEATURE_ID, RuleAlertData } from './types'; @@ -106,7 +110,6 @@ import { type InitializationPromise, errorResult, } from './alerts_service'; -import { getRulesSettingsFeature } from './rules_settings_feature'; import { maintenanceWindowFeature } from './maintenance_window_feature'; import { ConnectorAdapterRegistry } from './connector_adapters/connector_adapter_registry'; import { ConnectorAdapter, ConnectorAdapterParams } from './connector_adapters/types'; @@ -588,33 +591,38 @@ export class AlertingPlugin { }; taskRunnerFactory.initialize({ - logger, + actionsConfigMap: getActionsConfigMap(this.config.rules.run.actions), + actionsPlugin: plugins.actions, + alertsService: this.alertsService, + backfillClient: this.backfillClient!, + basePathService: core.http.basePath, + cancelAlertsOnRuleTimeout: this.config.cancelAlertsOnRuleTimeout, + connectorAdapterRegistry: this.connectorAdapterRegistry, data: plugins.data, - share: plugins.share, dataViews: plugins.dataViews, - savedObjects: core.savedObjects, - uiSettings: core.uiSettings, elasticsearch: core.elasticsearch, - getRulesClientWithRequest, - spaceIdToNamespace, - actionsPlugin: plugins.actions, encryptedSavedObjectsClient, - basePathService: core.http.basePath, eventLogger: this.eventLogger!, executionContext: core.executionContext, - ruleTypeRegistry: this.ruleTypeRegistry!, - alertsService: this.alertsService, + getMaintenanceWindowClientWithRequest, + getRulesClientWithRequest, kibanaBaseUrl: this.kibanaBaseUrl, - supportsEphemeralTasks: plugins.taskManager.supportsEphemeralTasks(), - maxEphemeralActionsPerRule: this.config.maxEphemeralActionsPerAlert, - cancelAlertsOnRuleTimeout: this.config.cancelAlertsOnRuleTimeout, + logger, maxAlerts: this.config.rules.run.alerts.max, - actionsConfigMap: getActionsConfigMap(this.config.rules.run.actions), + maxEphemeralActionsPerRule: this.config.maxEphemeralActionsPerAlert, + ruleTypeRegistry: this.ruleTypeRegistry!, + rulesSettingsService: new RulesSettingsService({ + cacheInterval: this.config.rulesSettings.cacheInterval, + getRulesSettingsClientWithRequest, + isServerless: !!plugins.serverless, + logger, + }), + savedObjects: core.savedObjects, + share: plugins.share, + spaceIdToNamespace, + supportsEphemeralTasks: plugins.taskManager.supportsEphemeralTasks(), + uiSettings: core.uiSettings, usageCounter: this.usageCounter, - getRulesSettingsClientWithRequest, - getMaintenanceWindowClientWithRequest, - backfillClient: this.backfillClient!, - connectorAdapterRegistry: this.connectorAdapterRegistry, }); this.eventLogService!.registerSavedObjectProvider(RULE_SAVED_OBJECT_TYPE, (request) => { diff --git a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts index cab10e242cdad..b2f25d349ec7f 100644 --- a/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/alerting/server/routes/_mock_handler_arguments.ts @@ -12,7 +12,10 @@ import { httpServerMock } from '@kbn/core/server/mocks'; import { actionsClientMock } from '@kbn/actions-plugin/server/mocks'; import type { ActionsClientMock } from '@kbn/actions-plugin/server/mocks'; import { rulesClientMock, RulesClientMock } from '../rules_client.mock'; -import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { + rulesSettingsClientMock, + RulesSettingsClientMock, +} from '../rules_settings/rules_settings_client.mock'; import { maintenanceWindowClientMock, MaintenanceWindowClientMock, diff --git a/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts b/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts index 80354da80b784..b1353a6e328db 100644 --- a/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts +++ b/x-pack/plugins/alerting/server/routes/get_flapping_settings.test.ts @@ -8,7 +8,10 @@ import { httpServiceMock } from '@kbn/core/server/mocks'; import { licenseStateMock } from '../lib/license_state.mock'; import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { + rulesSettingsClientMock, + RulesSettingsClientMock, +} from '../rules_settings/rules_settings_client.mock'; import { getFlappingSettingsRoute } from './get_flapping_settings'; let rulesSettingsClient: RulesSettingsClientMock; diff --git a/x-pack/plugins/alerting/server/routes/rules_settings/apis/get/get_query_delay_settings.test.ts b/x-pack/plugins/alerting/server/routes/rules_settings/apis/get/get_query_delay_settings.test.ts index 4102aa80b29af..e025fcf84a25b 100644 --- a/x-pack/plugins/alerting/server/routes/rules_settings/apis/get/get_query_delay_settings.test.ts +++ b/x-pack/plugins/alerting/server/routes/rules_settings/apis/get/get_query_delay_settings.test.ts @@ -11,7 +11,7 @@ import { mockHandlerArguments } from '../../../_mock_handler_arguments'; import { rulesSettingsClientMock, RulesSettingsClientMock, -} from '../../../../rules_settings_client.mock'; +} from '../../../../rules_settings/rules_settings_client.mock'; import { getQueryDelaySettingsRoute } from './get_query_delay_settings'; let rulesSettingsClient: RulesSettingsClientMock; diff --git a/x-pack/plugins/alerting/server/routes/rules_settings/apis/update/update_query_delay_settings.test.ts b/x-pack/plugins/alerting/server/routes/rules_settings/apis/update/update_query_delay_settings.test.ts index 8a506809131ab..34d3c8dfefe08 100644 --- a/x-pack/plugins/alerting/server/routes/rules_settings/apis/update/update_query_delay_settings.test.ts +++ b/x-pack/plugins/alerting/server/routes/rules_settings/apis/update/update_query_delay_settings.test.ts @@ -11,7 +11,7 @@ import { mockHandlerArguments } from '../../../_mock_handler_arguments'; import { rulesSettingsClientMock, RulesSettingsClientMock, -} from '../../../../rules_settings_client.mock'; +} from '../../../../rules_settings/rules_settings_client.mock'; import { updateQueryDelaySettingsRoute } from './update_query_delay_settings'; let rulesSettingsClient: RulesSettingsClientMock; diff --git a/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts b/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts index 84fb238b8509b..81ea7dd087b16 100644 --- a/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts +++ b/x-pack/plugins/alerting/server/routes/update_flapping_settings.test.ts @@ -8,7 +8,10 @@ import { httpServiceMock } from '@kbn/core/server/mocks'; import { licenseStateMock } from '../lib/license_state.mock'; import { mockHandlerArguments } from './_mock_handler_arguments'; -import { rulesSettingsClientMock, RulesSettingsClientMock } from '../rules_settings_client.mock'; +import { + rulesSettingsClientMock, + RulesSettingsClientMock, +} from '../rules_settings/rules_settings_client.mock'; import { updateFlappingSettingsRoute } from './update_flapping_settings'; let rulesSettingsClient: RulesSettingsClientMock; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts b/x-pack/plugins/alerting/server/rules_settings/flapping/rules_settings_flapping_client.test.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.test.ts rename to x-pack/plugins/alerting/server/rules_settings/flapping/rules_settings_flapping_client.test.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts b/x-pack/plugins/alerting/server/rules_settings/flapping/rules_settings_flapping_client.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/flapping/rules_settings_flapping_client.ts rename to x-pack/plugins/alerting/server/rules_settings/flapping/rules_settings_flapping_client.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client/index.ts b/x-pack/plugins/alerting/server/rules_settings/index.ts similarity index 75% rename from x-pack/plugins/alerting/server/rules_settings_client/index.ts rename to x-pack/plugins/alerting/server/rules_settings/index.ts index fcbf30b0bcb6c..d1b0525bd3754 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client/index.ts +++ b/x-pack/plugins/alerting/server/rules_settings/index.ts @@ -8,3 +8,6 @@ export * from './rules_settings_client'; export * from './flapping/rules_settings_flapping_client'; export * from './query_delay/rules_settings_query_delay_client'; +export * from './rules_settings_client_factory'; +export * from './rules_settings_feature'; +export * from './rules_settings_service'; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.test.ts b/x-pack/plugins/alerting/server/rules_settings/query_delay/rules_settings_query_delay_client.test.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.test.ts rename to x-pack/plugins/alerting/server/rules_settings/query_delay/rules_settings_query_delay_client.test.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.ts b/x-pack/plugins/alerting/server/rules_settings/query_delay/rules_settings_query_delay_client.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/query_delay/rules_settings_query_delay_client.ts rename to x-pack/plugins/alerting/server/rules_settings/query_delay/rules_settings_query_delay_client.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client.mock.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client.mock.ts similarity index 98% rename from x-pack/plugins/alerting/server/rules_settings_client.mock.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_client.mock.ts index 5e3479b10e0ab..cc7601a56fcd1 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client.mock.ts +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client.mock.ts @@ -11,7 +11,7 @@ import { RulesSettingsQueryDelayClientApi, DEFAULT_FLAPPING_SETTINGS, DEFAULT_QUERY_DELAY_SETTINGS, -} from './types'; +} from '../types'; export type RulesSettingsClientMock = jest.Mocked; export type RulesSettingsFlappingClientMock = jest.Mocked; diff --git a/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client.test.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.test.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_client.test.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/rules_settings_client.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_client.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client_factory.test.ts similarity index 98% rename from x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_client_factory.test.ts index f107fbac3a541..8942fb31acd32 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client_factory.test.ts +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client_factory.test.ts @@ -18,7 +18,7 @@ import { } from '@kbn/core/server/mocks'; import { AuthenticatedUser } from '@kbn/security-plugin/common'; import { SECURITY_EXTENSION_ID } from '@kbn/core-saved-objects-server'; -import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../common'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; jest.mock('./rules_settings_client'); diff --git a/x-pack/plugins/alerting/server/rules_settings_client_factory.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client_factory.ts similarity index 97% rename from x-pack/plugins/alerting/server/rules_settings_client_factory.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_client_factory.ts index 707c38b508c1a..a55529f995783 100644 --- a/x-pack/plugins/alerting/server/rules_settings_client_factory.ts +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_client_factory.ts @@ -13,7 +13,7 @@ import { SecurityServiceStart, } from '@kbn/core/server'; import { RulesSettingsClient } from './rules_settings_client'; -import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../common'; +import { RULES_SETTINGS_SAVED_OBJECT_TYPE } from '../../common'; export interface RulesSettingsClientFactoryOpts { logger: Logger; diff --git a/x-pack/plugins/alerting/server/rules_settings_feature.test.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_feature.test.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_feature.test.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_feature.test.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_feature.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_feature.ts similarity index 99% rename from x-pack/plugins/alerting/server/rules_settings_feature.ts rename to x-pack/plugins/alerting/server/rules_settings/rules_settings_feature.ts index 5087ae3eaf03a..57a4e333c0b56 100644 --- a/x-pack/plugins/alerting/server/rules_settings_feature.ts +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_feature.ts @@ -17,7 +17,7 @@ import { RULES_SETTINGS_SAVED_OBJECT_TYPE, ALL_QUERY_DELAY_SETTINGS_SUB_FEATURE_ID, READ_QUERY_DELAY_SETTINGS_SUB_FEATURE_ID, -} from '../common'; +} from '../../common'; export function getRulesSettingsFeature(isServerless: boolean): KibanaFeatureConfig { const settings = { diff --git a/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.mock.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.mock.ts new file mode 100644 index 0000000000000..d4fea3bcc0da0 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.mock.ts @@ -0,0 +1,23 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DEFAULT_FLAPPING_SETTINGS, DEFAULT_QUERY_DELAY_SETTINGS } from '../types'; + +const createRulesSettingsServiceMock = () => { + return jest.fn().mockImplementation(() => { + return { + getSettings: jest.fn().mockReturnValue({ + queryDelaySettings: DEFAULT_QUERY_DELAY_SETTINGS, + flappingSettings: DEFAULT_FLAPPING_SETTINGS, + }), + }; + }); +}; + +export const rulesSettingsServiceMock = { + create: createRulesSettingsServiceMock(), +}; diff --git a/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.test.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.test.ts new file mode 100644 index 0000000000000..7a42b2d9b92cc --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.test.ts @@ -0,0 +1,241 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import sinon from 'sinon'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { KibanaRequest } from '@kbn/core/server'; +import { rulesSettingsClientMock } from './rules_settings_client.mock'; +import { RulesSettingsService } from './rules_settings_service'; +import { DEFAULT_QUERY_DELAY_SETTINGS, DEFAULT_SERVERLESS_QUERY_DELAY_SETTINGS } from '../types'; + +const fakeRequest = { + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + getSavedObjectsClient: jest.fn(), +} as unknown as KibanaRequest; +let fakeTimer: sinon.SinonFakeTimers; + +const logger = loggingSystemMock.create().get(); + +describe('RulesSettingsService', () => { + beforeAll(() => { + fakeTimer = sinon.useFakeTimers(new Date('2023-02-27T08:15:00.000Z')); + }); + beforeEach(() => { + fakeTimer.reset(); + }); + afterAll(() => fakeTimer.restore()); + + for (const isServerless of [false, true]) { + const label = isServerless ? 'serverless' : 'non-serverless'; + describe(`getSettings in ${label}`, () => { + afterEach(() => { + jest.resetAllMocks(); + jest.clearAllMocks(); + }); + + test('should fetch settings if none in cache', async () => { + const rulesSettingsClient = rulesSettingsClientMock.create(); + const rulesSettingsService = new RulesSettingsService({ + isServerless, + logger, + getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClient), + }); + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('default')).toBeUndefined(); + + const settings = await rulesSettingsService.getSettings(fakeRequest, 'default'); + expect(rulesSettingsClient.queryDelay().get).toHaveBeenCalledTimes(1); + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(1); + + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('default')).toEqual({ + lastUpdated: 1677485700000, + queryDelaySettings: { delay: 0 }, + flappingSettings: { enabled: true, lookBackWindow: 20, statusChangeThreshold: 4 }, + }); + + expect(settings.queryDelaySettings).toEqual({ delay: 0 }); + expect(settings.flappingSettings).toEqual(getFlappingSettings(20, 4)); + }); + + test('should return defaults if fetch settings errors and nothing in cache', async () => { + const rulesSettingsClient = rulesSettingsClientMock.create(); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockImplementationOnce(() => { + throw new Error('no!'); + }); + + const rulesSettingsService = new RulesSettingsService({ + isServerless, + logger, + getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClient), + }); + + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('default')).toBeUndefined(); + + const settings = await rulesSettingsService.getSettings(fakeRequest, 'default'); + expect(rulesSettingsClient.queryDelay().get).toHaveBeenCalledTimes(1); + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(0); + + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('default')).toBeUndefined(); + + expect(settings.queryDelaySettings).toEqual( + isServerless ? DEFAULT_SERVERLESS_QUERY_DELAY_SETTINGS : DEFAULT_QUERY_DELAY_SETTINGS + ); + expect(settings.flappingSettings).toEqual(getFlappingSettings(20, 4)); + + expect(logger.debug).toHaveBeenCalledWith( + `Failed to fetch initial rules settings, using default settings: no!` + ); + }); + + test('should fetch settings per space', async () => { + const rulesSettingsClient = rulesSettingsClientMock.create(); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockResolvedValueOnce({ delay: 13 }); + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValueOnce( + getFlappingSettings(45, 2) + ); + const rulesSettingsService = new RulesSettingsService({ + isServerless, + logger, + getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClient), + }); + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('default')).toBeUndefined(); + + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('new-space')).toBeUndefined(); + + const settingsDefault = await rulesSettingsService.getSettings(fakeRequest, 'default'); + const settingsNewSpace = await rulesSettingsService.getSettings(fakeRequest, 'new-space'); + expect(rulesSettingsClient.queryDelay().get).toHaveBeenCalledTimes(2); + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(2); + + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('default')).toEqual({ + lastUpdated: 1677485700000, + queryDelaySettings: { delay: 13 }, + flappingSettings: getFlappingSettings(45, 2), + }); + + // @ts-ignore - accessing private variable + expect(rulesSettingsService.settings.get('new-space')).toEqual({ + lastUpdated: 1677485700000, + queryDelaySettings: { delay: 0 }, + flappingSettings: getFlappingSettings(20, 4), + }); + + expect(settingsNewSpace.queryDelaySettings).toEqual({ delay: 0 }); + expect(settingsNewSpace.flappingSettings).toEqual(getFlappingSettings(20, 4)); + + expect(settingsDefault.queryDelaySettings).toEqual({ delay: 13 }); + expect(settingsDefault.flappingSettings).toEqual(getFlappingSettings(45, 2)); + }); + + test('should use cached settings if cache has not expired', async () => { + const rulesSettingsClient = rulesSettingsClientMock.create(); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockResolvedValueOnce({ delay: 5 }); + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValueOnce( + getFlappingSettings(30, 3) + ); + const rulesSettingsService = new RulesSettingsService({ + isServerless, + logger, + getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClient), + }); + + const settings1 = await rulesSettingsService.getSettings(fakeRequest, 'default'); + fakeTimer.tick(30000); + const settings2 = await rulesSettingsService.getSettings(fakeRequest, 'default'); + + expect(rulesSettingsClient.queryDelay().get).toHaveBeenCalledTimes(1); + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(1); + + expect(settings1.queryDelaySettings).toEqual({ delay: 5 }); + expect(settings1.flappingSettings).toEqual(getFlappingSettings(30, 3)); + expect(settings1).toEqual(settings2); + }); + + test('should refetch settings if cache has expired', async () => { + const rulesSettingsClient = rulesSettingsClientMock.create(); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockResolvedValueOnce({ delay: 5 }); + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValueOnce( + getFlappingSettings(30, 3) + ); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockResolvedValueOnce({ delay: 21 }); + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValueOnce( + getFlappingSettings(11, 44) + ); + const rulesSettingsService = new RulesSettingsService({ + isServerless, + logger, + getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClient), + }); + + const settings1 = await rulesSettingsService.getSettings(fakeRequest, 'default'); + fakeTimer.tick(61000); + const settings2 = await rulesSettingsService.getSettings(fakeRequest, 'default'); + + expect(rulesSettingsClient.queryDelay().get).toHaveBeenCalledTimes(2); + expect(rulesSettingsClient.flapping().get).toHaveBeenCalledTimes(2); + + expect(settings1.queryDelaySettings).toEqual({ delay: 5 }); + expect(settings1.flappingSettings).toEqual(getFlappingSettings(30, 3)); + expect(settings2.queryDelaySettings).toEqual({ delay: 21 }); + expect(settings2.flappingSettings).toEqual(getFlappingSettings(11, 44)); + }); + + test('should return cached settings if refetching throws an error', async () => { + const rulesSettingsClient = rulesSettingsClientMock.create(); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockResolvedValueOnce({ delay: 13 }); + (rulesSettingsClient.flapping().get as jest.Mock).mockResolvedValueOnce( + getFlappingSettings(11, 44) + ); + (rulesSettingsClient.queryDelay().get as jest.Mock).mockImplementationOnce(() => { + throw new Error('no!'); + }); + const rulesSettingsService = new RulesSettingsService({ + isServerless, + logger, + getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClient), + }); + + const settings1 = await rulesSettingsService.getSettings(fakeRequest, 'default'); + fakeTimer.tick(61000); + const settings2 = await rulesSettingsService.getSettings(fakeRequest, 'default'); + + expect(rulesSettingsClient.queryDelay().get).toHaveBeenCalledTimes(2); + + expect(settings1.queryDelaySettings).toEqual({ delay: 13 }); + expect(settings1.flappingSettings).toEqual(getFlappingSettings(11, 44)); + expect(settings1).toEqual(settings2); + + expect(logger.debug).toHaveBeenCalledWith( + `Failed to fetch rules settings after cache expiration, using cached settings: no!` + ); + }); + }); + } +}); + +const getFlappingSettings = (lookback: number, threshold: number) => ({ + enabled: true, + lookBackWindow: lookback, + statusChangeThreshold: threshold, +}); diff --git a/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.ts b/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.ts new file mode 100644 index 0000000000000..2dd264e5d9a69 --- /dev/null +++ b/x-pack/plugins/alerting/server/rules_settings/rules_settings_service.ts @@ -0,0 +1,112 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { KibanaRequest, Logger } from '@kbn/core/server'; +import { + DEFAULT_FLAPPING_SETTINGS, + DEFAULT_QUERY_DELAY_SETTINGS, + DEFAULT_SERVERLESS_QUERY_DELAY_SETTINGS, + RulesSettingsClientApi, + RulesSettingsFlappingProperties, + RulesSettingsQueryDelayProperties, +} from '../types'; +import { withAlertingSpan } from '../task_runner/lib'; + +export const DEFAULT_CACHE_INTERVAL_MS = 60000; // 1 minute cache + +export interface RulesSettingsServiceConstructorOptions { + readonly isServerless: boolean; + cacheInterval?: number; + logger: Logger; + getRulesSettingsClientWithRequest(request: KibanaRequest): RulesSettingsClientApi; +} + +interface Settings { + queryDelaySettings: RulesSettingsQueryDelayProperties; + flappingSettings: RulesSettingsFlappingProperties; +} + +type LastUpdatedSettings = Settings & { lastUpdated: number }; + +export class RulesSettingsService { + private cacheIntervalMs = DEFAULT_CACHE_INTERVAL_MS; + private defaultQueryDelaySettings: RulesSettingsQueryDelayProperties; + private settings: Map = new Map(); + + constructor(private readonly options: RulesSettingsServiceConstructorOptions) { + if (options.cacheInterval) { + this.cacheIntervalMs = options.cacheInterval; + } + this.defaultQueryDelaySettings = options.isServerless + ? DEFAULT_SERVERLESS_QUERY_DELAY_SETTINGS + : DEFAULT_QUERY_DELAY_SETTINGS; + } + + public async getSettings(request: KibanaRequest, spaceId: string): Promise { + const now = Date.now(); + if (this.settings.has(spaceId)) { + const settingsFromLastUpdate = this.settings.get(spaceId)!; + const lastUpdated = new Date(settingsFromLastUpdate.lastUpdated).getTime(); + const currentFlappingSettings = settingsFromLastUpdate.flappingSettings; + const currentQueryDelaySettings = settingsFromLastUpdate.queryDelaySettings; + + if (now - lastUpdated >= this.cacheIntervalMs) { + // cache expired, refetch settings + try { + return await this.fetchSettings(request, spaceId, now); + } catch (err) { + // return cached settings on error + this.options.logger.debug( + `Failed to fetch rules settings after cache expiration, using cached settings: ${err.message}` + ); + return { + queryDelaySettings: currentQueryDelaySettings, + flappingSettings: currentFlappingSettings, + }; + } + } else { + return { + queryDelaySettings: currentQueryDelaySettings, + flappingSettings: currentFlappingSettings, + }; + } + } else { + // nothing in cache, fetch settings + try { + return await this.fetchSettings(request, spaceId, now); + } catch (err) { + // return default settings on error + this.options.logger.debug( + `Failed to fetch initial rules settings, using default settings: ${err.message}` + ); + return { + queryDelaySettings: this.defaultQueryDelaySettings, + flappingSettings: DEFAULT_FLAPPING_SETTINGS, + }; + } + } + } + + private async fetchSettings( + request: KibanaRequest, + spaceId: string, + now: number + ): Promise { + const rulesSettingsClient = this.options.getRulesSettingsClientWithRequest(request); + const queryDelaySettings = await withAlertingSpan('alerting:get-query-delay-settings', () => + rulesSettingsClient.queryDelay().get() + ); + + const flappingSettings = await withAlertingSpan('alerting:get-flapping-settings', () => + rulesSettingsClient.flapping().get() + ); + + this.settings.set(spaceId, { lastUpdated: now, queryDelaySettings, flappingSettings }); + + return { flappingSettings, queryDelaySettings }; + } +} diff --git a/x-pack/plugins/alerting/server/rules_settings_client/schemas/flapping_schema.ts b/x-pack/plugins/alerting/server/rules_settings/schemas/flapping_schema.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/schemas/flapping_schema.ts rename to x-pack/plugins/alerting/server/rules_settings/schemas/flapping_schema.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client/schemas/index.ts b/x-pack/plugins/alerting/server/rules_settings/schemas/index.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/schemas/index.ts rename to x-pack/plugins/alerting/server/rules_settings/schemas/index.ts diff --git a/x-pack/plugins/alerting/server/rules_settings_client/schemas/query_delay_schema.ts b/x-pack/plugins/alerting/server/rules_settings/schemas/query_delay_schema.ts similarity index 100% rename from x-pack/plugins/alerting/server/rules_settings_client/schemas/query_delay_schema.ts rename to x-pack/plugins/alerting/server/rules_settings/schemas/query_delay_schema.ts diff --git a/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts index 9b65f6613baaf..f90420ba85036 100644 --- a/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/ad_hoc_task_runner.test.ts @@ -32,7 +32,6 @@ import { TaskRunnerContext } from './types'; import { backfillClientMock } from '../backfill_client/backfill_client.mock'; import { maintenanceWindowClientMock } from '../maintenance_window_client.mock'; import { rulesClientMock } from '../rules_client.mock'; -import { rulesSettingsClientMock } from '../rules_settings_client.mock'; import { ruleTypeRegistryMock } from '../rule_type_registry.mock'; import { AlertingEventLogger, @@ -94,6 +93,7 @@ import { validateRuleTypeParams } from '../lib/validate_rule_type_params'; import { ruleRunMetricsStoreMock } from '../lib/rule_run_metrics_store.mock'; import { RuleRunMetricsStore } from '../lib/rule_run_metrics_store'; import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; +import { rulesSettingsServiceMock } from '../rules_settings/rules_settings_service.mock'; const UUID = '5f6aa57d-3e22-484e-bae8-cbed868f4d28'; @@ -145,17 +145,14 @@ const internalSavedObjectsRepository = savedObjectsRepositoryMock.create(); const maintenanceWindowClient = maintenanceWindowClientMock.create(); const rulesClient = rulesClientMock.create(); const ruleRunMetricsStore = ruleRunMetricsStoreMock.create(); +const rulesSettingsService = rulesSettingsServiceMock.create(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); const savedObjectsService = savedObjectsServiceMock.createInternalStartContract(); const services = alertsMock.createRuleExecutorServices(); const uiSettingsService = uiSettingsServiceMock.createStartContract(); const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType = { - actionsConfigMap: { - default: { - max: 10000, - }, - }, + actionsConfigMap: { default: { max: 1000 } }, actionsPlugin: actionsMock.createStart(), alertsService, backfillClient, @@ -170,12 +167,12 @@ const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType executionContext: executionContextServiceMock.createInternalStartContract(), getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient), getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), - getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClientMock.create()), kibanaBaseUrl: 'https://localhost:5601', logger, maxAlerts: 1000, maxEphemeralActionsPerRule: 10, ruleTypeRegistry, + rulesSettingsService, savedObjects: savedObjectsService, share: {} as SharePluginStart, spaceIdToNamespace: jest.fn().mockReturnValue(undefined), diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index c6cec600090ba..833393504fdeb 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -17,6 +17,8 @@ import { Rule, RuleAction, RuleAlertData, + DEFAULT_FLAPPING_SETTINGS, + DEFAULT_QUERY_DELAY_SETTINGS, } from '../types'; import { ConcreteTaskInstance, @@ -81,7 +83,6 @@ import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_e import { SharePluginStart } from '@kbn/share-plugin/server'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; -import { rulesSettingsClientMock } from '../rules_settings_client.mock'; import { maintenanceWindowClientMock } from '../maintenance_window_client.mock'; import { alertsServiceMock } from '../alerts_service/alerts_service.mock'; import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; @@ -95,6 +96,7 @@ import { ruleResultServiceMock } from '../monitoring/rule_result_service.mock'; import { backfillClientMock } from '../backfill_client/backfill_client.mock'; import { UntypedNormalizedRuleType } from '../rule_type_registry'; import * as getExecutorServicesModule from './get_executor_services'; +import { rulesSettingsServiceMock } from '../rules_settings/rules_settings_service.mock'; jest.mock('uuid', () => ({ v4: () => '5f6aa57d-3e22-484e-bae8-cbed868f4d28', @@ -157,6 +159,7 @@ describe('Task Runner', () => { const alertsService = alertsServiceMock.create(); const maintenanceWindowClient = maintenanceWindowClientMock.create(); const connectorAdapterRegistry = new ConnectorAdapterRegistry(); + const rulesSettingsService = rulesSettingsServiceMock.create(); type TaskRunnerFactoryInitializerParamsType = jest.Mocked & { actionsPlugin: jest.Mocked; @@ -165,37 +168,35 @@ describe('Task Runner', () => { }; const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType = { + actionsConfigMap: { default: { max: 1000 } }, + actionsPlugin: actionsMock.createStart(), + alertsService, + backfillClient, + basePathService: httpServiceMock.createBasePath(), + cancelAlertsOnRuleTimeout: true, + connectorAdapterRegistry, data: dataPlugin, dataViews: dataViewsMock, - savedObjects: savedObjectsService, - share: {} as SharePluginStart, - uiSettings: uiSettingsService, elasticsearch: elasticsearchService, - actionsPlugin: actionsMock.createStart(), - getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), encryptedSavedObjectsClient, - logger, - backfillClient, - executionContext: executionContextServiceMock.createInternalStartContract(), - spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - basePathService: httpServiceMock.createBasePath(), eventLogger: eventLoggerMock.create(), - ruleTypeRegistry, - alertsService, + executionContext: executionContextServiceMock.createInternalStartContract(), + getMaintenanceWindowClientWithRequest: jest + .fn() + .mockReturnValue(maintenanceWindowClientMock.create()), + getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), kibanaBaseUrl: 'https://localhost:5601', - supportsEphemeralTasks: false, - maxEphemeralActionsPerRule: 10, + logger, maxAlerts: 1000, - cancelAlertsOnRuleTimeout: true, + maxEphemeralActionsPerRule: 10, + ruleTypeRegistry, + rulesSettingsService, + savedObjects: savedObjectsService, + share: {} as SharePluginStart, + spaceIdToNamespace: jest.fn().mockReturnValue(undefined), + supportsEphemeralTasks: false, + uiSettings: uiSettingsService, usageCounter: mockUsageCounter, - actionsConfigMap: { - default: { - max: 10000, - }, - }, - getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClientMock.create()), - getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient), - connectorAdapterRegistry, }; const ephemeralTestParams: Array< @@ -242,13 +243,14 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams.actionsPlugin.renderActionParameterTemplates.mockImplementation( (actionTypeId, actionId, params) => params ); + rulesSettingsService.getSettings.mockResolvedValue({ + flappingSettings: DEFAULT_FLAPPING_SETTINGS, + queryDelaySettings: DEFAULT_QUERY_DELAY_SETTINGS, + }); ruleTypeRegistry.get.mockReturnValue(ruleType); taskRunnerFactoryInitializerParams.executionContext.withContext.mockImplementation((ctx, fn) => fn() ); - taskRunnerFactoryInitializerParams.getRulesSettingsClientWithRequest.mockReturnValue( - rulesSettingsClientMock.create() - ); taskRunnerFactoryInitializerParams.getMaintenanceWindowClientWithRequest.mockReturnValue( maintenanceWindowClient ); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 409427bb34ca2..936ff2bc64797 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -291,21 +291,16 @@ export class TaskRunner< state: { previousStartedAt }, } = this.taskInstance; - const rulesSettingsClient = this.context.getRulesSettingsClientWithRequest(fakeRequest); + const { queryDelaySettings, flappingSettings } = + await this.context.rulesSettingsService.getSettings(fakeRequest, spaceId); const ruleRunMetricsStore = new RuleRunMetricsStore(); const ruleLabel = `${this.ruleType.id}:${ruleId}: '${rule.name}'`; - const queryDelay = await withAlertingSpan('alerting:get-query-delay-settings', () => - rulesSettingsClient.queryDelay().get() - ); - const flappingSettings = await withAlertingSpan('alerting:get-flapping-settings', () => - rulesSettingsClient.flapping().get() - ); const ruleTypeRunnerContext = { alertingEventLogger: this.alertingEventLogger, flappingSettings, namespace: this.context.spaceIdToNamespace(spaceId), - queryDelaySec: queryDelay.delay, + queryDelaySec: queryDelaySettings.delay, ruleId, ruleLogPrefix: ruleLabel, ruleRunMetricsStore, diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts index 851bdddaed62a..cee8a2ea3b345 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_alerts_client.test.ts @@ -15,6 +15,8 @@ import { AlertInstanceContext, Rule, RuleAlertData, + DEFAULT_FLAPPING_SETTINGS, + DEFAULT_QUERY_DELAY_SETTINGS, } from '../types'; import { ConcreteTaskInstance } from '@kbn/task-manager-plugin/server'; import { TaskRunnerContext } from './types'; @@ -55,7 +57,6 @@ import { alertingEventLoggerMock } from '../lib/alerting_event_logger/alerting_e import { SharePluginStart } from '@kbn/share-plugin/server'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; -import { rulesSettingsClientMock } from '../rules_settings_client.mock'; import { maintenanceWindowClientMock } from '../maintenance_window_client.mock'; import { alertsServiceMock } from '../alerts_service/alerts_service.mock'; import { UntypedNormalizedRuleType } from '../rule_type_registry'; @@ -103,6 +104,7 @@ import { import { backfillClientMock } from '../backfill_client/backfill_client.mock'; import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; import { createTaskRunnerLogger } from './lib'; +import { rulesSettingsServiceMock } from '../rules_settings/rules_settings_service.mock'; jest.mock('uuid', () => ({ v4: () => '5f6aa57d-3e22-484e-bae8-cbed868f4d28', @@ -161,6 +163,7 @@ describe('Task Runner', () => { const backfillClient = backfillClientMock.create(); const services = alertsMock.createRuleExecutorServices(); const actionsClient = actionsClientMock.create(); + const rulesSettingsService = rulesSettingsServiceMock.create(); const rulesClient = rulesClientMock.create(); const ruleTypeRegistry = ruleTypeRegistryMock.create(); const savedObjectsService = savedObjectsServiceMock.createInternalStartContract(); @@ -189,39 +192,33 @@ describe('Task Runner', () => { }; const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType = { + actionsConfigMap: { default: { max: 1000 } }, + actionsPlugin: actionsMock.createStart(), + alertsService: mockAlertsService, + backfillClient, + basePathService: httpServiceMock.createBasePath(), + cancelAlertsOnRuleTimeout: true, + connectorAdapterRegistry, data: dataPlugin, dataViews: dataViewsMock, - savedObjects: savedObjectsService, - share: {} as SharePluginStart, - uiSettings: uiSettingsService, elasticsearch: elasticsearchService, - actionsPlugin: actionsMock.createStart(), - getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), encryptedSavedObjectsClient, - logger, - executionContext: executionContextServiceMock.createInternalStartContract(), - spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - basePathService: httpServiceMock.createBasePath(), eventLogger: eventLoggerMock.create(), - backfillClient, - ruleTypeRegistry, - alertsService: mockAlertsService, + executionContext: executionContextServiceMock.createInternalStartContract(), + getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient), + getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), kibanaBaseUrl: 'https://localhost:5601', - supportsEphemeralTasks: false, - maxEphemeralActionsPerRule: 10, + logger, maxAlerts: 1000, - cancelAlertsOnRuleTimeout: true, + maxEphemeralActionsPerRule: 10, + ruleTypeRegistry, + rulesSettingsService, + savedObjects: savedObjectsService, + share: {} as SharePluginStart, + spaceIdToNamespace: jest.fn().mockReturnValue(undefined), + supportsEphemeralTasks: false, + uiSettings: uiSettingsService, usageCounter: mockUsageCounter, - actionsConfigMap: { - default: { - max: 10000, - }, - }, - getRulesSettingsClientWithRequest: jest - .fn() - .mockReturnValue(rulesSettingsClientMock.create()), - getMaintenanceWindowClientWithRequest: jest.fn().mockReturnValue(maintenanceWindowClient), - connectorAdapterRegistry, }; describe(`using ${label} for alert indices`, () => { @@ -251,9 +248,10 @@ describe('Task Runner', () => { taskRunnerFactoryInitializerParams.executionContext.withContext.mockImplementation( (ctx, fn) => fn() ); - taskRunnerFactoryInitializerParams.getRulesSettingsClientWithRequest.mockReturnValue( - rulesSettingsClientMock.create() - ); + rulesSettingsService.getSettings.mockResolvedValue({ + flappingSettings: DEFAULT_FLAPPING_SETTINGS, + queryDelaySettings: DEFAULT_QUERY_DELAY_SETTINGS, + }); taskRunnerFactoryInitializerParams.getMaintenanceWindowClientWithRequest.mockReturnValue( maintenanceWindowClient ); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts index fdc05d208aba1..b9fb6284c3911 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_cancel.test.ts @@ -15,6 +15,8 @@ import { AlertInstanceContext, Rule, RuleAlertData, + DEFAULT_FLAPPING_SETTINGS, + DEFAULT_QUERY_DELAY_SETTINGS, } from '../types'; import { ConcreteTaskInstance } from '@kbn/task-manager-plugin/server'; import { TaskRunner } from './task_runner'; @@ -54,7 +56,6 @@ import { EVENT_LOG_ACTIONS } from '../plugin'; import { SharePluginStart } from '@kbn/share-plugin/server'; import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { rulesSettingsClientMock } from '../rules_settings_client.mock'; import { maintenanceWindowClientMock } from '../maintenance_window_client.mock'; import { alertsServiceMock } from '../alerts_service/alerts_service.mock'; import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; @@ -62,6 +63,7 @@ import { RULE_SAVED_OBJECT_TYPE } from '../saved_objects'; import { TaskRunnerContext } from './types'; import { backfillClientMock } from '../backfill_client/backfill_client.mock'; import { UntypedNormalizedRuleType } from '../rule_type_registry'; +import { rulesSettingsServiceMock } from '../rules_settings/rules_settings_service.mock'; jest.mock('uuid', () => ({ v4: () => '5f6aa57d-3e22-484e-bae8-cbed868f4d28', @@ -116,6 +118,7 @@ describe('Task Runner Cancel', () => { const dataPlugin = dataPluginMock.createStartContract(); const inMemoryMetrics = inMemoryMetricsMock.create(); const connectorAdapterRegistry = new ConnectorAdapterRegistry(); + const rulesSettingsService = rulesSettingsServiceMock.create(); type TaskRunnerFactoryInitializerParamsType = jest.Mocked & { actionsPlugin: jest.Mocked; @@ -124,39 +127,35 @@ describe('Task Runner Cancel', () => { }; const taskRunnerFactoryInitializerParams: TaskRunnerFactoryInitializerParamsType = { + actionsConfigMap: { default: { max: 1000 } }, + actionsPlugin: actionsMock.createStart(), + alertsService, + backfillClient, + basePathService: httpServiceMock.createBasePath(), + cancelAlertsOnRuleTimeout: true, + connectorAdapterRegistry, data: dataPlugin, dataViews: dataViewsMock, - savedObjects: savedObjectsService, - share: {} as SharePluginStart, - uiSettings: uiSettingsService, elasticsearch: elasticsearchService, - actionsPlugin: actionsMock.createStart(), - getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), encryptedSavedObjectsClient, - logger, - executionContext: executionContextServiceMock.createInternalStartContract(), - spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - basePathService: httpServiceMock.createBasePath(), eventLogger: eventLoggerMock.create(), - backfillClient, - ruleTypeRegistry, - alertsService, - kibanaBaseUrl: 'https://localhost:5601', - supportsEphemeralTasks: false, - maxEphemeralActionsPerRule: 10, - maxAlerts: 1000, - cancelAlertsOnRuleTimeout: true, - usageCounter: mockUsageCounter, - actionsConfigMap: { - default: { - max: 1000, - }, - }, - getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClientMock.create()), + executionContext: executionContextServiceMock.createInternalStartContract(), getMaintenanceWindowClientWithRequest: jest .fn() .mockReturnValue(maintenanceWindowClientMock.create()), - connectorAdapterRegistry, + getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), + kibanaBaseUrl: 'https://localhost:5601', + logger, + maxAlerts: 1000, + maxEphemeralActionsPerRule: 10, + ruleTypeRegistry, + rulesSettingsService, + savedObjects: savedObjectsService, + share: {} as SharePluginStart, + spaceIdToNamespace: jest.fn().mockReturnValue(undefined), + supportsEphemeralTasks: false, + uiSettings: uiSettingsService, + usageCounter: mockUsageCounter, }; beforeEach(() => { @@ -184,9 +183,10 @@ describe('Task Runner Cancel', () => { taskRunnerFactoryInitializerParams.executionContext.withContext.mockImplementation((ctx, fn) => fn() ); - taskRunnerFactoryInitializerParams.getRulesSettingsClientWithRequest.mockReturnValue( - rulesSettingsClientMock.create() - ); + rulesSettingsService.getSettings.mockResolvedValue({ + flappingSettings: DEFAULT_FLAPPING_SETTINGS, + queryDelaySettings: DEFAULT_QUERY_DELAY_SETTINGS, + }); taskRunnerFactoryInitializerParams.getMaintenanceWindowClientWithRequest.mockReturnValue( maintenanceWindowClientMock.create() ); diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts index a29d9f3c0ad91..d2e863ef865b2 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner_factory.test.ts @@ -28,16 +28,17 @@ import { inMemoryMetricsMock } from '../monitoring/in_memory_metrics.mock'; import { SharePluginStart } from '@kbn/share-plugin/server'; import { DataViewsServerPluginStart } from '@kbn/data-views-plugin/server'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; -import { rulesSettingsClientMock } from '../rules_settings_client.mock'; import { maintenanceWindowClientMock } from '../maintenance_window_client.mock'; import { alertsServiceMock } from '../alerts_service/alerts_service.mock'; import { schema } from '@kbn/config-schema'; import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; import { TaskRunnerContext } from './types'; import { backfillClientMock } from '../backfill_client/backfill_client.mock'; +import { rulesSettingsServiceMock } from '../rules_settings/rules_settings_service.mock'; const inMemoryMetrics = inMemoryMetricsMock.create(); const backfillClient = backfillClientMock.create(); +const rulesSettingsService = rulesSettingsServiceMock.create(); const executionContext = executionContextServiceMock.createSetupContract(); const mockUsageCountersSetup = usageCountersServiceMock.createSetupContract(); const mockUsageCounter = mockUsageCountersSetup.createUsageCounter('test'); @@ -103,39 +104,35 @@ describe('Task Runner Factory', () => { const connectorAdapterRegistry = new ConnectorAdapterRegistry(); const taskRunnerFactoryInitializerParams: jest.Mocked = { + actionsConfigMap: { default: { max: 1000 } }, + actionsPlugin: actionsMock.createStart(), + alertsService: mockAlertService, backfillClient, + basePathService: httpServiceMock.createBasePath(), + cancelAlertsOnRuleTimeout: true, + connectorAdapterRegistry, data: dataPlugin, dataViews: dataViewsMock, - savedObjects: savedObjectsService, - share: {} as SharePluginStart, - uiSettings: uiSettingsService, elasticsearch: elasticsearchService, - getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), - actionsPlugin: actionsMock.createStart(), encryptedSavedObjectsClient: encryptedSavedObjectsPlugin.getClient(), - logger: loggingSystemMock.create().get(), - spaceIdToNamespace: jest.fn().mockReturnValue(undefined), - basePathService: httpServiceMock.createBasePath(), eventLogger: eventLoggerMock.create(), - ruleTypeRegistry: ruleTypeRegistryMock.create(), - alertsService: mockAlertService, - kibanaBaseUrl: 'https://localhost:5601', - supportsEphemeralTasks: true, - maxEphemeralActionsPerRule: 10, - maxAlerts: 1000, - cancelAlertsOnRuleTimeout: true, executionContext, - usageCounter: mockUsageCounter, - actionsConfigMap: { - default: { - max: 1000, - }, - }, - getRulesSettingsClientWithRequest: jest.fn().mockReturnValue(rulesSettingsClientMock.create()), getMaintenanceWindowClientWithRequest: jest .fn() .mockReturnValue(maintenanceWindowClientMock.create()), - connectorAdapterRegistry, + getRulesClientWithRequest: jest.fn().mockReturnValue(rulesClient), + kibanaBaseUrl: 'https://localhost:5601', + logger: loggingSystemMock.create().get(), + maxAlerts: 1000, + maxEphemeralActionsPerRule: 10, + ruleTypeRegistry: ruleTypeRegistryMock.create(), + rulesSettingsService, + savedObjects: savedObjectsService, + share: {} as SharePluginStart, + spaceIdToNamespace: jest.fn().mockReturnValue(undefined), + supportsEphemeralTasks: true, + uiSettings: uiSettingsService, + usageCounter: mockUsageCounter, }; beforeEach(() => { diff --git a/x-pack/plugins/alerting/server/task_runner/types.ts b/x-pack/plugins/alerting/server/task_runner/types.ts index 9d40c186bcead..18bf53cdc60b9 100644 --- a/x-pack/plugins/alerting/server/task_runner/types.ts +++ b/x-pack/plugins/alerting/server/task_runner/types.ts @@ -48,7 +48,6 @@ import { MaintenanceWindowClientApi, RawRule, RulesClientApi, - RulesSettingsClientApi, RuleTypeRegistry, SpaceIdToNamespaceFunction, } from '../types'; @@ -57,6 +56,7 @@ import { AlertingEventLogger } from '../lib/alerting_event_logger/alerting_event import { BackfillClient } from '../backfill_client/backfill_client'; import { ElasticsearchError } from '../lib'; import { ConnectorAdapterRegistry } from '../connector_adapters/connector_adapter_registry'; +import { RulesSettingsService } from '../rules_settings'; export interface RuleTaskRunResult { state: RuleTaskState; @@ -160,6 +160,7 @@ export interface TaskRunnerContext { backfillClient: BackfillClient; basePathService: IBasePath; cancelAlertsOnRuleTimeout: boolean; + connectorAdapterRegistry: ConnectorAdapterRegistry; data: DataPluginStart; dataViews: DataViewsPluginStart; elasticsearch: ElasticsearchServiceStart; @@ -168,17 +169,16 @@ export interface TaskRunnerContext { executionContext: ExecutionContextStart; getMaintenanceWindowClientWithRequest(request: KibanaRequest): MaintenanceWindowClientApi; getRulesClientWithRequest(request: KibanaRequest): RulesClientApi; - getRulesSettingsClientWithRequest(request: KibanaRequest): RulesSettingsClientApi; kibanaBaseUrl: string | undefined; logger: Logger; maxAlerts: number; maxEphemeralActionsPerRule: number; ruleTypeRegistry: RuleTypeRegistry; + rulesSettingsService: RulesSettingsService; savedObjects: SavedObjectsServiceStart; share: SharePluginStart; spaceIdToNamespace: SpaceIdToNamespaceFunction; supportsEphemeralTasks: boolean; uiSettings: UiSettingsServiceStart; usageCounter?: UsageCounter; - connectorAdapterRegistry: ConnectorAdapterRegistry; } diff --git a/x-pack/plugins/alerting/server/test_utils/index.ts b/x-pack/plugins/alerting/server/test_utils/index.ts index 9985f43348eb0..036454f2f80c6 100644 --- a/x-pack/plugins/alerting/server/test_utils/index.ts +++ b/x-pack/plugins/alerting/server/test_utils/index.ts @@ -71,5 +71,6 @@ export function generateAlertingConfig(): AlertingConfig { }, }, }, + rulesSettings: { cacheInterval: 60000 }, }; } diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index 3df6f241061c3..58404268efaa8 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -36,7 +36,7 @@ import { RulesSettingsClient, RulesSettingsFlappingClient, RulesSettingsQueryDelayClient, -} from './rules_settings_client'; +} from './rules_settings'; import { MaintenanceWindowClient } from './maintenance_window_client'; export * from '../common'; import { diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 80439bc1cb489..1faadc6041634 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -208,6 +208,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) { id: 'test.capped', max: '1' }, ])}`, `--xpack.alerting.enableFrameworkAlerts=true`, + `--xpack.alerting.rulesSettings.cacheInterval=10000`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, `--xpack.actions.rejectUnauthorized=${rejectUnauthorized}`, `--xpack.actions.microsoftGraphApiUrl=${servers.kibana.protocol}://${servers.kibana.hostname}:${servers.kibana.port}/api/_actions-FTS-external-service-simulators/exchange/users/test@/sendMail`, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts index 5ce7ffcd18ef5..c0c52ddc73b5a 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data.ts @@ -8,6 +8,7 @@ import expect from '@kbn/expect'; import { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import { setTimeout as setTimeoutAsync } from 'timers/promises'; import type { Alert } from '@kbn/alerts-as-data-utils'; import { omit } from 'lodash'; import { @@ -87,6 +88,8 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F it(`should write alert docs during rule execution with flapping.enabled: ${enableFlapping}`, async () => { await setFlappingSettings(enableFlapping); + // wait so cache expires + await setTimeoutAsync(10000); const pattern = { alertA: [true, true, true], // stays active across executions diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts index 6dce47b54ebce..de1f4351e0fa8 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts @@ -9,6 +9,7 @@ import expect from '@kbn/expect'; import { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import type { Alert } from '@kbn/alerts-as-data-utils'; import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; +import { setTimeout as setTimeoutAsync } from 'timers/promises'; import { ALERT_FLAPPING, ALERT_FLAPPING_HISTORY, ALERT_RULE_UUID } from '@kbn/rule-data-utils'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { Spaces } from '../../../../scenarios'; @@ -57,6 +58,8 @@ export default function createAlertsAsDataFlappingTest({ getService }: FtrProvid status_change_threshold: 4, }) .expect(200); + // wait so cache expires + await setTimeoutAsync(10000); const pattern = { alertA: [true, false, false, true, false, true, false, true, false].concat( @@ -188,6 +191,8 @@ export default function createAlertsAsDataFlappingTest({ getService }: FtrProvid status_change_threshold: 4, }) .expect(200); + // wait so cache expires + await setTimeoutAsync(10000); const pattern = { alertA: [true, false, false, true, false, true, false, true, false, true].concat( @@ -316,6 +321,8 @@ export default function createAlertsAsDataFlappingTest({ getService }: FtrProvid status_change_threshold: 3, }) .expect(200); + // wait so cache expires + await setTimeoutAsync(10000); const pattern = { alertA: [true, false, true, false, false, false, false, false, false], @@ -374,6 +381,8 @@ export default function createAlertsAsDataFlappingTest({ getService }: FtrProvid status_change_threshold: 5, }) .expect(200); + // wait so cache expires + await setTimeoutAsync(10000); const pattern = { alertA: [true, false, false, true, false, true, false, true, false].concat( From 636873e10c93941baefc65477ea445c1c3a3bc04 Mon Sep 17 00:00:00 2001 From: Yehor Shvedov <146825775+ev1yehor@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:35:28 +0300 Subject: [PATCH 019/139] Add vault bot to allowed list (#190977) ## Summary Summarize your PR. If it involves visual changes include a screenshot or gif. Adding github vault bot to allowed list to allow triggering buildkite builds. Related to PR https://github.com/elastic/package-storage-infra/pull/787 And issue: https://github.com/elastic/ingest-dev/issues/3495 --- .buildkite/pull_requests.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.buildkite/pull_requests.json b/.buildkite/pull_requests.json index 0758e0255247f..1f45c01042888 100644 --- a/.buildkite/pull_requests.json +++ b/.buildkite/pull_requests.json @@ -8,6 +8,7 @@ "enabled": true, "allow_org_users": true, "allowed_repo_permissions": ["admin", "write"], + "allowed_list": ["elastic-vault-github-plugin-prod[bot]"], "set_commit_status": true, "commit_status_context": "kibana-ci", "build_on_commit": true, From a5a7f1554b731f98e51a18efccdbf6e771077144 Mon Sep 17 00:00:00 2001 From: Or Ouziel Date: Mon, 16 Sep 2024 16:38:42 +0300 Subject: [PATCH 020/139] [Cloud Security] Fix GCP service account deployment copy-paste command (#192959) --- .../gcp_credentials_form/gcp_credentials_form_agentless.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/gcp_credentials_form/gcp_credentials_form_agentless.tsx b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/gcp_credentials_form/gcp_credentials_form_agentless.tsx index 9cced3c87729b..4cec65cc695bb 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/gcp_credentials_form/gcp_credentials_form_agentless.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/gcp_credentials_form/gcp_credentials_form_agentless.tsx @@ -194,8 +194,8 @@ export const GcpCredentialsFormAgentless = ({ )?.replace(TEMPLATE_URL_ACCOUNT_TYPE_ENV_VAR, accountType); const commandText = `gcloud config set project ${ - isOrganization ? ` && ORD_ID=` : `` - } && ./deploy_service_account.sh`; + isOrganization ? ` && ORG_ID=` : `` + } ./deploy_service_account.sh`; return ( <> From e404a3992e220735ae51918c532a1a032e7f7993 Mon Sep 17 00:00:00 2001 From: Drew Tate Date: Mon, 16 Sep 2024 07:41:38 -0600 Subject: [PATCH 021/139] [ES|QL] open suggestions automatically in sources lists and `ENRICH` (#191312) ## Summary Part of https://github.com/elastic/kibana/issues/189662 Also, a follow-on to https://github.com/elastic/kibana/issues/187184 with certain source names (e.g. `foo$bar`, `my-policy`) and fields in the `ENRICH` command. During this effort I discovered https://github.com/elastic/kibana/issues/191321 and a bug with the validation of field names in the "ENRICH ... WITH" list (documented [here](https://github.com/elastic/kibana/issues/177699)), both of which will be addressed separately. ## Sources ### General flow https://github.com/user-attachments/assets/4b103621-0e66-4c36-807f-4932f0cb8faf ### Works with wild-card matches https://github.com/user-attachments/assets/6b47fffc-e922-4e2d-b6aa-3d9a2fc2236c ### `METADATA` field list https://github.com/user-attachments/assets/d3bdf4dc-1d0c-4d56-81d7-af6bc4e25a4a ## ENRICH Autosuggest now helps you along https://github.com/user-attachments/assets/d627484c-e729-4dc7-9e7b-795395a31d4f Also, fixed this bug (follow on to https://github.com/elastic/kibana/issues/187184 ) https://github.com/user-attachments/assets/aa62a0c3-6db5-434a-829a-59f14c5c4c85 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Elastic Machine Co-authored-by: Stratoula Kalafateli --- packages/kbn-esql-ast/src/ast_helpers.ts | 2 +- .../src/utils/query_parsing_helpers.ts | 2 +- .../autocomplete.command.from.test.ts | 26 +- .../src/autocomplete/__tests__/helpers.ts | 7 +- .../src/autocomplete/autocomplete.test.ts | 425 +++++++++++++----- .../src/autocomplete/autocomplete.ts | 195 +++++--- .../src/autocomplete/factories.ts | 9 +- .../src/autocomplete/helper.ts | 4 +- .../src/shared/helpers.ts | 10 + .../src/shared/types.ts | 19 +- 10 files changed, 491 insertions(+), 208 deletions(-) diff --git a/packages/kbn-esql-ast/src/ast_helpers.ts b/packages/kbn-esql-ast/src/ast_helpers.ts index 7dff8cda3566a..76f576f1ec019 100644 --- a/packages/kbn-esql-ast/src/ast_helpers.ts +++ b/packages/kbn-esql-ast/src/ast_helpers.ts @@ -405,9 +405,9 @@ export function createSource( index, name: text, sourceType: type, - text, location: getPosition(ctx.start, ctx.stop), incomplete: Boolean(ctx.exception || text === ''), + text: ctx?.getText(), }; } diff --git a/packages/kbn-esql-utils/src/utils/query_parsing_helpers.ts b/packages/kbn-esql-utils/src/utils/query_parsing_helpers.ts index 734acac70fd7d..53ce6e06bb536 100644 --- a/packages/kbn-esql-utils/src/utils/query_parsing_helpers.ts +++ b/packages/kbn-esql-utils/src/utils/query_parsing_helpers.ts @@ -24,7 +24,7 @@ export function getIndexPatternFromESQLQuery(esql?: string) { const sourceCommand = ast.find(({ name }) => ['from', 'metrics'].includes(name)); const args = (sourceCommand?.args ?? []) as ESQLSource[]; const indices = args.filter((arg) => arg.sourceType === 'index'); - return indices?.map((index) => index.text).join(','); + return indices?.map((index) => index.name).join(','); } // For ES|QL we consider stats and keep transformational command diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.from.test.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.from.test.ts index 4d37ca078dd88..fa2a969384a09 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.from.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/autocomplete.command.from.test.ts @@ -15,9 +15,6 @@ const visibleIndices = indexes .map(({ name, suggestedAs }) => suggestedAs || name) .sort(); -const addTrailingSpace = (strings: string[], predicate: (s: string) => boolean = (_s) => true) => - strings.map((string) => (predicate(string) ? `${string} ` : string)); - const metadataFields = [...METADATA_FIELDS].sort(); describe('autocomplete.suggest', () => { @@ -37,17 +34,17 @@ describe('autocomplete.suggest', () => { test('suggests visible indices on space', async () => { const { assertSuggestions } = await setup(); - await assertSuggestions('from /', addTrailingSpace(visibleIndices)); - await assertSuggestions('FROM /', addTrailingSpace(visibleIndices)); - await assertSuggestions('from /index', addTrailingSpace(visibleIndices)); + await assertSuggestions('from /', visibleIndices); + await assertSuggestions('FROM /', visibleIndices); + await assertSuggestions('from /index', visibleIndices); }); test('suggests visible indices on comma', async () => { const { assertSuggestions } = await setup(); - await assertSuggestions('FROM a,/', addTrailingSpace(visibleIndices)); - await assertSuggestions('FROM a, /', addTrailingSpace(visibleIndices)); - await assertSuggestions('from *,/', addTrailingSpace(visibleIndices)); + await assertSuggestions('FROM a,/', visibleIndices); + await assertSuggestions('FROM a, /', visibleIndices); + await assertSuggestions('from *,/', visibleIndices); }); test('can suggest integration data sources', async () => { @@ -56,10 +53,7 @@ describe('autocomplete.suggest', () => { .filter(({ hidden }) => !hidden) .map(({ name, suggestedAs }) => suggestedAs || name) .sort(); - const expectedSuggestions = addTrailingSpace( - visibleDataSources, - (s) => !integrations.find(({ name }) => name === s) - ); + const expectedSuggestions = visibleDataSources; const { assertSuggestions, callbacks } = await setup(); const cb = { ...callbacks, @@ -75,7 +69,7 @@ describe('autocomplete.suggest', () => { }); describe('... METADATA ', () => { - const metadataFieldsSandIndex = metadataFields.filter((field) => field !== '_index'); + const metadataFieldsAndIndex = metadataFields.filter((field) => field !== '_index'); test('on SPACE without comma ",", suggests adding metadata', async () => { const { assertSuggestions } = await setup(); @@ -103,8 +97,8 @@ describe('autocomplete.suggest', () => { test('filters out already used metadata fields', async () => { const { assertSuggestions } = await setup(); - await assertSuggestions('from a, b [metadata _index, /]', metadataFieldsSandIndex); - await assertSuggestions('from a, b metadata _index, /', metadataFieldsSandIndex); + await assertSuggestions('from a, b [metadata _index, /]', metadataFieldsAndIndex); + await assertSuggestions('from a, b metadata _index, /', metadataFieldsAndIndex); }); }); }); diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/helpers.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/helpers.ts index 70b1d717f6e4e..7d09f2c82c4b7 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/helpers.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/__tests__/helpers.ts @@ -17,7 +17,7 @@ import { groupingFunctionDefinitions } from '../../definitions/grouping'; import * as autocomplete from '../autocomplete'; import type { ESQLCallbacks } from '../../shared/types'; import type { EditorContext, SuggestionRawDefinition } from '../types'; -import { TIME_SYSTEM_PARAMS } from '../factories'; +import { TIME_SYSTEM_PARAMS, getSafeInsertText } from '../factories'; import { getFunctionSignatures } from '../../definitions/helpers'; import { ESQLRealField } from '../../validation/types'; import { @@ -280,10 +280,7 @@ export function createCompletionContext(triggerCharacter?: string) { export function getPolicyFields(policyName: string) { return policies .filter(({ name }) => name === policyName) - .flatMap(({ enrichFields }) => - // ok, this is a bit of cheating as it's using the same logic as in the helper - enrichFields.map((field) => (/[^a-zA-Z\d_\.@]/.test(field) ? `\`${field}\`` : field)) - ); + .flatMap(({ enrichFields }) => enrichFields.map((field) => getSafeInsertText(field))); } export interface SuggestOptions { diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts index 80ff7148f8623..a58a55f124c4e 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.test.ts @@ -392,27 +392,44 @@ describe('autocomplete', () => { describe('enrich', () => { const modes = ['any', 'coordinator', 'remote']; - const policyNames = policies.map(({ name, suggestedAs }) => suggestedAs || name); + const expectedPolicyNameSuggestions = policies + .map(({ name, suggestedAs }) => suggestedAs || name) + .map((name) => `${name} `); for (const prevCommand of [ '', // '| enrich other-policy ', // '| enrich other-policy on b ', // '| enrich other-policy with c ', ]) { - testSuggestions(`from a ${prevCommand}| enrich /`, policyNames); + testSuggestions(`from a ${prevCommand}| enrich /`, expectedPolicyNameSuggestions); testSuggestions( `from a ${prevCommand}| enrich _/`, modes.map((mode) => `_${mode}:$0`), '_' ); for (const mode of modes) { - testSuggestions(`from a ${prevCommand}| enrich _${mode}:/`, policyNames, ':'); - testSuggestions(`from a ${prevCommand}| enrich _${mode.toUpperCase()}:/`, policyNames, ':'); - testSuggestions(`from a ${prevCommand}| enrich _${camelCase(mode)}:/`, policyNames, ':'); + testSuggestions( + `from a ${prevCommand}| enrich _${mode}:/`, + expectedPolicyNameSuggestions, + ':' + ); + testSuggestions( + `from a ${prevCommand}| enrich _${mode.toUpperCase()}:/`, + expectedPolicyNameSuggestions, + ':' + ); + testSuggestions( + `from a ${prevCommand}| enrich _${camelCase(mode)}:/`, + expectedPolicyNameSuggestions, + ':' + ); } testSuggestions(`from a ${prevCommand}| enrich policy /`, ['ON $0', 'WITH $0', '| ']); - testSuggestions(`from a ${prevCommand}| enrich policy on /`, getFieldNamesByType('any')); - testSuggestions(`from a ${prevCommand}| enrich policy on b /`, ['WITH $0', ',', '| ']); + testSuggestions( + `from a ${prevCommand}| enrich policy on /`, + getFieldNamesByType('any').map((v) => `${v} `) + ); + testSuggestions(`from a ${prevCommand}| enrich policy on b /`, ['WITH $0', '| ']); testSuggestions( `from a ${prevCommand}| enrich policy on b with /`, ['var0 = ', ...getPolicyFields('policy')], @@ -453,14 +470,8 @@ describe('autocomplete', () => { // @TODO: get updated eval block from main describe('values suggestions', () => { - testSuggestions('FROM "a/"', ['a ', 'b '], undefined, [ - , - [ - { name: 'a', hidden: false }, - { name: 'b', hidden: false }, - ], - ]); - testSuggestions('FROM " /"', [], ' '); + testSuggestions('FROM "i/"', ['index'], undefined, [, [{ name: 'index', hidden: false }]]); + testSuggestions('FROM "index/"', ['index'], undefined, [, [{ name: 'index', hidden: false }]]); // TODO — re-enable these tests when we can support this case testSuggestions.skip('FROM " a/"', []); testSuggestions.skip('FROM "foo b/"', []); @@ -564,7 +575,7 @@ describe('autocomplete', () => { }); // FROM source - testSuggestions('FROM k/', ['index1 ', 'index2 '], undefined, [ + testSuggestions('FROM k/', ['index1', 'index2'], undefined, [ , [ { name: 'index1', hidden: false }, @@ -604,14 +615,17 @@ describe('autocomplete', () => { // ENRICH policy testSuggestions( 'FROM index1 | ENRICH p/', - policies.map(({ name }) => getSafeInsertText(name)) + policies.map(({ name }) => getSafeInsertText(name) + ' ') ); // ENRICH policy ON testSuggestions('FROM index1 | ENRICH policy O/', ['ON $0', 'WITH $0', '| ']); // ENRICH policy ON field - testSuggestions('FROM index1 | ENRICH policy ON f/', getFieldNamesByType('any')); + testSuggestions( + 'FROM index1 | ENRICH policy ON f/', + getFieldNamesByType('any').map((name) => `${name} `) + ); // ENRICH policy WITH policyfield testSuggestions('FROM index1 | ENRICH policy WITH v/', [ @@ -714,6 +728,10 @@ describe('autocomplete', () => { }); describe('advancing the cursor and opening the suggestion menu automatically ✨', () => { + /** + * NOTE: Monaco uses an Invoke trigger kind when the show suggestions action is triggered (e.g. accepting the "FROM" suggestion) + */ + const attachTriggerCommand = ( s: string | PartialSuggestionWithText ): PartialSuggestionWithText => @@ -819,24 +837,122 @@ describe('autocomplete', () => { ]); // FROM source - // - // Using an Invoke trigger kind here because that's what Monaco uses when the show suggestions - // action is triggered (e.g. accepting the "FROM" suggestion) - testSuggestions( - 'FROM /', - [ - { text: 'index1 ', command: TRIGGER_SUGGESTION_COMMAND }, - { text: 'index2 ', command: TRIGGER_SUGGESTION_COMMAND }, - ], - undefined, - [ - , + describe('sources', () => { + testSuggestions( + 'FROM /', [ - { name: 'index1', hidden: false }, - { name: 'index2', hidden: false }, + { text: 'index1', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'index2', command: TRIGGER_SUGGESTION_COMMAND }, ], - ] - ); + undefined, + [ + , + [ + { name: 'index1', hidden: false }, + { name: 'index2', hidden: false }, + ], + ] + ); + + testSuggestions( + 'FROM index/', + [ + { text: 'index1', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'index2', command: TRIGGER_SUGGESTION_COMMAND }, + ], + undefined, + [ + , + [ + { name: 'index1', hidden: false }, + { name: 'index2', hidden: false }, + ], + ] + ); + + testSuggestions( + 'FROM index1/', + [ + { text: 'index1 | ', filterText: 'index1', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'index1, ', filterText: 'index1', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'index1 METADATA ', filterText: 'index1', command: TRIGGER_SUGGESTION_COMMAND }, + ], + undefined, + [ + , + [ + { name: 'index1', hidden: false }, + { name: 'index2', hidden: false }, + ], + ] + ); + + testSuggestions( + 'FROM index1, index2/', + [ + { text: 'index2 | ', filterText: 'index2', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'index2, ', filterText: 'index2', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'index2 METADATA ', filterText: 'index2', command: TRIGGER_SUGGESTION_COMMAND }, + ], + undefined, + [ + , + [ + { name: 'index1', hidden: false }, + { name: 'index2', hidden: false }, + ], + ] + ); + + // This is a source name that contains a special character + // meaning that Monaco by default will only set the replacement + // range to cover "bar" and not "foo$bar". We have to make sure + // we're setting it ourselves. + testSuggestions( + 'FROM foo$bar/', + [ + { + text: 'foo$bar | ', + filterText: 'foo$bar', + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace: { start: 6, end: 13 }, + }, + { + text: 'foo$bar, ', + filterText: 'foo$bar', + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace: { start: 6, end: 13 }, + }, + { + text: 'foo$bar METADATA ', + filterText: 'foo$bar', + asSnippet: false, // important because the text includes "$" + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace: { start: 6, end: 13 }, + }, + ], + undefined, + [, [{ name: 'foo$bar', hidden: false }]] + ); + + // This is an identifier that matches multiple sources + testSuggestions( + 'FROM i*/', + [ + { text: 'i* | ', filterText: 'i*', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'i*, ', filterText: 'i*', command: TRIGGER_SUGGESTION_COMMAND }, + { text: 'i* METADATA ', filterText: 'i*', command: TRIGGER_SUGGESTION_COMMAND }, + ], + undefined, + [ + , + [ + { name: 'index1', hidden: false }, + { name: 'index2', hidden: false }, + ], + ] + ); + }); // FROM source METADATA testSuggestions('FROM index1 M/', [ @@ -845,6 +961,57 @@ describe('autocomplete', () => { '| ', ]); + describe('ENRICH', () => { + testSuggestions( + 'FROM a | ENRICH /', + policies.map((p) => `${getSafeInsertText(p.name)} `).map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a | ENRICH pol/', + policies + .map((p) => `${getSafeInsertText(p.name)} `) + .map(attachTriggerCommand) + .map((s) => ({ ...s, rangeToReplace: { start: 17, end: 20 } })) + ); + testSuggestions( + 'FROM a | ENRICH policy /', + ['ON $0', 'WITH $0', '| '].map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a | ENRICH policy ON /', + getFieldNamesByType('any') + .map((name) => `${name} `) + .map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a | ENRICH policy ON @timestamp /', + ['WITH $0', '| '].map(attachTriggerCommand) + ); + // nothing fancy with this field list + testSuggestions('FROM a | ENRICH policy ON @timestamp WITH /', [ + 'var0 = ', + ...getPolicyFields('policy').map((name) => ({ text: name, command: undefined })), + ]); + describe('replacement range', () => { + testSuggestions('FROM a | ENRICH policy ON @timestamp WITH othe/', [ + 'var0 = ', + ...getPolicyFields('policy').map((name) => ({ + text: name, + command: undefined, + rangeToReplace: { start: 43, end: 47 }, + })), + ]); + testSuggestions( + 'FROM a | ENRICH policy ON @timestamp WITH var0 = othe/', + getPolicyFields('policy').map((name) => ({ + text: name, + command: undefined, + rangeToReplace: { start: 50, end: 54 }, + })) + ); + }); + }); + // LIMIT number testSuggestions('FROM a | LIMIT /', ['10 ', '100 ', '1000 '].map(attachTriggerCommand)); @@ -937,80 +1104,126 @@ describe('autocomplete', () => { ['keyword'] ).map((s) => (s.text.toLowerCase().includes('null') ? s : attachTriggerCommand(s))) ); - describe('field lists', () => { - // KEEP field - testSuggestions('FROM a | KEEP /', getFieldNamesByType('any').map(attachTriggerCommand)); - testSuggestions( - 'FROM a | KEEP d/', - getFieldNamesByType('any') - .map((text) => ({ - text, - rangeToReplace: { start: 15, end: 16 }, - })) - .map(attachTriggerCommand) - ); - testSuggestions( - 'FROM a | KEEP doubleFiel/', - getFieldNamesByType('any').map(attachTriggerCommand) - ); - testSuggestions( - 'FROM a | KEEP doubleField/', - ['doubleField, ', 'doubleField | '] - .map((text) => ({ - text, - filterText: 'doubleField', - rangeToReplace: { start: 15, end: 26 }, - })) - .map(attachTriggerCommand) - ); - testSuggestions('FROM a | KEEP doubleField /', ['| ', ',']); - // Let's get funky with the field names - testSuggestions( - 'FROM a | KEEP @timestamp/', - ['@timestamp, ', '@timestamp | '] - .map((text) => ({ - text, - filterText: '@timestamp', - rangeToReplace: { start: 15, end: 25 }, - })) - .map(attachTriggerCommand), - undefined, - [[{ name: '@timestamp', type: 'date' }]] - ); - testSuggestions( - 'FROM a | KEEP foo.bar/', - ['foo.bar, ', 'foo.bar | '] - .map((text) => ({ - text, - filterText: 'foo.bar', - rangeToReplace: { start: 15, end: 22 }, - })) - .map(attachTriggerCommand), - undefined, - [[{ name: 'foo.bar', type: 'double' }]] - ); - - // @todo re-enable these tests when we can use AST to support this case - testSuggestions.skip('FROM a | KEEP `foo.bar`/', ['foo.bar, ', 'foo.bar | '], undefined, [ - [{ name: 'foo.bar', type: 'double' }], - ]); - testSuggestions.skip('FROM a | KEEP `foo`.`bar`/', ['foo.bar, ', 'foo.bar | '], undefined, [ - [{ name: 'foo.bar', type: 'double' }], - ]); - testSuggestions.skip('FROM a | KEEP `any#Char$Field`/', [ - '`any#Char$Field`, ', - '`any#Char$Field` | ', - ]); + describe('field lists', () => { + describe('METADATA ', () => { + // METADATA field + testSuggestions('FROM a METADATA /', METADATA_FIELDS.map(attachTriggerCommand)); + testSuggestions('FROM a METADATA _i/', METADATA_FIELDS.map(attachTriggerCommand)); + testSuggestions( + 'FROM a METADATA _id/', + [ + { filterText: '_id', text: '_id, ' }, + { filterText: '_id', text: '_id | ' }, + ].map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a METADATA _id, /', + METADATA_FIELDS.filter((field) => field !== '_id').map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a METADATA _id, _ignored/', + [ + { filterText: '_ignored', text: '_ignored, ' }, + { filterText: '_ignored', text: '_ignored | ' }, + ].map(attachTriggerCommand) + ); + // comma if there's even one more field + testSuggestions('FROM a METADATA _id, _ignored, _index, _source/', [ + { filterText: '_source', text: '_source | ', command: TRIGGER_SUGGESTION_COMMAND }, + { filterText: '_source', text: '_source, ', command: TRIGGER_SUGGESTION_COMMAND }, + ]); + // no comma if there are no more fields + testSuggestions('FROM a METADATA _id, _ignored, _index, _source, _version/', [ + { filterText: '_version', text: '_version | ', command: TRIGGER_SUGGESTION_COMMAND }, + ]); + }); - // Subsequent fields - testSuggestions( - 'FROM a | KEEP doubleField, dateFiel/', - getFieldNamesByType('any') - .filter((s) => s !== 'doubleField') - .map(attachTriggerCommand) - ); - testSuggestions('FROM a | KEEP doubleField, dateField/', ['dateField, ', 'dateField | ']); + describe('KEEP ', () => { + // KEEP field + testSuggestions('FROM a | KEEP /', getFieldNamesByType('any').map(attachTriggerCommand)); + testSuggestions( + 'FROM a | KEEP d/', + getFieldNamesByType('any') + .map((text) => ({ + text, + rangeToReplace: { start: 15, end: 16 }, + })) + .map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a | KEEP doubleFiel/', + getFieldNamesByType('any').map(attachTriggerCommand) + ); + testSuggestions( + 'FROM a | KEEP doubleField/', + ['doubleField, ', 'doubleField | '] + .map((text) => ({ + text, + filterText: 'doubleField', + rangeToReplace: { start: 15, end: 26 }, + })) + .map(attachTriggerCommand) + ); + testSuggestions('FROM a | KEEP doubleField /', ['| ', ',']); + + // Let's get funky with the field names + testSuggestions( + 'FROM a | KEEP @timestamp/', + ['@timestamp, ', '@timestamp | '] + .map((text) => ({ + text, + filterText: '@timestamp', + rangeToReplace: { start: 15, end: 25 }, + })) + .map(attachTriggerCommand), + undefined, + [[{ name: '@timestamp', type: 'date' }]] + ); + testSuggestions( + 'FROM a | KEEP foo.bar/', + ['foo.bar, ', 'foo.bar | '] + .map((text) => ({ + text, + filterText: 'foo.bar', + rangeToReplace: { start: 15, end: 22 }, + })) + .map(attachTriggerCommand), + undefined, + [[{ name: 'foo.bar', type: 'double' }]] + ); + + describe('escaped field names', () => { + // This isn't actually the behavior we want, but this test is here + // to make sure no weird suggestions start cropping up in this case. + testSuggestions('FROM a | KEEP `foo.bar`/', ['foo.bar'], undefined, [ + [{ name: 'foo.bar', type: 'double' }], + ]); + // @todo re-enable these tests when we can use AST to support this case + testSuggestions.skip('FROM a | KEEP `foo.bar`/', ['foo.bar, ', 'foo.bar | '], undefined, [ + [{ name: 'foo.bar', type: 'double' }], + ]); + testSuggestions.skip( + 'FROM a | KEEP `foo`.`bar`/', + ['foo.bar, ', 'foo.bar | '], + undefined, + [[{ name: 'foo.bar', type: 'double' }]] + ); + testSuggestions.skip('FROM a | KEEP `any#Char$Field`/', [ + '`any#Char$Field`, ', + '`any#Char$Field` | ', + ]); + }); + + // Subsequent fields + testSuggestions( + 'FROM a | KEEP doubleField, dateFiel/', + getFieldNamesByType('any') + .filter((s) => s !== 'doubleField') + .map(attachTriggerCommand) + ); + testSuggestions('FROM a | KEEP doubleField, dateField/', ['dateField, ', 'dateField | ']); + }); }); }); diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts index f80ebf862c0cf..a1be88b0b1436 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/autocomplete.ts @@ -47,6 +47,8 @@ import { noCaseCompare, correctQuerySyntax, getColumnByName, + sourceExists, + findFinalWord, } from '../shared/helpers'; import { collectVariables, excludeVariablesFromCurrentCommand } from '../shared/variables'; import type { ESQLPolicy, ESQLRealField, ESQLVariable, ReferenceMaps } from '../validation/types'; @@ -89,7 +91,7 @@ import { getPolicyHelper, getSourcesHelper, } from '../shared/resources_helpers'; -import { ESQLCallbacks } from '../shared/types'; +import { ESQLCallbacks, ESQLSourceResult } from '../shared/types'; import { getFunctionsToIgnoreForStats, getOverlapRange, @@ -107,12 +109,9 @@ import { isParameterType, isReturnType, } from '../definitions/types'; +import { metadataOption } from '../definitions/options'; import { comparisonFunctions } from '../definitions/builtin'; -type GetSourceFn = () => Promise; -type GetDataStreamsForIntegrationFn = ( - sourceName: string -) => Promise | undefined>; type GetFieldsByTypeFn = ( type: string | string[], ignored?: string[], @@ -178,8 +177,7 @@ export async function suggest( queryForFields, resourceRetriever ); - const getSources = getSourcesRetriever(resourceRetriever); - const getDatastreamsForIntegration = getDatastreamsForIntegrationRetriever(resourceRetriever); + const getSources = getSourcesHelper(resourceRetriever); const { getPolicies, getPolicyMetadata } = getPolicyRetriever(resourceRetriever); if (astContext.type === 'newCommand') { @@ -201,7 +199,6 @@ export async function suggest( ast, astContext, getSources, - getDatastreamsForIntegration, getFieldsByType, getFieldsMap, getPolicies, @@ -287,29 +284,15 @@ function getPolicyRetriever(resourceRetriever?: ESQLCallbacks) { }; } -function getSourcesRetriever(resourceRetriever?: ESQLCallbacks) { - const helper = getSourcesHelper(resourceRetriever); - return async () => { - const list = (await helper()) || []; - // hide indexes that start with . - return buildSourcesDefinitions( - list - .filter(({ hidden }) => !hidden) - .map(({ name, dataStreams, title, type }) => { - return { name, isIntegration: Boolean(dataStreams && dataStreams.length), title, type }; - }) - ); - }; -} - -function getDatastreamsForIntegrationRetriever( - resourceRetriever?: ESQLCallbacks -): GetDataStreamsForIntegrationFn { - const helper = getSourcesHelper(resourceRetriever); - return async (sourceName: string) => { - const list = (await helper()) || []; - return list.find(({ name }) => name === sourceName)?.dataStreams; - }; +function getSourceSuggestions(sources: ESQLSourceResult[]) { + // hide indexes that start with . + return buildSourcesDefinitions( + sources + .filter(({ hidden }) => !hidden) + .map(({ name, dataStreams, title, type }) => { + return { name, isIntegration: Boolean(dataStreams && dataStreams.length), title, type }; + }) + ); } function findNewVariable(variables: Map) { @@ -487,8 +470,7 @@ async function getExpressionSuggestionsByType( option: ESQLCommandOption | undefined; node: ESQLSingleAstItem | undefined; }, - getSources: GetSourceFn, - getDatastreamsForIntegration: GetDataStreamsForIntegrationFn, + getSources: () => Promise, getFieldsByType: GetFieldsByTypeFn, getFieldsMap: GetFieldsMapFn, getPolicies: GetPoliciesFn, @@ -626,13 +608,12 @@ async function getExpressionSuggestionsByType( ); /** - * @TODO — this string manipulation is crude and can't support all cases + * @TODO — this string scanning is crude and can't support all cases * Checking for a partial word and computing the replacement range should * really be done using the AST node, but we'll have to refactor further upstream * to make that available. This is a quick fix to support the most common case. */ - const words = innerText.split(/\s+/); - const lastWord = words[words.length - 1]; + const lastWord = findFinalWord(innerText); if (lastWord !== '') { // ... | @@ -649,16 +630,13 @@ async function getExpressionSuggestionsByType( } // now we know that the user has already entered a column, // so suggest comma and pipe - // const NON_ALPHANUMERIC_REGEXP = /[^a-zA-Z\d]/g; - // const textToUse = lastWord.replace(NON_ALPHANUMERIC_REGEXP, ''); - const textToUse = lastWord; return [ { ...pipeCompleteItem, text: ' | ' }, { ...commaCompleteItem, text: ', ' }, ].map((s) => ({ ...s, - filterText: textToUse, - text: textToUse + s.text, + filterText: lastWord, + text: lastWord + s.text, command: TRIGGER_SUGGESTION_COMMAND, rangeToReplace, })); @@ -912,9 +890,22 @@ async function getExpressionSuggestionsByType( if (argDef.innerTypes?.includes('policy')) { // ... | ENRICH const policies = await getPolicies(); + const lastWord = findFinalWord(innerText); + if (lastWord !== '') { + policies.forEach((suggestion) => { + suggestions.push({ + ...suggestion, + rangeToReplace: { + start: innerText.length - lastWord.length + 1, + end: innerText.length + 1, + }, + }); + }); + } suggestions.push(...(policies.length ? policies : [buildNoPoliciesAvailableDefinition()])); } else { - const index = getSourcesFromCommands(commands, 'index'); + const indexes = getSourcesFromCommands(commands, 'index'); + const lastIndex = indexes[indexes.length - 1]; const canRemoveQuote = isNewExpression && innerText.includes('"'); // Function to add suggestions based on canRemoveQuote const addSuggestionsBasedOnQuote = async (definitions: SuggestionRawDefinition[]) => { @@ -923,24 +914,58 @@ async function getExpressionSuggestionsByType( ); }; - if (index && index.text && index.text !== EDITOR_MARKER) { - const source = index.text.replace(EDITOR_MARKER, ''); - const dataStreams = await getDatastreamsForIntegration(source); + if (lastIndex && lastIndex.text && lastIndex.text !== EDITOR_MARKER) { + const sources = await getSources(); + const sourceIdentifier = lastIndex.text.replace(EDITOR_MARKER, ''); + if (sourceExists(sourceIdentifier, new Set(sources.map(({ name }) => name)))) { + const exactMatch = sources.find(({ name: _name }) => _name === sourceIdentifier); + if (exactMatch?.dataStreams) { + // this is an integration name, suggest the datastreams + addSuggestionsBasedOnQuote( + buildSourcesDefinitions( + exactMatch.dataStreams.map(({ name }) => ({ name, isIntegration: false })) + ) + ); + } else { + // this is a complete source name + const rangeToReplace = { + start: innerText.length - sourceIdentifier.length + 1, + end: innerText.length + 1, + }; - if (dataStreams) { - // Integration name, suggest the datastreams - await addSuggestionsBasedOnQuote( - buildSourcesDefinitions( - dataStreams.map(({ name }) => ({ name, isIntegration: false })) - ) - ); + const suggestionsToAdd: SuggestionRawDefinition[] = [ + { + ...pipeCompleteItem, + filterText: sourceIdentifier, + text: sourceIdentifier + ' | ', + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }, + { + ...commaCompleteItem, + filterText: sourceIdentifier, + text: sourceIdentifier + ', ', + command: TRIGGER_SUGGESTION_COMMAND, + rangeToReplace, + }, + { + ...buildOptionDefinition(metadataOption), + filterText: sourceIdentifier, + text: sourceIdentifier + ' METADATA ', + asSnippet: false, // turn this off because $ could be contained within the source name + rangeToReplace, + }, + ]; + + addSuggestionsBasedOnQuote(suggestionsToAdd); + } } else { - // Not an integration, just a partial source name - await addSuggestionsBasedOnQuote(await getSources()); + // Just a partial source name + await addSuggestionsBasedOnQuote(getSourceSuggestions(sources)); } } else { // FROM or no index/text - await addSuggestionsBasedOnQuote(await getSources()); + await addSuggestionsBasedOnQuote(getSourceSuggestions(await getSources())); } } } @@ -1541,7 +1566,7 @@ async function getOptionArgsSuggestions( // if it's a new expression, suggest fields to match on if ( isNewExpression || - findPreviousWord(innerText) === 'ON' || + noCaseCompare(findPreviousWord(innerText), 'ON') || (option && isAssignment(option.args[0]) && !option.args[1]) ) { const policyName = isSourceItem(command.args[0]) ? command.args[0].name : undefined; @@ -1561,7 +1586,7 @@ async function getOptionArgsSuggestions( suggestions.push( buildOptionDefinition(getCommandOption('with')!), ...getFinalSuggestions({ - comma: true, + comma: false, }) ); } @@ -1588,7 +1613,23 @@ async function getOptionArgsSuggestions( if (policyMetadata) { if (isNewExpression || (assignFn && !isAssignmentComplete(assignFn))) { // ... | ENRICH ... WITH a = - suggestions.push(...buildFieldsDefinitions(policyMetadata.enrichFields)); + // ... | ENRICH ... WITH b + const fieldSuggestions = buildFieldsDefinitions(policyMetadata.enrichFields); + // in this case, we don't want to open the suggestions menu when the field is accepted + // because we're keeping the suggestions simple here for now. Could always revisit. + fieldSuggestions.forEach((s) => (s.command = undefined)); + + // attach the replacement range if needed + const lastWord = findFinalWord(innerText); + if (lastWord) { + // ENRICH ... WITH a + const rangeToReplace = { + start: innerText.length - lastWord.length + 1, + end: innerText.length + 1, + }; + fieldSuggestions.forEach((s) => (s.rangeToReplace = rangeToReplace)); + } + suggestions.push(...fieldSuggestions); } } @@ -1640,13 +1681,41 @@ async function getOptionArgsSuggestions( if (option.name === 'metadata') { const existingFields = new Set(option.args.filter(isColumnItem).map(({ name }) => name)); const filteredMetaFields = METADATA_FIELDS.filter((name) => !existingFields.has(name)); - if (isNewExpression) { + const lastWord = findFinalWord(innerText); + if (lastWord) { + // METADATA something + const isField = METADATA_FIELDS.includes(lastWord); + if (isField) { + // METADATA field + suggestions.push({ + ...pipeCompleteItem, + text: lastWord + ' | ', + filterText: lastWord, + command: TRIGGER_SUGGESTION_COMMAND, + }); + if (filteredMetaFields.length > 1) { + suggestions.push({ + ...commaCompleteItem, + text: lastWord + ', ', + filterText: lastWord, + command: TRIGGER_SUGGESTION_COMMAND, + }); + } + } else { + suggestions.push(...buildFieldsDefinitions(filteredMetaFields)); + } + } else if (isNewExpression) { + // METADATA + // METADATA field, suggestions.push(...buildFieldsDefinitions(filteredMetaFields)); - } else if (existingFields.size > 0) { - if (filteredMetaFields.length > 0) { - suggestions.push(commaCompleteItem); + } else { + if (existingFields.size > 0) { + // METADATA field + if (filteredMetaFields.length > 0) { + suggestions.push(commaCompleteItem); + } + suggestions.push(pipeCompleteItem); } - suggestions.push(pipeCompleteItem); } } diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts index d085588c934e7..b33d705711f05 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/factories.ts @@ -175,6 +175,7 @@ export const buildFieldsDefinitions = (fields: string[]): SuggestionRawDefinitio defaultMessage: `Field specified by the input table`, }), sortText: 'D', + command: TRIGGER_SUGGESTION_COMMAND, })); }; export const buildVariablesDefinitions = (variables: string[]): SuggestionRawDefinition[] => @@ -196,7 +197,7 @@ export const buildSourcesDefinitions = ( ): SuggestionRawDefinition[] => sources.map(({ name, isIntegration, title, type }) => ({ label: title ?? name, - text: getSafeInsertSourceText(name) + (!isIntegration ? ' ' : ''), + text: getSafeInsertSourceText(name), isSnippet: isIntegration, kind: isIntegration ? 'Class' : 'Issue', detail: isIntegration @@ -272,7 +273,7 @@ export const buildPoliciesDefinitions = ( ): SuggestionRawDefinition[] => policies.map(({ name: label, sourceIndices }) => ({ label, - text: getSafeInsertText(label, { dashSupported: true }), + text: getSafeInsertText(label, { dashSupported: true }) + ' ', kind: 'Class', detail: i18n.translate('kbn-esql-validation-autocomplete.esql.autocomplete.policyDefinition', { defaultMessage: `Policy defined on {count, plural, one {index} other {indices}}: {indices}`, @@ -282,6 +283,7 @@ export const buildPoliciesDefinitions = ( }, }), sortText: 'D', + command: TRIGGER_SUGGESTION_COMMAND, })); export const buildMatchingFieldsDefinition = ( @@ -290,7 +292,7 @@ export const buildMatchingFieldsDefinition = ( ): SuggestionRawDefinition[] => fields.map((label) => ({ label, - text: getSafeInsertText(label), + text: getSafeInsertText(label) + ' ', kind: 'Variable', detail: i18n.translate( 'kbn-esql-validation-autocomplete.esql.autocomplete.matchingFieldDefinition', @@ -302,6 +304,7 @@ export const buildMatchingFieldsDefinition = ( } ), sortText: 'D', + command: TRIGGER_SUGGESTION_COMMAND, })); export const buildOptionDefinition = ( diff --git a/packages/kbn-esql-validation-autocomplete/src/autocomplete/helper.ts b/packages/kbn-esql-validation-autocomplete/src/autocomplete/helper.ts index deba0b045563d..f42d7de5a38ab 100644 --- a/packages/kbn-esql-validation-autocomplete/src/autocomplete/helper.ts +++ b/packages/kbn-esql-validation-autocomplete/src/autocomplete/helper.ts @@ -94,9 +94,7 @@ export function getQueryForFields(queryString: string, commands: ESQLCommand[]) export function getSourcesFromCommands(commands: ESQLCommand[], sourceType: 'index' | 'policy') { const fromCommand = commands.find(({ name }) => name === 'from'); const args = (fromCommand?.args ?? []) as ESQLSource[]; - const sources = args.filter((arg) => arg.sourceType === sourceType); - - return sources.length === 1 ? sources[0] : undefined; + return args.filter((arg) => arg.sourceType === sourceType); } export function removeQuoteForSuggestedSources(suggestions: SuggestionRawDefinition[]) { diff --git a/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts b/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts index eb51bfa79227b..d58101e9ff8eb 100644 --- a/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts +++ b/packages/kbn-esql-validation-autocomplete/src/shared/helpers.ts @@ -640,6 +640,16 @@ export function findPreviousWord(text: string) { return words[words.length - 2]; } +/** + * Returns the word at the end of the text if there is one. + * @param text + * @returns + */ +export function findFinalWord(text: string) { + const words = text.split(/\s+/); + return words[words.length - 1]; +} + export function shouldBeQuotedSource(text: string) { // Based on lexer `fragment UNQUOTED_SOURCE_PART` return /[:"=|,[\]\/ \t\r\n]/.test(text); diff --git a/packages/kbn-esql-validation-autocomplete/src/shared/types.ts b/packages/kbn-esql-validation-autocomplete/src/shared/types.ts index 45f1fc0e9311d..d27b84dc4cb27 100644 --- a/packages/kbn-esql-validation-autocomplete/src/shared/types.ts +++ b/packages/kbn-esql-validation-autocomplete/src/shared/types.ts @@ -13,17 +13,16 @@ import type { ESQLRealField } from '../validation/types'; type CallbackFn = (ctx?: Options) => Result[] | Promise; /** @public **/ +export interface ESQLSourceResult { + name: string; + hidden: boolean; + title?: string; + dataStreams?: Array<{ name: string; title?: string }>; + type?: string; +} + export interface ESQLCallbacks { - getSources?: CallbackFn< - {}, - { - name: string; - hidden: boolean; - title?: string; - dataStreams?: Array<{ name: string; title?: string }>; - type?: string; - } - >; + getSources?: CallbackFn<{}, ESQLSourceResult>; getFieldsFor?: CallbackFn<{ query: string }, ESQLRealField>; getPolicies?: CallbackFn< {}, From 1f673dc9f12e90a6aa41a903fee8b0adafcdcaf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Mon, 16 Sep 2024 10:10:36 -0400 Subject: [PATCH 022/139] Consistent scheduling when tasks run within the poll interval of their original time (#190093) Resolves https://github.com/elastic/kibana/issues/189114 In this PR, I'm changing the logic to calculate the task's next run at. Whenever the gap between the task's runAt and when it was picked up is less than the poll interval, we'll use the `runAt` to schedule the next. This way we don't continuously add time to the task's next run (ex: running every 1m turns into every 1m 3s). I've had to modify a few tests to have a more increased interval because this made tasks run more frequently (on time), which introduced flakiness. ## To verify 1. Create an alerting rule that runs every 10s 2. Apply the following diff to your code ``` diff --git a/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts b/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts index 55d5f85e5d3..4342dcdd845 100644 --- a/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts +++ b/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts @@ -31,5 +31,7 @@ export function getNextRunAt( Date.now() ); + console.log(`*** Next run at: ${new Date(nextCalculatedRunAt).toISOString()}, interval=${newSchedule?.interval ?? schedule.interval}, originalRunAt=${originalRunAt.toISOString()}, startedAt=${startedAt.toISOString()}`); + return new Date(nextCalculatedRunAt); } ``` 3. Observe the logs, the gap between runAt and startedAt should be less than the poll interval, so the next run at is based on `runAt` instead of `startedAt`. 4. Stop Kibana for 15 seconds then start it again 5. Observe the first logs when the rule runs again and notice now that the gap between runAt and startedAt is larger than the poll interval, the next run at is based on `startedAt` instead of `runAt` to spread the tasks out evenly. --------- Co-authored-by: Elastic Machine --- .../task_manager/server/config.mock.ts | 17 ++++++ .../server/lib/get_next_run_at.test.ts | 58 +++++++++++++++++++ .../server/lib/get_next_run_at.ts | 25 ++++++++ .../task_manager/server/polling_lifecycle.ts | 5 +- .../server/task_running/task_runner.test.ts | 26 +++++++-- .../server/task_running/task_runner.ts | 38 ++++++++---- .../alerting/group1/get_action_error_log.ts | 2 +- .../builtin_alert_types/es_query/common.ts | 2 +- .../builtin_alert_types/es_query/esql_only.ts | 12 ++-- .../builtin_alert_types/es_query/rule.ts | 24 ++++---- 10 files changed, 173 insertions(+), 36 deletions(-) create mode 100644 x-pack/plugins/task_manager/server/config.mock.ts create mode 100644 x-pack/plugins/task_manager/server/lib/get_next_run_at.test.ts create mode 100644 x-pack/plugins/task_manager/server/lib/get_next_run_at.ts diff --git a/x-pack/plugins/task_manager/server/config.mock.ts b/x-pack/plugins/task_manager/server/config.mock.ts new file mode 100644 index 0000000000000..513dea71d39dd --- /dev/null +++ b/x-pack/plugins/task_manager/server/config.mock.ts @@ -0,0 +1,17 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { type TaskManagerConfig, configSchema } from './config'; + +const createConfigMock = (overwrites: Partial = {}) => { + const mocked: TaskManagerConfig = configSchema.validate(overwrites); + return mocked; +}; + +export const configMock = { + create: createConfigMock, +}; diff --git a/x-pack/plugins/task_manager/server/lib/get_next_run_at.test.ts b/x-pack/plugins/task_manager/server/lib/get_next_run_at.test.ts new file mode 100644 index 0000000000000..efa7cf90ae15f --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/get_next_run_at.test.ts @@ -0,0 +1,58 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { taskManagerMock } from '../mocks'; + +import { getNextRunAt } from './get_next_run_at'; + +describe('getNextRunAt', () => { + test('should use startedAt when the task delay is greater than the threshold', () => { + const now = new Date(); + // Use time in the past to ensure the task delay calculation isn't relative to "now" + const fiveSecondsAgo = new Date(now.getTime() - 5000); + const fourSecondsAgo = new Date(now.getTime() - 4000); + const nextRunAt = getNextRunAt( + taskManagerMock.createTask({ + schedule: { interval: '1m' }, + runAt: fiveSecondsAgo, + startedAt: fourSecondsAgo, + }), + 500 + ); + expect(nextRunAt).toEqual(new Date(fourSecondsAgo.getTime() + 60000)); + }); + + test('should use runAt when the task delay is greater than the threshold', () => { + const now = new Date(); + // Use time in the past to ensure the task delay calculation isn't relative to "now" + const fiveSecondsAgo = new Date(now.getTime() - 5000); + const aBitLessThanFiveSecondsAgo = new Date(now.getTime() - 4995); + const nextRunAt = getNextRunAt( + taskManagerMock.createTask({ + schedule: { interval: '1m' }, + runAt: fiveSecondsAgo, + startedAt: aBitLessThanFiveSecondsAgo, + }), + 500 + ); + expect(nextRunAt).toEqual(new Date(fiveSecondsAgo.getTime() + 60000)); + }); + + test('should not schedule in the past', () => { + const testStart = new Date(); + const fiveMinsAgo = new Date(Date.now() - 300000); + const nextRunAt = getNextRunAt( + taskManagerMock.createTask({ + schedule: { interval: '1m' }, + runAt: fiveMinsAgo, + startedAt: fiveMinsAgo, + }), + 0 + ); + expect(nextRunAt.getTime()).toBeGreaterThanOrEqual(testStart.getTime()); + }); +}); diff --git a/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts b/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts new file mode 100644 index 0000000000000..a25960e61ee29 --- /dev/null +++ b/x-pack/plugins/task_manager/server/lib/get_next_run_at.ts @@ -0,0 +1,25 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { intervalFromDate } from './intervals'; +import type { ConcreteTaskInstance } from '../task'; + +export function getNextRunAt( + { runAt, startedAt, schedule }: Pick, + taskDelayThresholdForPreciseScheduling: number = 0 +): Date { + const taskDelay = startedAt!.getTime() - runAt.getTime(); + const scheduleFromDate = taskDelay < taskDelayThresholdForPreciseScheduling ? runAt : startedAt!; + + // Ensure we also don't schedule in the past by performing the Math.max with Date.now() + const nextCalculatedRunAt = Math.max( + intervalFromDate(scheduleFromDate, schedule!.interval)!.getTime(), + Date.now() + ); + + return new Date(nextCalculatedRunAt); +} diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.ts index b8d41391f1411..81a65009391f6 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.ts @@ -84,6 +84,7 @@ export class TaskPollingLifecycle implements ITaskEventEmitter; private logger: Logger; public pool: TaskPool; @@ -122,6 +123,7 @@ export class TaskPollingLifecycle implements ITaskEventEmitter this.events$.next(event); @@ -220,9 +222,10 @@ export class TaskPollingLifecycle implements ITaskEventEmitter secondsFromNow(mins * 60); +const getNextRunAtSpy = jest.spyOn(nextRunAtUtils, 'getNextRunAt'); let fakeTimer: sinon.SinonFakeTimers; @@ -977,6 +981,8 @@ describe('TaskManagerRunner', () => { expect(instance.params).toEqual({ a: 'b' }); expect(instance.state).toEqual({ hey: 'there' }); expect(instance.enabled).not.toBeDefined(); + + expect(getNextRunAtSpy).not.toHaveBeenCalled(); }); test('reschedules tasks that have an schedule', async () => { @@ -1007,6 +1013,8 @@ describe('TaskManagerRunner', () => { expect(instance.runAt.getTime()).toBeGreaterThan(minutesFromNow(9).getTime()); expect(instance.runAt.getTime()).toBeLessThanOrEqual(minutesFromNow(10).getTime()); expect(instance.enabled).not.toBeDefined(); + + expect(getNextRunAtSpy).toHaveBeenCalled(); }); test('expiration returns time after which timeout will have elapsed from start', async () => { @@ -1084,6 +1092,8 @@ describe('TaskManagerRunner', () => { expect(store.update).toHaveBeenCalledWith(expect.objectContaining({ runAt }), { validate: true, }); + + expect(getNextRunAtSpy).not.toHaveBeenCalled(); }); test('reschedules tasks that return a schedule', async () => { @@ -1114,6 +1124,11 @@ describe('TaskManagerRunner', () => { expect(store.update).toHaveBeenCalledWith(expect.objectContaining({ runAt }), { validate: true, }); + + expect(getNextRunAtSpy).toHaveBeenCalledWith( + expect.objectContaining({ schedule }), + expect.any(Number) + ); }); test(`doesn't reschedule recurring tasks that throw an unrecoverable error`, async () => { @@ -2479,12 +2494,15 @@ describe('TaskManagerRunner', () => { onTaskEvent: opts.onTaskEvent, executionContext, usageCounter, - eventLoopDelayConfig: { - monitor: true, - warn_threshold: 5000, - }, + config: configMock.create({ + event_loop_delay: { + monitor: true, + warn_threshold: 5000, + }, + }), allowReadingInvalidState: opts.allowReadingInvalidState || false, strategy: opts.strategy ?? CLAIM_STRATEGY_UPDATE_BY_QUERY, + pollIntervalConfiguration$: new BehaviorSubject(500), }); if (stage === TaskRunningStage.READY_TO_RUN) { diff --git a/x-pack/plugins/task_manager/server/task_running/task_runner.ts b/x-pack/plugins/task_manager/server/task_running/task_runner.ts index b92c363a7972c..32b48c5caf58b 100644 --- a/x-pack/plugins/task_manager/server/task_running/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_running/task_runner.ts @@ -11,6 +11,7 @@ * rescheduling, middleware application, etc. */ +import { Observable } from 'rxjs'; import apm from 'elastic-apm-node'; import { v4 as uuidv4 } from 'uuid'; import { withSpan } from '@kbn/apm-utils'; @@ -55,9 +56,10 @@ import { } from '../task'; import { TaskTypeDictionary } from '../task_type_dictionary'; import { isUnrecoverableError } from './errors'; -import { CLAIM_STRATEGY_MGET, type EventLoopDelayConfig } from '../config'; +import { CLAIM_STRATEGY_MGET, type TaskManagerConfig } from '../config'; import { TaskValidator } from '../task_validator'; import { getRetryAt, getRetryDate, getTimeout } from '../lib/get_retry_at'; +import { getNextRunAt } from '../lib/get_next_run_at'; export const EMPTY_RUN_RESULT: SuccessfulRunResult = { state: {} }; @@ -108,9 +110,10 @@ type Opts = { defaultMaxAttempts: number; executionContext: ExecutionContextStart; usageCounter?: UsageCounter; - eventLoopDelayConfig: EventLoopDelayConfig; + config: TaskManagerConfig; allowReadingInvalidState: boolean; strategy: string; + pollIntervalConfiguration$: Observable; } & Pick; export enum TaskRunResult { @@ -160,9 +163,10 @@ export class TaskManagerRunner implements TaskRunner { private uuid: string; private readonly executionContext: ExecutionContextStart; private usageCounter?: UsageCounter; - private eventLoopDelayConfig: EventLoopDelayConfig; + private config: TaskManagerConfig; private readonly taskValidator: TaskValidator; private readonly claimStrategy: string; + private currentPollInterval: number; /** * Creates an instance of TaskManagerRunner. @@ -185,9 +189,10 @@ export class TaskManagerRunner implements TaskRunner { onTaskEvent = identity, executionContext, usageCounter, - eventLoopDelayConfig, + config, allowReadingInvalidState, strategy, + pollIntervalConfiguration$, }: Opts) { this.instance = asPending(sanitizeInstance(instance)); this.definitions = definitions; @@ -200,13 +205,17 @@ export class TaskManagerRunner implements TaskRunner { this.executionContext = executionContext; this.usageCounter = usageCounter; this.uuid = uuidv4(); - this.eventLoopDelayConfig = eventLoopDelayConfig; + this.config = config; this.taskValidator = new TaskValidator({ logger: this.logger, definitions: this.definitions, allowReadingInvalidState, }); this.claimStrategy = strategy; + this.currentPollInterval = config.poll_interval; + pollIntervalConfiguration$.subscribe((pollInterval) => { + this.currentPollInterval = pollInterval; + }); } /** @@ -335,7 +344,7 @@ export class TaskManagerRunner implements TaskRunner { const apmTrans = apm.startTransaction(this.taskType, TASK_MANAGER_RUN_TRANSACTION_TYPE, { childOf: this.instance.task.traceparent, }); - const stopTaskTimer = startTaskTimerWithEventLoopMonitoring(this.eventLoopDelayConfig); + const stopTaskTimer = startTaskTimerWithEventLoopMonitoring(this.config.event_loop_delay); // Validate state const stateValidationResult = this.validateTaskState(this.instance.task); @@ -637,13 +646,20 @@ export class TaskManagerRunner implements TaskRunner { return asOk({ status: TaskStatus.ShouldDelete }); } - const { startedAt, schedule } = this.instance.task; - + const updatedTaskSchedule = reschedule ?? this.instance.task.schedule; return asOk({ runAt: - runAt || intervalFromDate(startedAt!, reschedule?.interval ?? schedule?.interval)!, + runAt || + getNextRunAt( + { + runAt: this.instance.task.runAt, + startedAt: this.instance.task.startedAt, + schedule: updatedTaskSchedule, + }, + this.currentPollInterval + ), state, - schedule: reschedule ?? schedule, + schedule: updatedTaskSchedule, attempts, status: TaskStatus.Idle, }); @@ -791,7 +807,7 @@ export class TaskManagerRunner implements TaskRunner { const { eventLoopBlockMs = 0 } = taskTiming; const taskLabel = `${this.taskType} ${this.instance.task.id}`; - if (eventLoopBlockMs > this.eventLoopDelayConfig.warn_threshold) { + if (eventLoopBlockMs > this.config.event_loop_delay.warn_threshold) { this.logger.warn( `event loop blocked for at least ${eventLoopBlockMs} ms while running task ${taskLabel}`, { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get_action_error_log.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get_action_error_log.ts index dbb8cee8673b8..2a25cf481407e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get_action_error_log.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/get_action_error_log.ts @@ -146,7 +146,7 @@ export default function createGetActionErrorLogTests({ getService }: FtrProvider .send( getTestRuleData({ rule_type_id: 'test.cumulative-firing', - schedule: { interval: '5s' }, + schedule: { interval: '6s' }, actions: [ { id: createdConnector1.id, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts index 26d8c64a30296..a08dba15f77ba 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/common.ts @@ -20,7 +20,7 @@ export const ES_TEST_OUTPUT_INDEX_NAME = `${ES_TEST_INDEX_NAME}-output`; export const ES_TEST_DATA_STREAM_NAME = 'test-data-stream'; export const RULE_INTERVALS_TO_WRITE = 5; -export const RULE_INTERVAL_SECONDS = 4; +export const RULE_INTERVAL_SECONDS = 6; export const RULE_INTERVAL_MILLIS = RULE_INTERVAL_SECONDS * 1000; export const ES_GROUPS_TO_WRITE = 3; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts index 10aaf21a28a07..e748b56bd64cb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/esql_only.ts @@ -82,7 +82,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { }); const docs = await waitForDocs(2); - const messagePattern = /Document count is \d+ in the last 20s. Alert when greater than 0./; + const messagePattern = /Document count is \d+ in the last 30s. Alert when greater than 0./; for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -136,7 +136,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); - const messagePattern = /Document count is \d+ in the last 20s. Alert when greater than 0./; + const messagePattern = /Document count is \d+ in the last 30s. Alert when greater than 0./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); } @@ -156,7 +156,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); - const messagePattern = /Document count is \d+ in the last 20s. Alert when greater than 0./; + const messagePattern = /Document count is \d+ in the last 30s. Alert when greater than 0./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); } @@ -186,7 +186,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(activeTitle).to.be(`rule 'fire then recovers' matched query`); expect(activeValue).to.be('1'); expect(activeMessage).to.match( - /Document count is \d+ in the last 4s. Alert when greater than 0./ + /Document count is \d+ in the last 6s. Alert when greater than 0./ ); await createEsDocumentsInGroups(1, endDate); docs = await waitForDocs(2); @@ -200,7 +200,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(recoveredName).to.be('fire then recovers'); expect(recoveredTitle).to.be(`rule 'fire then recovers' recovered`); expect(recoveredMessage).to.match( - /Document count is \d+ in the last 4s. Alert when greater than 0./ + /Document count is \d+ in the last 6s. Alert when greater than 0./ ); }); @@ -223,7 +223,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { 'from test-data-stream | stats c = count(@timestamp) by host.hostname, host.name, host.id | where c > -1', }); - const messagePattern = /Document count is \d+ in the last 20s. Alert when greater than 0./; + const messagePattern = /Document count is \d+ in the last 30s. Alert when greater than 0./; const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts index d53c985f616f3..5ad588a6924de 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group3/builtin_alert_types/es_query/rule.ts @@ -151,7 +151,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { const docs = await waitForDocs(2); const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + /Document count is \d+.?\d* in the last 30s in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; for (let i = 0; i < docs.length; i++) { const doc = docs[i]; @@ -269,7 +269,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { await initData(); const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + /Document count is \d+.?\d* in the last 30s in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { @@ -391,7 +391,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { await initData(); const messagePattern = - /Document count is \d+.?\d* in the last 20s for group-\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + /Document count is \d+.?\d* in the last 30s for group-\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; const titlePattern = /rule 'always fire' matched query for group group-\d/; const conditionPattern = /Number of matching documents for group "group-\d" is greater than -1/; @@ -478,7 +478,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { await initData(); const messagePattern = - /Document count is \d+.?\d* in the last 20s for group-\d+,\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + /Document count is \d+.?\d* in the last 30s for group-\d+,\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; const titlePattern = /rule 'always fire' matched query for group group-\d+,\d+/; const conditionPattern = /Number of matching documents for group "group-\d+,\d+" is greater than -1/; @@ -608,7 +608,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { const titlePattern = /rule 'always fire' matched query for group group-\d/; expect(title).to.match(titlePattern); const messagePattern = - /Document count is \d+.?\d* in the last 20s for group-\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; + /Document count is \d+.?\d* in the last 30s for group-\d+ in .kibana-alerting-test-data (?:index|data view). Alert when greater than -1./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); @@ -696,7 +696,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). ./; + /Document count is \d+.?\d* in the last 30s in .kibana-alerting-test-data (?:index|data view). ./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); @@ -806,7 +806,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('fires once'); expect(title).to.be(`rule 'fires once' matched query`); const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when greater than or equal to 0./; + /Document count is \d+.?\d* in the last 30s in .kibana-alerting-test-data (?:index|data view). Alert when greater than or equal to 0./; expect(message).to.match(messagePattern); expect(hits).not.to.be.empty(); expect(previousTimestamp).to.be.empty(); @@ -866,7 +866,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(name).to.be('always fire'); expect(title).to.be(`rule 'always fire' matched query`); const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when less than 1./; + /Document count is \d+.?\d* in the last 30s in .kibana-alerting-test-data (?:index|data view). Alert when less than 1./; expect(message).to.match(messagePattern); expect(hits).to.be.empty(); @@ -944,7 +944,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(activeTitle).to.be(`rule 'fire then recovers' matched query`); expect(activeValue).to.be('0'); expect(activeMessage).to.match( - /Document count is \d+.?\d* in the last 4s in .kibana-alerting-test-data (?:index|data view). Alert when less than 1./ + /Document count is \d+.?\d* in the last 6s in .kibana-alerting-test-data (?:index|data view). Alert when less than 1./ ); await createEsDocumentsInGroups(1, endDate); @@ -959,7 +959,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(recoveredName).to.be('fire then recovers'); expect(recoveredTitle).to.be(`rule 'fire then recovers' recovered`); expect(recoveredMessage).to.match( - /Document count is \d+.?\d* in the last 4s in .kibana-alerting-test-data (?:index|data view). Alert when less than 1./ + /Document count is \d+.?\d* in the last 6s in .kibana-alerting-test-data (?:index|data view). Alert when less than 1./ ); }) ); @@ -1044,7 +1044,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { await initData(); const messagePattern = - /Document count is \d+.?\d* in the last 20s in test-data-stream (?:index|data view). Alert when greater than -1./; + /Document count is \d+.?\d* in the last 30s in test-data-stream (?:index|data view). Alert when greater than -1./; const docs = await waitForDocs(2); for (let i = 0; i < docs.length; i++) { @@ -1179,7 +1179,7 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(docs[0]._source.hits.length).greaterThan(0); const messagePattern = - /Document count is \d+.?\d* in the last 20s in .kibana-alerting-test-data (?:index|data view). Alert when greater than 0./; + /Document count is \d+.?\d* in the last 30s in .kibana-alerting-test-data (?:index|data view). Alert when greater than 0./; expect(docs[0]._source.params.message).to.match(messagePattern); expect(docs[1]._source.hits.length).to.be(0); From fd67f2d92ef299e11274c89a7195ed2cf6de1808 Mon Sep 17 00:00:00 2001 From: Bharat Pasupula <123897612+bhapas@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:33:04 +0200 Subject: [PATCH 023/139] [Automatic Import] Change the integrations owner type to community (#193002) ## Summary Currently the integrations created by `Automatic Import` are set to `elastic`. But `community` fits better. Once the custom integrations generated by Automatic Import are moved into upstream `elastic/integrations` repository appropriate owner type can be defined in the contribution PR. Screenshot 2024-09-16 at 14 12 17 - Closes https://github.com/elastic/kibana/issues/192917 ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../server/integration_builder/build_integration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/integration_assistant/server/integration_builder/build_integration.ts b/x-pack/plugins/integration_assistant/server/integration_builder/build_integration.ts index 73113f6bf7b04..0598ee3ba2cca 100644 --- a/x-pack/plugins/integration_assistant/server/integration_builder/build_integration.ts +++ b/x-pack/plugins/integration_assistant/server/integration_builder/build_integration.ts @@ -174,7 +174,7 @@ function createPackageManifestDict( ], owner: { github: package_owner, - type: 'elastic', + type: 'community', }, }; From 8e94a4ba57508f36cf7ec38d52dc141565757a5a Mon Sep 17 00:00:00 2001 From: Tre Date: Mon, 16 Sep 2024 15:40:45 +0100 Subject: [PATCH 024/139] [FTR][ML] Cleanup ML Job Table and JobDetails Services (#191720) ## Summary Services such as `MachineLearningJobExpandedDetailsProvider` and `MachineLearningJobTableProvider` share some responsibility. We need to clarify what goes where, such that the design of the services makes the most sense with respect to where the methods live. - Dropped "class" syntax of job table service, for simple object literal (not super important, but "I was in the neighborhood") - Mv `assertJobRowDetailsCounts` jobTable -> jobExpandedDetails - Mv `clickJobRowCalendarWithAssertion` jobTable -> jobExpandedDetails - Mv `assertJobRowCalendars` jobTable -> jobExpandedDetails - Mv `openAnnotationsTab` jobTable -> jobExpandedDetails - Mv `assertJobListMultiSelectionText` jobExpandedDetails -> jobTable --------- Co-authored-by: Elastic Machine --- .../ml/anomaly_detection_jobs/advanced_job.ts | 4 +- .../categorization_job.ts | 4 +- .../anomaly_detection_jobs/date_nanos_job.ts | 2 +- .../apps/ml/anomaly_detection_jobs/geo_job.ts | 4 +- .../job_expanded_details.ts | 4 +- .../multi_metric_job.ts | 4 +- .../anomaly_detection_jobs/population_job.ts | 4 +- .../saved_search_job.ts | 2 +- .../single_metric_job.ts | 4 +- ...ingle_metric_job_without_datafeed_start.ts | 2 +- .../annotations.ts | 10 +- .../short_tests/settings/calendar_creation.ts | 11 +- .../services/ml/job_expanded_details.ts | 59 ++- .../test/functional/services/ml/job_table.ts | 365 +++++++----------- 14 files changed, 223 insertions(+), 256 deletions(-) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts index ea5d70fcbe069..370580fe604dc 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts @@ -423,7 +423,7 @@ export default function ({ getService }: FtrProviderContext) { ...testData.expected.row, }); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( testData.jobId, { job_id: testData.jobId, @@ -638,7 +638,7 @@ export default function ({ getService }: FtrProviderContext) { ...testData.expected.row, }); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( testData.jobIdClone, { job_id: testData.jobIdClone, diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts index 07929a8f9b6f9..eb3708c129205 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts @@ -228,7 +228,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId, jobGroups)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobId, getExpectedCounts(jobId), getExpectedModelSizeStats(jobId) @@ -343,7 +343,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobIdClone, getExpectedRow(jobIdClone, jobGroupsClone)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobIdClone, getExpectedCounts(jobIdClone), getExpectedModelSizeStats(jobIdClone) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts index e5ffd4c193949..c513e1ee10bdb 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts @@ -298,7 +298,7 @@ export default function ({ getService }: FtrProviderContext) { ...testData.expected.row, }); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( testData.jobId, { job_id: testData.jobId, diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts index a95ba4782c413..f5ed246f939d2 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts @@ -219,7 +219,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId, jobGroups)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobId, getExpectedCounts(jobId), getExpectedModelSizeStats(jobId) @@ -339,7 +339,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobIdClone, getExpectedRow(jobIdClone, jobGroupsClone)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobIdClone, getExpectedCounts(jobIdClone), getExpectedModelSizeStats(jobIdClone) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/job_expanded_details.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/job_expanded_details.ts index e48ca875bb1f2..bddcd564bdd18 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/job_expanded_details.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/job_expanded_details.ts @@ -113,10 +113,10 @@ export default function ({ getService }: FtrProviderContext) { it('multi-selection with one opened job should only present the opened job when job list is filtered by the Opened button', async () => { await ml.jobTable.selectAllJobs(); - await ml.jobExpandedDetails.assertJobListMultiSelectionText('2 jobs selected'); + await ml.jobTable.assertJobListMultiSelectionText('2 jobs selected'); await ml.jobTable.filterByState(QuickFilterButtonTypes.Opened); await ml.jobTable.assertJobsInTable([jobId]); - await ml.jobExpandedDetails.assertJobListMultiSelectionText('1 job selected'); + await ml.jobTable.assertJobListMultiSelectionText('1 job selected'); }); it('multi-selection with one closed job should only present the closed job when job list is filtered by the Closed button', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts index 24f385704bd71..c60c4d21bc92b 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts @@ -244,7 +244,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId, jobGroups)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobId, getExpectedCounts(jobId), getExpectedModelSizeStats(jobId) @@ -376,7 +376,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobIdClone, getExpectedRow(jobIdClone, jobGroupsClone)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobIdClone, getExpectedCounts(jobIdClone), getExpectedModelSizeStats(jobIdClone) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts index 1dd7801fa334c..9ef7aea22bb6b 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts @@ -259,7 +259,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId, jobGroups)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobId, getExpectedCounts(jobId), getExpectedModelSizeStats(jobId) @@ -402,7 +402,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobIdClone, getExpectedRow(jobIdClone, jobGroupsClone)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobIdClone, getExpectedCounts(jobIdClone), getExpectedModelSizeStats(jobIdClone) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts index 414230b0b73a1..342a8a13eebbe 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts @@ -424,7 +424,7 @@ export default function ({ getService }: FtrProviderContext) { ...testData.expected.row, }); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( testData.jobId, { job_id: testData.jobId, diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts index 957ac090e1ade..411b013deb64c 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts @@ -219,7 +219,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId, jobGroups)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobId, getExpectedCounts(jobId), getExpectedModelSizeStats(jobId) @@ -357,7 +357,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobIdClone, getExpectedRow(jobIdClone, jobGroupsClone)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobIdClone, getExpectedCounts(jobIdClone), getExpectedModelSizeStats(jobIdClone) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts index e137f366628e7..89fbd1213e6e8 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts @@ -143,7 +143,7 @@ export default function ({ getService }: FtrProviderContext) { ); await ml.jobTable.assertJobRowFields(jobId, getExpectedRow(jobId)); - await ml.jobTable.assertJobRowDetailsCounts( + await ml.jobExpandedDetails.assertJobRowDetailsCounts( jobId, getExpectedCounts(jobId), getExpectedModelSizeStats(jobId) diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts index ab1177d2dbc84..acae757510aa4 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts @@ -90,7 +90,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('should display created annotation in job list'); await ml.navigation.navigateToJobManagement(); await ml.jobTable.filterWithSearchString(jobId, 1); - await ml.jobTable.openAnnotationsTab(jobId); + await ml.jobExpandedDetails.openAnnotationsTab(jobId); await ml.jobAnnotations.assertAnnotationExists({ annotation: newText, event: 'user', @@ -124,7 +124,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToJobManagement(); await ml.jobTable.filterWithSearchString(jobId, 1); - await ml.jobTable.openAnnotationsTab(jobId); + await ml.jobExpandedDetails.openAnnotationsTab(jobId); await ml.jobAnnotations.assertAnnotationContentById( annotationId, expectedOriginalAnnotation @@ -177,7 +177,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('should display edited annotation in job list'); await ml.navigation.navigateToJobManagement(); await ml.jobTable.filterWithSearchString(jobId, 1); - await ml.jobTable.openAnnotationsTab(jobId); + await ml.jobExpandedDetails.openAnnotationsTab(jobId); await ml.jobAnnotations.assertAnnotationContentById(annotationId, expectedEditedAnnotation); }); }); @@ -197,7 +197,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToMl(); await ml.navigation.navigateToJobManagement(); await ml.jobTable.filterWithSearchString(jobId, 1); - await ml.jobTable.openAnnotationsTab(jobId); + await ml.jobExpandedDetails.openAnnotationsTab(jobId); await ml.jobAnnotations.openDatafeedChartFlyout(annotationId, jobId); await ml.jobAnnotations.assertDelayedDataChartExists(); @@ -252,7 +252,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('does not show the deleted annotation in job list'); await ml.navigation.navigateToJobManagement(); await ml.jobTable.filterWithSearchString(jobId, 1); - await ml.jobTable.openAnnotationsTab(jobId); + await ml.jobExpandedDetails.openAnnotationsTab(jobId); await ml.jobAnnotations.assertAnnotationsRowMissing(annotationId); }); }); diff --git a/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts b/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts index 15eac59357928..78a15a64ce0bd 100644 --- a/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts +++ b/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts @@ -146,8 +146,11 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToAnomalyDetection(); - await ml.jobTable.assertJobRowCalendars('test_calendar_ad_1', [calendarId]); - await ml.jobTable.clickJobRowCalendarWithAssertion('test_calendar_ad_1', calendarId); + await ml.jobExpandedDetails.assertJobRowCalendars('test_calendar_ad_1', [calendarId]); + await ml.jobExpandedDetails.clickJobRowCalendarWithAssertion( + 'test_calendar_ad_1', + calendarId + ); await ml.testExecution.logTestStep( 'created calendars can be connected to job groups after creation' @@ -161,8 +164,8 @@ export default function ({ getService }: FtrProviderContext) { 'multi-metric', ]); await ml.navigation.navigateToAnomalyDetection(); - await ml.jobTable.assertJobRowCalendars('test_calendar_ad_4', [calendarId]); - await ml.jobTable.assertJobRowCalendars('test_calendar_ad_3', [calendarId], false); + await ml.jobExpandedDetails.assertJobRowCalendars('test_calendar_ad_4', [calendarId]); + await ml.jobExpandedDetails.assertJobRowCalendars('test_calendar_ad_3', [calendarId], false); }); async function assignJobToCalendar( diff --git a/x-pack/test/functional/services/ml/job_expanded_details.ts b/x-pack/test/functional/services/ml/job_expanded_details.ts index d9c82d72eabc4..bf5c7b2c87b5b 100644 --- a/x-pack/test/functional/services/ml/job_expanded_details.ts +++ b/x-pack/test/functional/services/ml/job_expanded_details.ts @@ -21,6 +21,14 @@ export function MachineLearningJobExpandedDetailsProvider( const headerPage = getPageObject('header'); return { + async openAnnotationsTab(jobId: string) { + await retry.tryForTime(10000, async () => { + await jobTable.ensureDetailsOpen(jobId); + await testSubjects.click(jobTable.detailsSelector(jobId, 'mlJobListTab-annotations')); + await testSubjects.existOrFail('mlAnnotationsTable'); + }); + }, + async clickEditAnnotationAction(jobId: string, annotationId: string) { await jobAnnotationsTable.ensureAnnotationsActionsMenuOpen(annotationId); await testSubjects.click('mlAnnotationsActionEdit'); @@ -77,7 +85,7 @@ export function MachineLearningJobExpandedDetailsProvider( const { _id: annotationId }: { _id: string } = annotationsFromApi[0]; await jobTable.ensureDetailsOpen(jobId); - await jobTable.openAnnotationsTab(jobId); + await this.openAnnotationsTab(jobId); await this.clearSearchButton(); await jobAnnotationsTable.ensureAnnotationsActionsMenuOpen(annotationId); await testSubjects.click('mlAnnotationsActionOpenInSingleMetricViewer'); @@ -92,7 +100,7 @@ export function MachineLearningJobExpandedDetailsProvider( await this.assertAnnotationsFromApi(annotationsFromApi); await jobTable.ensureDetailsOpen(jobId); - await jobTable.openAnnotationsTab(jobId); + await this.openAnnotationsTab(jobId); await this.clearSearchButton(); const { _id: annotationId }: { _id: string } = annotationsFromApi[0]; @@ -107,7 +115,7 @@ export function MachineLearningJobExpandedDetailsProvider( await jobTable.ensureDetailsClosed(jobId); await jobTable.withDetailsOpen(jobId, async () => { - await jobTable.openAnnotationsTab(jobId); + await this.openAnnotationsTab(jobId); await this.clearSearchButton(); const visibleText = await testSubjects.getVisibleText( jobTable.detailsSelector(jobId, 'mlAnnotationsColumnAnnotation') @@ -118,7 +126,7 @@ export function MachineLearningJobExpandedDetailsProvider( async assertDataFeedFlyout(jobId: string): Promise { await jobTable.withDetailsOpen(jobId, async () => { - await jobTable.openAnnotationsTab(jobId); + await this.openAnnotationsTab(jobId); await this.clearSearchButton(); await testSubjects.click(jobTable.detailsSelector(jobId, 'euiCollapsedItemActionsButton')); await testSubjects.click('mlAnnotationsActionViewDatafeed'); @@ -162,9 +170,46 @@ export function MachineLearningJobExpandedDetailsProvider( }); }, - async assertJobListMultiSelectionText(expectedMsg: string): Promise { - const visibleText = await testSubjects.getVisibleText('~mlADJobListMultiSelectActionsArea'); - expect(visibleText).to.be(expectedMsg); + async clickJobRowCalendarWithAssertion(jobId: string, calendarId: string): Promise { + await jobTable.ensureDetailsOpen(jobId); + const calendarSelector = `mlJobDetailsCalendar-${calendarId}`; + await testSubjects.existOrFail(calendarSelector, { + timeout: 3_000, + }); + await testSubjects.click(calendarSelector, 3_000); + await testSubjects.existOrFail('mlPageCalendarEdit > mlCalendarFormEdit', { + timeout: 3_000, + }); + const calendarTitleVisibleText = await testSubjects.getVisibleText('mlCalendarTitle'); + expect(calendarTitleVisibleText).to.contain( + calendarId, + `Calendar page title should contain [${calendarId}], got [${calendarTitleVisibleText}]` + ); + }, + + async assertJobRowDetailsCounts( + jobId: string, + expectedCounts: object, + expectedModelSizeStats: object + ) { + const { counts, modelSizeStats } = await jobTable.parseJobCounts(jobId); + + // Only check for expected keys / values, ignore additional properties + // This way the tests stay stable when new properties are added on the ES side + for (const [key, value] of Object.entries(expectedCounts)) { + expect(counts) + .to.have.property(key) + .eql(value, `Expected counts property '${key}' to exist with value '${value}'`); + } + + for (const [key, value] of Object.entries(expectedModelSizeStats)) { + expect(modelSizeStats) + .to.have.property(key) + .eql( + value, + `Expected model size stats property '${key}' to exist with value '${value}')` + ); + } }, }; } diff --git a/x-pack/test/functional/services/ml/job_table.ts b/x-pack/test/functional/services/ml/job_table.ts index 97ce1858bc2f1..bd19a31f62b54 100644 --- a/x-pack/test/functional/services/ml/job_table.ts +++ b/x-pack/test/functional/services/ml/job_table.ts @@ -55,21 +55,21 @@ export function MachineLearningJobTableProvider( const testSubjects = getService('testSubjects'); const retry = getService('retry'); - return new (class MlJobTable { - public async selectAllJobs(): Promise { + return { + async selectAllJobs(): Promise { await testSubjects.click('checkboxSelectAll'); - } + }, - public async assertJobsInTable(expectedJobIds: string[]) { + async assertJobsInTable(expectedJobIds: string[]) { const sortedExpectedIds = expectedJobIds.sort(); const sortedActualJobIds = (await this.parseJobTable()).map((row) => row.id).sort(); expect(sortedActualJobIds).to.eql( sortedExpectedIds, `Expected jobs in table to be [${sortedExpectedIds}], got [${sortedActualJobIds}]` ); - } + }, - public async filterByState(quickFilterButton: QuickFilterButtonTypes): Promise { + async filterByState(quickFilterButton: QuickFilterButtonTypes): Promise { const searchBar: WebElementWrapper = await testSubjects.find('mlJobListSearchBar'); const quickFilter: WebElementWrapper = await searchBar.findByCssSelector( `span[data-text="${quickFilterButton}"]` @@ -86,46 +86,9 @@ export function MachineLearningJobTableProvider( quickFilterButton, `Expected visible text of pressed quick filter button to equal [${quickFilterButton}], but got [${pressedBttnText}]` ); - } + }, - public async clickJobRowCalendarWithAssertion( - jobId: string, - calendarId: string - ): Promise { - await this.ensureDetailsOpen(jobId); - const calendarSelector = `mlJobDetailsCalendar-${calendarId}`; - await testSubjects.existOrFail(calendarSelector, { - timeout: 3_000, - }); - await testSubjects.click(calendarSelector, 3_000); - await testSubjects.existOrFail('mlPageCalendarEdit > mlCalendarFormEdit', { - timeout: 3_000, - }); - const calendarTitleVisibleText = await testSubjects.getVisibleText('mlCalendarTitle'); - expect(calendarTitleVisibleText).to.contain( - calendarId, - `Calendar page title should contain [${calendarId}], got [${calendarTitleVisibleText}]` - ); - } - - public async assertJobRowCalendars( - jobId: string, - expectedCalendars: string[], - checkForExists: boolean = true - ): Promise { - await this.withDetailsOpen(jobId, async function verifyJobRowCalendars(): Promise { - for await (const expectedCalendar of expectedCalendars) { - const calendarSelector = `mlJobDetailsCalendar-${expectedCalendar}`; - await testSubjects[checkForExists ? 'existOrFail' : 'missingOrFail'](calendarSelector, { - timeout: 3_000, - }); - if (checkForExists) - expect(await testSubjects.getVisibleText(calendarSelector)).to.be(expectedCalendar); - } - }); - } - - public async parseJobTable( + async parseJobTable( tableEnvironment: 'mlAnomalyDetection' | 'stackMgmtJobList' = 'mlAnomalyDetection' ) { const table = await testSubjects.find('~mlJobListTable'); @@ -215,9 +178,10 @@ export function MachineLearningJobTableProvider( } return rows; - } + }, - public async parseJobCounts(jobId: string) { + // TODO: Mv this fn over too + async parseJobCounts(jobId: string) { return await this.withDetailsOpen(jobId, async () => { // click counts tab await testSubjects.click(this.detailsSelector(jobId, 'mlJobListTab-counts')); @@ -248,59 +212,51 @@ export function MachineLearningJobTableProvider( modelSizeStats: await parseTable(modelSizeStatsTable), }; }); - } + }, - public rowSelector(jobId: string, subSelector?: string) { + rowSelector(jobId: string, subSelector?: string) { const row = `~mlJobListTable > ~row-${jobId}`; return !subSelector ? row : `${row} > ${subSelector}`; - } + }, - public detailsSelector(jobId: string, subSelector?: string) { + detailsSelector(jobId: string, subSelector?: string) { const row = `~mlJobListTable > ~details-${jobId}`; return !subSelector ? row : `${row} > ${subSelector}`; - } + }, - public async withDetailsOpen(jobId: string, block: () => Promise): Promise { + async withDetailsOpen(jobId: string, block: () => Promise): Promise { await this.ensureDetailsOpen(jobId); try { return await block(); } finally { await this.ensureDetailsClosed(jobId); } - } + }, - public async ensureDetailsOpen(jobId: string) { + async ensureDetailsOpen(jobId: string) { await retry.tryForTime(10000, async () => { if (!(await testSubjects.exists(this.detailsSelector(jobId)))) { await testSubjects.click(this.rowSelector(jobId, 'mlJobListRowDetailsToggle')); await testSubjects.existOrFail(this.detailsSelector(jobId), { timeout: 1000 }); } }); - } + }, - public async ensureDetailsClosed(jobId: string) { + async ensureDetailsClosed(jobId: string) { await retry.tryForTime(10000, async () => { if (await testSubjects.exists(this.detailsSelector(jobId))) { await testSubjects.click(this.rowSelector(jobId, 'mlJobListRowDetailsToggle')); await testSubjects.missingOrFail(this.detailsSelector(jobId), { timeout: 1000 }); } }); - } - - public async openAnnotationsTab(jobId: string) { - await retry.tryForTime(10000, async () => { - await this.ensureDetailsOpen(jobId); - await testSubjects.click(this.detailsSelector(jobId, 'mlJobListTab-annotations')); - await testSubjects.existOrFail('mlAnnotationsTable'); - }); - } + }, - public async waitForRefreshButtonLoaded(buttonTestSubj: string) { + async waitForRefreshButtonLoaded(buttonTestSubj: string) { await testSubjects.existOrFail(`~${buttonTestSubj}`, { timeout: 10 * 1000 }); await testSubjects.existOrFail(`${buttonTestSubj} loaded`, { timeout: 30 * 1000 }); - } + }, - public async refreshJobList( + async refreshJobList( tableEnvironment: 'mlAnomalyDetection' | 'stackMgmtJobList' = 'mlAnomalyDetection' ) { const testSubjStr = @@ -312,14 +268,14 @@ export function MachineLearningJobTableProvider( await testSubjects.click(`~${testSubjStr}`); await this.waitForRefreshButtonLoaded(testSubjStr); await this.waitForJobsToLoad(); - } + }, - public async waitForJobsToLoad() { + async waitForJobsToLoad() { await testSubjects.existOrFail('~mlJobListTable', { timeout: 60 * 1000 }); await testSubjects.existOrFail('mlJobListTable loaded', { timeout: 30 * 1000 }); - } + }, - public async filterWithSearchString( + async filterWithSearchString( filter: string, expectedRowCount: number = 1, tableEnvironment: 'mlAnomalyDetection' | 'stackMgmtJobList' = 'mlAnomalyDetection' @@ -339,9 +295,9 @@ export function MachineLearningJobTableProvider( filteredRows )}')` ); - } + }, - public async assertJobRowFields(jobId: string, expectedRow: object) { + async assertJobRowFields(jobId: string, expectedRow: object) { await retry.tryForTime(5000, async () => { await this.refreshJobList(); const rows = await this.parseJobTable(); @@ -353,46 +309,18 @@ export function MachineLearningJobTableProvider( )}')` ); }); - } + }, - public async assertJobRowJobId(jobId: string) { + async assertJobRowJobId(jobId: string) { await retry.tryForTime(5000, async () => { await this.refreshJobList(); const rows = await this.parseJobTable(); const jobRowMatch = rows.find((row) => row.id === jobId); expect(jobRowMatch).to.not.eql(undefined, `Expected row with job ID ${jobId} to exist`); }); - } + }, - public async assertJobRowDetailsCounts( - jobId: string, - expectedCounts: object, - expectedModelSizeStats: object - ) { - const { counts, modelSizeStats } = await this.parseJobCounts(jobId); - - // Only check for expected keys / values, ignore additional properties - // This way the tests stay stable when new properties are added on the ES side - for (const [key, value] of Object.entries(expectedCounts)) { - expect(counts) - .to.have.property(key) - .eql(value, `Expected counts property '${key}' to exist with value '${value}'`); - } - - for (const [key, value] of Object.entries(expectedModelSizeStats)) { - expect(modelSizeStats) - .to.have.property(key) - .eql( - value, - `Expected model size stats property '${key}' to exist with value '${value}')` - ); - } - } - - public async assertJobActionSingleMetricViewerButtonEnabled( - jobId: string, - expectedValue: boolean - ) { + async assertJobActionSingleMetricViewerButtonEnabled(jobId: string, expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( this.rowSelector(jobId, 'mlOpenJobsInSingleMetricViewerButton') ); @@ -402,12 +330,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionAnomalyExplorerButtonEnabled( - jobId: string, - expectedValue: boolean - ) { + async assertJobActionAnomalyExplorerButtonEnabled(jobId: string, expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( this.rowSelector(jobId, 'mlOpenJobsInAnomalyExplorerButton') ); @@ -417,9 +342,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionsMenuButtonEnabled(jobId: string, expectedValue: boolean) { + async assertJobActionsMenuButtonEnabled(jobId: string, expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( this.rowSelector(jobId, 'euiCollapsedItemActionsButton') ); @@ -429,9 +354,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionStartDatafeedButtonEnabled(jobId: string, expectedValue: boolean) { + async assertJobActionStartDatafeedButtonEnabled(jobId: string, expectedValue: boolean) { await this.ensureJobActionsMenuOpen(jobId); const isEnabled = await testSubjects.isEnabled('mlActionButtonStartDatafeed'); expect(isEnabled).to.eql( @@ -440,9 +365,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionResetJobButtonEnabled(jobId: string, expectedValue: boolean) { + async assertJobActionResetJobButtonEnabled(jobId: string, expectedValue: boolean) { await this.ensureJobActionsMenuOpen(jobId); const isEnabled = await testSubjects.isEnabled('mlActionButtonResetJob'); expect(isEnabled).to.eql( @@ -451,9 +376,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionCloneJobButtonEnabled(jobId: string, expectedValue: boolean) { + async assertJobActionCloneJobButtonEnabled(jobId: string, expectedValue: boolean) { await this.ensureJobActionsMenuOpen(jobId); const isEnabled = await testSubjects.isEnabled('mlActionButtonCloneJob'); expect(isEnabled).to.eql( @@ -462,12 +387,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionViewDatafeedCountsButtonEnabled( - jobId: string, - expectedValue: boolean - ) { + async assertJobActionViewDatafeedCountsButtonEnabled(jobId: string, expectedValue: boolean) { await this.ensureJobActionsMenuOpen(jobId); const isEnabled = await testSubjects.isEnabled('mlActionButtonViewDatafeedChart'); expect(isEnabled).to.eql( @@ -476,9 +398,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionEditJobButtonEnabled(jobId: string, expectedValue: boolean) { + async assertJobActionEditJobButtonEnabled(jobId: string, expectedValue: boolean) { await this.ensureJobActionsMenuOpen(jobId); const isEnabled = await testSubjects.isEnabled('mlActionButtonEditJob'); expect(isEnabled).to.eql( @@ -487,9 +409,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertJobActionDeleteJobButtonEnabled(jobId: string, expectedValue: boolean) { + async assertJobActionDeleteJobButtonEnabled(jobId: string, expectedValue: boolean) { await this.ensureJobActionsMenuOpen(jobId); const isEnabled = await testSubjects.isEnabled('mlActionButtonDeleteJob'); expect(isEnabled).to.eql( @@ -498,51 +420,51 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async ensureJobActionsMenuOpen(jobId: string) { + async ensureJobActionsMenuOpen(jobId: string) { await retry.tryForTime(30 * 1000, async () => { if (!(await testSubjects.exists('mlActionButtonDeleteJob'))) { await testSubjects.click(this.rowSelector(jobId, 'euiCollapsedItemActionsButton')); await testSubjects.existOrFail('mlActionButtonDeleteJob', { timeout: 5000 }); } }); - } + }, - public async clickCloneJobAction(jobId: string) { + async clickCloneJobAction(jobId: string) { await this.ensureJobActionsMenuOpen(jobId); await testSubjects.click('mlActionButtonCloneJob'); await testSubjects.existOrFail('~mlPageJobWizard'); - } + }, - public async clickCloneJobActionWhenNoDataViewExists(jobId: string) { + async clickCloneJobActionWhenNoDataViewExists(jobId: string) { await this.ensureJobActionsMenuOpen(jobId); await testSubjects.click('mlActionButtonCloneJob'); await this.assertNoDataViewForCloneJobWarningToastExist(); - } + }, - public async assertNoDataViewForCloneJobWarningToastExist() { + async assertNoDataViewForCloneJobWarningToastExist() { await testSubjects.existOrFail('mlCloneJobNoDataViewExistsWarningToast', { timeout: 5000 }); - } + }, - public async clickEditJobAction(jobId: string) { + async clickEditJobAction(jobId: string) { await this.ensureJobActionsMenuOpen(jobId); await testSubjects.click('mlActionButtonEditJob'); await testSubjects.existOrFail('mlJobEditFlyout'); - } + }, - public async clickDeleteJobAction(jobId: string) { + async clickDeleteJobAction(jobId: string) { await this.ensureJobActionsMenuOpen(jobId); await testSubjects.click('mlActionButtonDeleteJob'); await testSubjects.existOrFail('mlDeleteJobConfirmModal'); - } + }, - public async confirmDeleteJobModal() { + async confirmDeleteJobModal() { await testSubjects.click('mlDeleteJobConfirmModal > mlDeleteJobConfirmModalButton'); await testSubjects.missingOrFail('mlDeleteJobConfirmModal', { timeout: 30 * 1000 }); - } + }, - public async clickDeleteAnnotationsInDeleteJobModal(checked: boolean) { + async clickDeleteAnnotationsInDeleteJobModal(checked: boolean) { await testSubjects.setEuiSwitch( 'mlDeleteJobConfirmModal > mlDeleteJobConfirmModalDeleteAnnotationsSwitch', checked ? 'check' : 'uncheck' @@ -552,23 +474,23 @@ export function MachineLearningJobTableProvider( ); expect(isChecked).to.eql(checked, `Expected delete annotations switch to be ${checked}`); - } + }, - public async clickOpenJobInSingleMetricViewerButton(jobId: string) { + async clickOpenJobInSingleMetricViewerButton(jobId: string) { await testSubjects.click(this.rowSelector(jobId, 'mlOpenJobsInSingleMetricViewerButton')); await testSubjects.existOrFail('~mlPageSingleMetricViewer'); - } + }, - public async clickOpenJobInAnomalyExplorerButton(jobId: string) { + async clickOpenJobInAnomalyExplorerButton(jobId: string) { await testSubjects.click(this.rowSelector(jobId, 'mlOpenJobsInAnomalyExplorerButton')); await testSubjects.existOrFail('~mlPageAnomalyExplorer'); - } + }, - public async isJobRowSelected(jobId: string): Promise { + async isJobRowSelected(jobId: string): Promise { return await testSubjects.isChecked(this.rowSelector(jobId, `checkboxSelectRow-${jobId}`)); - } + }, - public async assertJobRowSelected(jobId: string, expectedValue: boolean) { + async assertJobRowSelected(jobId: string, expectedValue: boolean) { const isSelected = await this.isJobRowSelected(jobId); expect(isSelected).to.eql( expectedValue, @@ -576,37 +498,37 @@ export function MachineLearningJobTableProvider( expectedValue ? 'selected' : 'deselected' }' (got '${isSelected ? 'selected' : 'deselected'}')` ); - } + }, - public async selectJobRow(jobId: string) { + async selectJobRow(jobId: string) { if ((await this.isJobRowSelected(jobId)) === false) { await testSubjects.click(this.rowSelector(jobId, `checkboxSelectRow-${jobId}`)); } await this.assertJobRowSelected(jobId, true); await this.assertMultiSelectActionsAreaActive(); - } + }, - public async deselectJobRow(jobId: string) { + async deselectJobRow(jobId: string) { if ((await this.isJobRowSelected(jobId)) === true) { await testSubjects.click(this.rowSelector(jobId, `checkboxSelectRow-${jobId}`)); } await this.assertJobRowSelected(jobId, false); await this.assertMultiSelectActionsAreaInactive(); - } + }, - public async assertMultiSelectActionsAreaActive() { + async assertMultiSelectActionsAreaActive() { await testSubjects.existOrFail('mlADJobListMultiSelectActionsArea active'); - } + }, - public async assertMultiSelectActionsAreaInactive() { + async assertMultiSelectActionsAreaInactive() { await testSubjects.existOrFail('mlADJobListMultiSelectActionsArea inactive', { allowHidden: true, }); - } + }, - public async assertMultiSelectActionSingleMetricViewerButtonEnabled(expectedValue: boolean) { + async assertMultiSelectActionSingleMetricViewerButtonEnabled(expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( '~mlADJobListMultiSelectActionsArea > mlOpenJobsInSingleMetricViewerButton' ); @@ -616,9 +538,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertMultiSelectActionAnomalyExplorerButtonEnabled(expectedValue: boolean) { + async assertMultiSelectActionAnomalyExplorerButtonEnabled(expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( '~mlADJobListMultiSelectActionsArea > mlOpenJobsInAnomalyExplorerButton' ); @@ -628,9 +550,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertMultiSelectActionEditJobGroupsButtonEnabled(expectedValue: boolean) { + async assertMultiSelectActionEditJobGroupsButtonEnabled(expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( '~mlADJobListMultiSelectActionsArea > mlADJobListMultiSelectEditJobGroupsButton' ); @@ -640,9 +562,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertMultiSelectManagementActionsButtonEnabled(expectedValue: boolean) { + async assertMultiSelectManagementActionsButtonEnabled(expectedValue: boolean) { const isEnabled = await testSubjects.isEnabled( '~mlADJobListMultiSelectActionsArea > mlADJobListMultiSelectManagementActionsButton' ); @@ -652,9 +574,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertMultiSelectStartDatafeedActionButtonEnabled(expectedValue: boolean) { + async assertMultiSelectStartDatafeedActionButtonEnabled(expectedValue: boolean) { await this.ensureMultiSelectManagementActionsMenuOpen(); const isEnabled = await testSubjects.isEnabled( 'mlADJobListMultiSelectStartDatafeedActionButton' @@ -665,9 +587,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async assertMultiSelectDeleteJobActionButtonEnabled(expectedValue: boolean) { + async assertMultiSelectDeleteJobActionButtonEnabled(expectedValue: boolean) { await this.ensureMultiSelectManagementActionsMenuOpen(); const isEnabled = await testSubjects.isEnabled('mlADJobListMultiSelectDeleteJobActionButton'); expect(isEnabled).to.eql( @@ -676,9 +598,9 @@ export function MachineLearningJobTableProvider( expectedValue ? 'enabled' : 'disabled' }' (got '${isEnabled ? 'enabled' : 'disabled'}')` ); - } + }, - public async ensureMultiSelectManagementActionsMenuOpen() { + async ensureMultiSelectManagementActionsMenuOpen() { await retry.tryForTime(30 * 1000, async () => { if (!(await testSubjects.exists('mlADJobListMultiSelectDeleteJobActionButton'))) { await testSubjects.click('mlADJobListMultiSelectManagementActionsButton'); @@ -687,48 +609,44 @@ export function MachineLearningJobTableProvider( }); } }); - } + }, - public async openEditCustomUrlsForJobTab(jobId: string) { + async openEditCustomUrlsForJobTab(jobId: string) { await this.clickEditJobAction(jobId); // click Custom URLs tab await testSubjects.click('mlEditJobFlyout-customUrls'); await this.ensureEditCustomUrlTabOpen(); await headerPage.waitUntilLoadingHasFinished(); - } + }, - public async ensureEditCustomUrlTabOpen() { + async ensureEditCustomUrlTabOpen() { await testSubjects.existOrFail('mlJobOpenCustomUrlFormButton', { timeout: 5000 }); - } + }, - public async closeEditJobFlyout() { + async closeEditJobFlyout() { if (await testSubjects.exists('mlEditJobFlyoutCloseButton')) { await testSubjects.click('mlEditJobFlyoutCloseButton'); await testSubjects.missingOrFail('mlJobEditFlyout'); } - } + }, - public async saveEditJobFlyoutChanges() { + async saveEditJobFlyoutChanges() { await testSubjects.click('mlEditJobFlyoutSaveButton'); await testSubjects.missingOrFail('mlJobEditFlyout', { timeout: 5000 }); - } + }, - public async clickOpenCustomUrlEditor() { + async clickOpenCustomUrlEditor() { await this.ensureEditCustomUrlTabOpen(); await testSubjects.click('mlJobOpenCustomUrlFormButton'); await testSubjects.existOrFail('mlJobCustomUrlForm'); - } + }, - public async getExistingCustomUrlCount(): Promise { + async getExistingCustomUrlCount(): Promise { const existingCustomUrls = await testSubjects.findAll('mlJobEditCustomUrlItemLabel'); return existingCustomUrls.length; - } + }, - public async saveCustomUrl( - expectedLabel: string, - expectedIndex: number, - expectedValue?: string - ) { + async saveCustomUrl(expectedLabel: string, expectedIndex: number, expectedValue?: string) { await retry.tryForTime(5000, async () => { await testSubjects.click('mlJobAddCustomUrl'); await customUrls.assertCustomUrlLabel(expectedIndex, expectedLabel); @@ -737,9 +655,9 @@ export function MachineLearningJobTableProvider( if (expectedValue !== undefined) { await customUrls.assertCustomUrlUrlValue(expectedIndex, expectedValue); } - } + }, - public async fillInDiscoverUrlForm(customUrl: DiscoverUrlConfig) { + async fillInDiscoverUrlForm(customUrl: DiscoverUrlConfig) { await this.clickOpenCustomUrlEditor(); await customUrls.setCustomUrlLabel(customUrl.label); await mlCommonUI.selectRadioGroupValue( @@ -758,9 +676,9 @@ export function MachineLearningJobTableProvider( if (customUrl.timeRange === TIME_RANGE_TYPE.INTERVAL) { await customUrls.setCustomUrlTimeRangeInterval(customUrl.timeRangeInterval!); } - } + }, - public async fillInDashboardUrlForm(customUrl: DashboardUrlConfig) { + async fillInDashboardUrlForm(customUrl: DashboardUrlConfig) { await this.clickOpenCustomUrlEditor(); await customUrls.setCustomUrlLabel(customUrl.label); await mlCommonUI.selectRadioGroupValue( @@ -779,16 +697,16 @@ export function MachineLearningJobTableProvider( if (customUrl.timeRange === TIME_RANGE_TYPE.INTERVAL) { await customUrls.setCustomUrlTimeRangeInterval(customUrl.timeRangeInterval!); } - } + }, - public async fillInOtherUrlForm(customUrl: OtherUrlConfig) { + async fillInOtherUrlForm(customUrl: OtherUrlConfig) { await this.clickOpenCustomUrlEditor(); await customUrls.setCustomUrlLabel(customUrl.label); await mlCommonUI.selectRadioGroupValue(`mlJobCustomUrlLinkToTypeInput`, URL_TYPE.OTHER); await customUrls.setCustomUrlOtherTypeUrl(customUrl.url); - } + }, - public async addDiscoverCustomUrl(jobId: string, customUrl: DiscoverUrlConfig) { + async addDiscoverCustomUrl(jobId: string, customUrl: DiscoverUrlConfig) { await retry.tryForTime(30 * 1000, async () => { await this.closeEditJobFlyout(); await this.openEditCustomUrlsForJobTab(jobId); @@ -800,9 +718,9 @@ export function MachineLearningJobTableProvider( // Save the job await this.saveEditJobFlyoutChanges(); - } + }, - public async addDashboardCustomUrl( + async addDashboardCustomUrl( jobId: string, customUrl: DashboardUrlConfig, expectedResult: { index: number; url: string } @@ -816,9 +734,9 @@ export function MachineLearningJobTableProvider( // Save the job await this.saveEditJobFlyoutChanges(); - } + }, - public async addOtherTypeCustomUrl(jobId: string, customUrl: OtherUrlConfig) { + async addOtherTypeCustomUrl(jobId: string, customUrl: OtherUrlConfig) { await retry.tryForTime(30 * 1000, async () => { await this.closeEditJobFlyout(); await this.openEditCustomUrlsForJobTab(jobId); @@ -830,9 +748,9 @@ export function MachineLearningJobTableProvider( // Save the job await this.saveEditJobFlyoutChanges(); - } + }, - public async editCustomUrl( + async editCustomUrl( jobId: string, indexInList: number, customUrl: { label: string; url: string } @@ -843,9 +761,9 @@ export function MachineLearningJobTableProvider( // Save the edit await this.saveEditJobFlyoutChanges(); - } + }, - public async deleteCustomUrl(jobId: string, indexInList: number) { + async deleteCustomUrl(jobId: string, indexInList: number) { await this.openEditCustomUrlsForJobTab(jobId); const beforeCustomUrls = await testSubjects.findAll('mlJobEditCustomUrlItemLabel'); await customUrls.deleteCustomUrl(indexInList); @@ -855,30 +773,31 @@ export function MachineLearningJobTableProvider( await this.openEditCustomUrlsForJobTab(jobId); await customUrls.assertCustomUrlsLength(beforeCustomUrls.length - 1); await this.closeEditJobFlyout(); - } + }, - public async openTestCustomUrl(jobId: string, indexInList: number) { + async openTestCustomUrl(jobId: string, indexInList: number) { await this.openEditCustomUrlsForJobTab(jobId); await customUrls.clickTestCustomUrl(indexInList); - } + }, - public async testDiscoverCustomUrlAction(expectedHitCountFormatted: string) { + async testDiscoverCustomUrlAction(expectedHitCountFormatted: string) { await customUrls.assertDiscoverCustomUrlAction(expectedHitCountFormatted); - } + }, - public async testDashboardCustomUrlAction(expectedPanelCount: number) { + async testDashboardCustomUrlAction(expectedPanelCount: number) { await customUrls.assertDashboardCustomUrlAction(expectedPanelCount); - } + }, - public async testOtherTypeCustomUrlAction( - jobId: string, - indexInList: number, - expectedUrl: string - ) { + async testOtherTypeCustomUrlAction(jobId: string, indexInList: number, expectedUrl: string) { // Can't test the contents of the external page, so just check the expected URL. await this.openEditCustomUrlsForJobTab(jobId); await customUrls.assertCustomUrlUrlValue(indexInList, expectedUrl); await this.closeEditJobFlyout(); - } - })(); + }, + + async assertJobListMultiSelectionText(expectedMsg: string): Promise { + const visibleText = await testSubjects.getVisibleText('~mlADJobListMultiSelectActionsArea'); + expect(visibleText).to.be(expectedMsg); + }, + }; } From 9d22e8c6a8d92449055fd99b67b745d1995b5107 Mon Sep 17 00:00:00 2001 From: Tre Date: Mon, 16 Sep 2024 15:42:06 +0100 Subject: [PATCH 025/139] [FTR] Collapse Alerting API Helpers Impl (#192216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Resolves: https://github.com/elastic/kibana/issues/192201 - Expose `TryWithRetriesOptions` - Tune timeouts to pass ci - Add attempt count debug info to `retry/retry_for_success.ts` - Helps with tuning timeout params - Move exposure of `AlertingApiProvider` from `x-pack/test_serverless/api_integration/services/index.ts` -> `x-pack/test_serverless/shared/services/deployment_agnostic_services.ts` - This exposes the alerting api under Deployment Agnostic Services (DA), and DA is exposed within `x-pack/test_serverless/functional/services/index.ts` (Shared Services [Serverless]) - Collapse helper script functions into just another object literal stanza within `AlertingApiProvider` - Update all references - Refactor alerting api to use `retry` service, instead of p-retry (following [this pr](https://github.com/elastic/kibana/pull/178660)) ### Additional debug logging Run in debug mode (add `-v`): ``` node scripts/functional_tests \ --config x-pack/test_serverless/api_integration/test_suites/search/common_configs/config.group1.ts \ --grep "Summary actions" -v ``` #### After ``` │ sill retry.tryWithRetries('Alerting API - waitForDocumentInIndex, retryOptions: {"retryCount":5,"retryDelay":200}', [object AsyncFunction], [object Object]) │ debg --- retry.tryWithRetries error: index_not_found_exception │ Root causes: │ index_not_found_exception: no such index [alert-action-es-query] - Attempt #: 1 │ sill es.search([object Object]) │ debg --- retry.tryWithRetries failed again with the same message... - Attempt #: 2 │ sill es.search([object Object]) │ debg --- retry.tryWithRetries failed again with the same message... - Attempt #: 3 │ sill es.search([object Object]) │ debg --- retry.tryWithRetries failed again with the same message... - Attempt #: 4 │ sill es.search([object Object]) │ debg --- retry.tryWithRetries failed again with the same message... - Attempt #: 5 ... // Msg after all attempts fail: │ Error: retry.tryWithRetries reached the limit of attempts waiting for 'Alerting API - waitForDocumentInIndex, retryOptions: {"retryCount":5,"retryDelay":200}': 5 out of 5 │ ResponseError: index_not_found_exception │ Root causes: │ index_not_found_exception: no such index [alert-action-es-query] │ at SniffingTransport._request (node_modules/@elastic/transport/src/Transport.ts:601:17) │ at processTicksAndRejections (node:internal/process/task_queues:95:5) │ at /Users/trezworkbox/dev/main.worktrees/cleanup-alerting-api/node_modules/@elastic/transport/src/Transport.ts:704:22 │ at SniffingTransport.request (node_modules/@elastic/transport/src/Transport.ts:701:14) │ at Proxy.SearchApi (node_modules/@elastic/elasticsearch/src/api/api/search.ts:96:10) │ at alerting_api.ts:123:28 │ at runAttempt (retry_for_success.ts:30:15) │ at retryForSuccess (retry_for_success.ts:99:21) │ at Proxy.tryWithRetries (retry.ts:113:12) │ at Object.waitForDocumentInIndex (alerting_api.ts:120:14) │ at Context. (summary_actions.ts:146:20) │ at Object.apply (wrap_function.js:74:16) │ at Object.apply (wrap_function.js:74:16) │ at onFailure (retry_for_success.ts:18:9) │ at retryForSuccess (retry_for_success.ts:75:7) │ at Proxy.tryWithRetries (retry.ts:113:12) │ at Object.waitForDocumentInIndex (alerting_api.ts:120:14) │ at Context. (summary_actions.ts:146:20) │ at Object.apply (wrap_function.js:74:16) │ at Object.apply (wrap_function.js:74:16) ``` ### Notes Was put back in draft to additional scope detailed in issue linked above. --------- Co-authored-by: Elastic Machine --- .../index.ts | 2 +- .../services/retry/index.ts | 2 +- .../services/retry/retry.ts | 2 +- .../services/retry/retry_for_success.ts | 10 +- .../api_integration/services/alerting_api.ts | 176 --- .../api_integration/services/index.ts | 2 - .../common/alerting/alert_documents.ts | 35 +- .../alerting/helpers/alerting_api_helper.ts | 478 -------- .../helpers/alerting_wait_for_helpers.ts | 402 ------- .../test_suites/common/alerting/rules.ts | 234 ++-- .../common/alerting/summary_actions.ts | 87 +- .../es_query_rule/es_query_rule.ts | 6 +- .../functional/services/index.ts | 3 +- .../observability/rules/rules_list.ts | 221 ++-- .../test_suites/search/rules/rule_details.ts | 56 +- .../shared/services/alerting_api.ts | 1032 +++++++++++++++++ .../services/deployment_agnostic_services.ts | 3 +- 17 files changed, 1306 insertions(+), 1445 deletions(-) delete mode 100644 x-pack/test_serverless/api_integration/services/alerting_api.ts delete mode 100644 x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_api_helper.ts delete mode 100644 x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_wait_for_helpers.ts create mode 100644 x-pack/test_serverless/shared/services/alerting_api.ts diff --git a/packages/kbn-ftr-common-functional-services/index.ts b/packages/kbn-ftr-common-functional-services/index.ts index e156949f0daf9..506566216c721 100644 --- a/packages/kbn-ftr-common-functional-services/index.ts +++ b/packages/kbn-ftr-common-functional-services/index.ts @@ -14,7 +14,7 @@ import { KibanaServerProvider } from './services/kibana_server'; export { KibanaServerProvider } from './services/kibana_server'; export type KibanaServer = ProvidedType; -export { RetryService } from './services/retry'; +export { RetryService, type TryWithRetriesOptions } from './services/retry'; import { EsArchiverProvider } from './services/es_archiver'; export type EsArchiver = ProvidedType; diff --git a/packages/kbn-ftr-common-functional-services/services/retry/index.ts b/packages/kbn-ftr-common-functional-services/services/retry/index.ts index 6f42e0368364d..f96e413da2680 100644 --- a/packages/kbn-ftr-common-functional-services/services/retry/index.ts +++ b/packages/kbn-ftr-common-functional-services/services/retry/index.ts @@ -7,4 +7,4 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export { RetryService } from './retry'; +export { RetryService, type TryWithRetriesOptions } from './retry'; diff --git a/packages/kbn-ftr-common-functional-services/services/retry/retry.ts b/packages/kbn-ftr-common-functional-services/services/retry/retry.ts index 9ddd13ea583a7..614f57064512c 100644 --- a/packages/kbn-ftr-common-functional-services/services/retry/retry.ts +++ b/packages/kbn-ftr-common-functional-services/services/retry/retry.ts @@ -11,7 +11,7 @@ import { FtrService } from '../ftr_provider_context'; import { retryForSuccess } from './retry_for_success'; import { retryForTruthy } from './retry_for_truthy'; -interface TryWithRetriesOptions { +export interface TryWithRetriesOptions { retryCount: number; retryDelay?: number; timeout?: number; diff --git a/packages/kbn-ftr-common-functional-services/services/retry/retry_for_success.ts b/packages/kbn-ftr-common-functional-services/services/retry/retry_for_success.ts index 5401eb21286d1..921efacd88fcc 100644 --- a/packages/kbn-ftr-common-functional-services/services/retry/retry_for_success.ts +++ b/packages/kbn-ftr-common-functional-services/services/retry/retry_for_success.ts @@ -92,7 +92,7 @@ export async function retryForSuccess(log: ToolingLog, options: Options) { if (lastError && onFailureBlock) { const before = await runAttempt(onFailureBlock); if ('error' in before) { - log.debug(`--- onRetryBlock error: ${before.error.message}`); + log.debug(`--- onRetryBlock error: ${before.error.message} - Attempt #: ${attemptCounter}`); } } @@ -104,9 +104,13 @@ export async function retryForSuccess(log: ToolingLog, options: Options) { if ('error' in attempt) { if (lastError && lastError.message === attempt.error.message) { - log.debug(`--- ${methodName} failed again with the same message...`); + log.debug( + `--- ${methodName} failed again with the same message... - Attempt #: ${attemptCounter}` + ); } else { - log.debug(`--- ${methodName} error: ${attempt.error.message}`); + log.debug( + `--- ${methodName} error: ${attempt.error.message} - Attempt #: ${attemptCounter}` + ); } lastError = attempt.error; diff --git a/x-pack/test_serverless/api_integration/services/alerting_api.ts b/x-pack/test_serverless/api_integration/services/alerting_api.ts deleted file mode 100644 index 6000e9d8bdc88..0000000000000 --- a/x-pack/test_serverless/api_integration/services/alerting_api.ts +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { - AggregationsAggregate, - SearchResponse, -} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; - -import { MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics'; -import { ThresholdParams } from '@kbn/observability-plugin/common/custom_threshold_rule/types'; -import { RoleCredentials } from '../../shared/services'; -import { SloBurnRateRuleParams } from './slo_api'; -import { FtrProviderContext } from '../ftr_provider_context'; - -export function AlertingApiProvider({ getService }: FtrProviderContext) { - const retry = getService('retry'); - const es = getService('es'); - const requestTimeout = 30 * 1000; - const retryTimeout = 120 * 1000; - const logger = getService('log'); - const svlCommonApi = getService('svlCommonApi'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); - - return { - async waitForRuleStatus({ - roleAuthc, - ruleId, - expectedStatus, - }: { - roleAuthc: RoleCredentials; - ruleId: string; - expectedStatus: string; - }) { - if (!ruleId) { - throw new Error(`'ruleId' is undefined`); - } - return await retry.tryForTime(retryTimeout, async () => { - const response = await supertestWithoutAuth - .get(`/api/alerting/rule/${ruleId}`) - .set(svlCommonApi.getInternalRequestHeader()) - .set(roleAuthc.apiKeyHeader) - .timeout(requestTimeout); - const { execution_status: executionStatus } = response.body || {}; - const { status } = executionStatus || {}; - if (status !== expectedStatus) { - throw new Error(`waitForStatus(${expectedStatus}): got ${status}`); - } - return executionStatus?.status; - }); - }, - - async waitForDocumentInIndex({ - indexName, - docCountTarget = 1, - }: { - indexName: string; - docCountTarget?: number; - }): Promise>> { - return await retry.tryForTime(retryTimeout, async () => { - const response = await es.search({ - index: indexName, - rest_total_hits_as_int: true, - }); - logger.debug(`Found ${response.hits.total} docs, looking for atleast ${docCountTarget}.`); - if (!response.hits.total || (response.hits.total as number) < docCountTarget) { - throw new Error('No hits found'); - } - return response; - }); - }, - - async waitForAlertInIndex({ - indexName, - ruleId, - }: { - indexName: string; - ruleId: string; - }): Promise>> { - if (!ruleId) { - throw new Error(`'ruleId' is undefined`); - } - return await retry.tryForTime(retryTimeout, async () => { - const response = await es.search({ - index: indexName, - body: { - query: { - term: { - 'kibana.alert.rule.uuid': ruleId, - }, - }, - }, - }); - if (response.hits.hits.length === 0) { - throw new Error('No hits found'); - } - return response; - }); - }, - - async createIndexConnector({ - roleAuthc, - name, - indexName, - }: { - roleAuthc: RoleCredentials; - name: string; - indexName: string; - }) { - const { body } = await supertestWithoutAuth - .post(`/api/actions/connector`) - .set(svlCommonApi.getInternalRequestHeader()) - .set(roleAuthc.apiKeyHeader) - .send({ - name, - config: { - index: indexName, - refresh: true, - }, - connector_type_id: '.index', - }); - return body.id as string; - }, - - async createRule({ - roleAuthc, - name, - ruleTypeId, - params, - actions = [], - tags = [], - schedule, - consumer, - }: { - roleAuthc: RoleCredentials; - ruleTypeId: string; - name: string; - params: MetricThresholdParams | ThresholdParams | SloBurnRateRuleParams; - actions?: any[]; - tags?: any[]; - schedule?: { interval: string }; - consumer: string; - }) { - const { body } = await supertestWithoutAuth - .post(`/api/alerting/rule`) - .set(svlCommonApi.getInternalRequestHeader()) - .set(roleAuthc.apiKeyHeader) - .send({ - params, - consumer, - schedule: schedule || { - interval: '5m', - }, - tags, - name, - rule_type_id: ruleTypeId, - actions, - }); - return body; - }, - - async findRule(roleAuthc: RoleCredentials, ruleId: string) { - if (!ruleId) { - throw new Error(`'ruleId' is undefined`); - } - const response = await supertestWithoutAuth - .get('/api/alerting/rules/_find') - .set(svlCommonApi.getInternalRequestHeader()) - .set(roleAuthc.apiKeyHeader); - return response.body.data.find((obj: any) => obj.id === ruleId); - }, - }; -} diff --git a/x-pack/test_serverless/api_integration/services/index.ts b/x-pack/test_serverless/api_integration/services/index.ts index 347fc1f68b0ca..22ce9b3bb4794 100644 --- a/x-pack/test_serverless/api_integration/services/index.ts +++ b/x-pack/test_serverless/api_integration/services/index.ts @@ -9,7 +9,6 @@ import { GenericFtrProviderContext } from '@kbn/test'; import { services as deploymentAgnosticSharedServices } from '../../shared/services/deployment_agnostic_services'; import { services as svlSharedServices } from '../../shared/services'; -import { AlertingApiProvider } from './alerting_api'; import { SamlToolsProvider } from './saml_tools'; import { SvlCasesServiceProvider } from './svl_cases'; import { SloApiProvider } from './slo_api'; @@ -35,7 +34,6 @@ export const services = { // serverless FTR services ...svlSharedServices, - alertingApi: AlertingApiProvider, samlTools: SamlToolsProvider, svlCases: SvlCasesServiceProvider, sloApi: SloApiProvider, diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts index 93dd4e5565db5..cf727fd9fd1bc 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/alert_documents.ts @@ -42,22 +42,18 @@ import { ALERT_PREVIOUS_ACTION_GROUP, } from '@kbn/rule-data-utils'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { createEsQueryRule } from './helpers/alerting_api_helper'; -import { waitForAlertInIndex, waitForNumRuleRuns } from './helpers/alerting_wait_for_helpers'; import { ObjectRemover } from '../../../../shared/lib'; -import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; +import { RoleCredentials } from '../../../../shared/services'; const OPEN_OR_ACTIVE = new Set(['open', 'active']); export default function ({ getService }: FtrProviderContext) { - const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); let roleAdmin: RoleCredentials; - let internalReqHeader: InternalRequestHeader; const supertest = getService('supertest'); const esClient = getService('es'); const objectRemover = new ObjectRemover(supertest); + const alertingApi = getService('alertingApi'); describe('Alert documents', function () { // Timeout of 360000ms exceeded @@ -68,7 +64,6 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAdmin = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); - internalReqHeader = svlCommonApi.getInternalRequestHeader(); }); afterEach(async () => { @@ -80,10 +75,8 @@ export default function ({ getService }: FtrProviderContext) { }); it('should generate an alert document for an active alert', async () => { - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -103,17 +96,15 @@ export default function ({ getService }: FtrProviderContext) { // get the first alert document written const testStart1 = new Date(); - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 1, ruleId, esClient, testStart: testStart1, }); - const alResp1 = await waitForAlertInIndex({ + const alResp1 = await alertingApi.helpers.waitForAlertInIndex({ esClient, filter: testStart1, indexName: ALERT_INDEX, @@ -206,10 +197,8 @@ export default function ({ getService }: FtrProviderContext) { }); it('should update an alert document for an ongoing alert', async () => { - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -229,17 +218,15 @@ export default function ({ getService }: FtrProviderContext) { // get the first alert document written const testStart1 = new Date(); - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 1, ruleId, esClient, testStart: testStart1, }); - const alResp1 = await waitForAlertInIndex({ + const alResp1 = await alertingApi.helpers.waitForAlertInIndex({ esClient, filter: testStart1, indexName: ALERT_INDEX, @@ -249,17 +236,15 @@ export default function ({ getService }: FtrProviderContext) { // wait for another run, get the updated alert document const testStart2 = new Date(); - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 1, ruleId, esClient, testStart: testStart2, }); - const alResp2 = await waitForAlertInIndex({ + const alResp2 = await alertingApi.helpers.waitForAlertInIndex({ esClient, filter: testStart2, indexName: ALERT_INDEX, diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_api_helper.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_api_helper.ts deleted file mode 100644 index f7a909c688d0e..0000000000000 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_api_helper.ts +++ /dev/null @@ -1,478 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import moment from 'moment'; -import { v4 as uuidv4 } from 'uuid'; -import type { Agent as SuperTestAgent } from 'supertest'; -import { - InternalRequestHeader, - RoleCredentials, - SupertestWithoutAuthProviderType, -} from '../../../../../shared/services'; - -interface CreateEsQueryRuleParams { - size: number; - thresholdComparator: string; - threshold: number[]; - timeWindowSize?: number; - timeWindowUnit?: string; - esQuery?: string; - timeField?: string; - searchConfiguration?: unknown; - indexName?: string; - excludeHitsFromPreviousRun?: boolean; - aggType?: string; - aggField?: string; - groupBy?: string; - termField?: string; - termSize?: number; - index?: string[]; -} - -export async function createIndexConnector({ - supertestWithoutAuth, - roleAuthc, - internalReqHeader, - name, - indexName, -}: { - supertestWithoutAuth: SupertestWithoutAuthProviderType; - roleAuthc: RoleCredentials; - internalReqHeader: InternalRequestHeader; - name: string; - indexName: string; -}) { - const { body } = await supertestWithoutAuth - .post(`/api/actions/connector`) - .set(internalReqHeader) - .set(roleAuthc.apiKeyHeader) - .send({ - name, - config: { - index: indexName, - refresh: true, - }, - connector_type_id: '.index', - }) - .expect(200); - return body; -} - -export async function createSlackConnector({ - supertestWithoutAuth, - roleAuthc, - internalReqHeader, - name, -}: { - supertestWithoutAuth: SupertestWithoutAuthProviderType; - roleAuthc: RoleCredentials; - internalReqHeader: InternalRequestHeader; - name: string; -}) { - const { body } = await supertestWithoutAuth - .post(`/api/actions/connector`) - .set(internalReqHeader) - .set(roleAuthc.apiKeyHeader) - .send({ - name, - config: {}, - secrets: { - webhookUrl: 'http://test', - }, - connector_type_id: '.slack', - }) - .expect(200); - return body; -} - -export async function createEsQueryRule({ - supertestWithoutAuth, - roleAuthc, - internalReqHeader, - name, - ruleTypeId, - params, - actions = [], - tags = [], - schedule, - consumer, - notifyWhen, - enabled = true, -}: { - supertestWithoutAuth: SupertestWithoutAuthProviderType; - roleAuthc: RoleCredentials; - internalReqHeader: InternalRequestHeader; - ruleTypeId: string; - name: string; - params: CreateEsQueryRuleParams; - consumer: string; - actions?: any[]; - tags?: any[]; - schedule?: { interval: string }; - notifyWhen?: string; - enabled?: boolean; -}) { - const { body } = await supertestWithoutAuth - .post(`/api/alerting/rule`) - .set(internalReqHeader) - .set(roleAuthc.apiKeyHeader) - .send({ - enabled, - params, - consumer, - schedule: schedule || { - interval: '1h', - }, - tags, - name, - rule_type_id: ruleTypeId, - actions, - ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), - }) - .expect(200); - return body; -} - -export const generateUniqueKey = () => uuidv4().replace(/-/g, ''); - -export async function createAnomalyRule({ - supertest, - name = generateUniqueKey(), - actions = [], - tags = ['foo', 'bar'], - schedule, - consumer = 'alerts', - notifyWhen, - enabled = true, - ruleTypeId = 'apm.anomaly', - params, -}: { - supertest: SuperTestAgent; - name?: string; - consumer?: string; - actions?: any[]; - tags?: any[]; - schedule?: { interval: string }; - notifyWhen?: string; - enabled?: boolean; - ruleTypeId?: string; - params?: any; -}) { - const { body } = await supertest - .post(`/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .send({ - enabled, - params: params || { - anomalySeverityType: 'critical', - anomalyDetectorTypes: ['txLatency'], - environment: 'ENVIRONMENT_ALL', - windowSize: 30, - windowUnit: 'm', - }, - consumer, - schedule: schedule || { - interval: '1m', - }, - tags, - name, - rule_type_id: ruleTypeId, - actions, - ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), - }) - .expect(200); - return body; -} - -export async function createLatencyThresholdRule({ - supertest, - name = generateUniqueKey(), - actions = [], - tags = ['foo', 'bar'], - schedule, - consumer = 'apm', - notifyWhen, - enabled = true, - ruleTypeId = 'apm.transaction_duration', - params, -}: { - supertest: SuperTestAgent; - name?: string; - consumer?: string; - actions?: any[]; - tags?: any[]; - schedule?: { interval: string }; - notifyWhen?: string; - enabled?: boolean; - ruleTypeId?: string; - params?: any; -}) { - const { body } = await supertest - .post(`/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .send({ - enabled, - params: params || { - aggregationType: 'avg', - environment: 'ENVIRONMENT_ALL', - threshold: 1500, - windowSize: 5, - windowUnit: 'm', - }, - consumer, - schedule: schedule || { - interval: '1m', - }, - tags, - name, - rule_type_id: ruleTypeId, - actions, - ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), - }); - return body; -} - -export async function createInventoryRule({ - supertest, - name = generateUniqueKey(), - actions = [], - tags = ['foo', 'bar'], - schedule, - consumer = 'alerts', - notifyWhen, - enabled = true, - ruleTypeId = 'metrics.alert.inventory.threshold', - params, -}: { - supertest: SuperTestAgent; - name?: string; - consumer?: string; - actions?: any[]; - tags?: any[]; - schedule?: { interval: string }; - notifyWhen?: string; - enabled?: boolean; - ruleTypeId?: string; - params?: any; -}) { - const { body } = await supertest - .post(`/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .send({ - enabled, - params: params || { - nodeType: 'host', - criteria: [ - { - metric: 'cpu', - comparator: '>', - threshold: [5], - timeSize: 1, - timeUnit: 'm', - customMetric: { - type: 'custom', - id: 'alert-custom-metric', - field: '', - aggregation: 'avg', - }, - }, - ], - sourceId: 'default', - }, - consumer, - schedule: schedule || { - interval: '1m', - }, - tags, - name, - rule_type_id: ruleTypeId, - actions, - ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), - }) - .expect(200); - return body; -} - -export async function disableRule({ - supertest, - ruleId, -}: { - supertest: SuperTestAgent; - ruleId: string; -}) { - const { body } = await supertest - .post(`/api/alerting/rule/${ruleId}/_disable`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .expect(204); - return body; -} - -export async function updateEsQueryRule({ - supertest, - ruleId, - updates, -}: { - supertest: SuperTestAgent; - ruleId: string; - updates: any; -}) { - const { body: r } = await supertest - .get(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .expect(200); - const body = await supertest - .put(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .send({ - ...{ - name: r.name, - schedule: r.schedule, - throttle: r.throttle, - tags: r.tags, - params: r.params, - notify_when: r.notifyWhen, - actions: r.actions.map((action: any) => ({ - group: action.group, - params: action.params, - id: action.id, - frequency: action.frequency, - })), - }, - ...updates, - }) - .expect(200); - return body; -} - -export async function runRule({ - supertestWithoutAuth, - roleAuthc, - internalReqHeader, - ruleId, -}: { - supertestWithoutAuth: SupertestWithoutAuthProviderType; - roleAuthc: RoleCredentials; - internalReqHeader: InternalRequestHeader; - ruleId: string; -}) { - const response = await supertestWithoutAuth - .post(`/internal/alerting/rule/${ruleId}/_run_soon`) - .set(internalReqHeader) - .set(roleAuthc.apiKeyHeader) - .expect(204); - return response; -} - -export async function muteRule({ - supertest, - ruleId, -}: { - supertest: SuperTestAgent; - ruleId: string; -}) { - const { body } = await supertest - .post(`/api/alerting/rule/${ruleId}/_mute_all`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .expect(204); - return body; -} - -export async function enableRule({ - supertest, - ruleId, -}: { - supertest: SuperTestAgent; - ruleId: string; -}) { - const { body } = await supertest - .post(`/api/alerting/rule/${ruleId}/_enable`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .expect(204); - return body; -} - -export async function muteAlert({ - supertest, - ruleId, - alertId, -}: { - supertest: SuperTestAgent; - ruleId: string; - alertId: string; -}) { - const { body } = await supertest - .post(`/api/alerting/rule/${ruleId}/alert/${alertId}/_mute`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .expect(204); - return body; -} - -export async function unmuteRule({ - supertest, - ruleId, -}: { - supertest: SuperTestAgent; - ruleId: string; -}) { - const { body } = await supertest - .post(`/api/alerting/rule/${ruleId}/_unmute_all`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .expect(204); - return body; -} - -export async function snoozeRule({ - supertest, - ruleId, -}: { - supertest: SuperTestAgent; - ruleId: string; -}) { - const { body } = await supertest - .post(`/internal/alerting/rule/${ruleId}/_snooze`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo') - .send({ - snooze_schedule: { - duration: 100000000, - rRule: { - count: 1, - dtstart: moment().format(), - tzid: 'UTC', - }, - }, - }) - .expect(204); - return body; -} - -export async function findRule({ - supertest, - ruleId, -}: { - supertest: SuperTestAgent; - ruleId: string; -}) { - if (!ruleId) { - throw new Error(`'ruleId' is undefined`); - } - const response = await supertest - .get(`/api/alerting/rule/${ruleId}`) - .set('kbn-xsrf', 'foo') - .set('x-elastic-internal-origin', 'foo'); - return response.body || {}; -} diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_wait_for_helpers.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_wait_for_helpers.ts deleted file mode 100644 index c7f2ac357e4a2..0000000000000 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/helpers/alerting_wait_for_helpers.ts +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import pRetry from 'p-retry'; -import type { Client } from '@elastic/elasticsearch'; -import type { - AggregationsAggregate, - SearchResponse, -} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { runRule } from './alerting_api_helper'; -import type { SupertestWithoutAuthProviderType } from '../../../../../shared/services'; -import { RoleCredentials } from '../../../../../shared/services'; -import { InternalRequestHeader } from '../../../../../shared/services'; - -export async function waitForDocumentInIndex({ - esClient, - indexName, - ruleId, - num = 1, - sort = 'desc', -}: { - esClient: Client; - indexName: string; - ruleId: string; - num?: number; - sort?: 'asc' | 'desc'; -}): Promise { - return await pRetry( - async () => { - const response = await esClient.search({ - index: indexName, - sort: `date:${sort}`, - body: { - query: { - bool: { - must: [ - { - term: { - 'ruleId.keyword': ruleId, - }, - }, - ], - }, - }, - }, - }); - if (response.hits.hits.length < num) { - throw new Error(`Only found ${response.hits.hits.length} / ${num} documents`); - } - return response; - }, - { retries: 10 } - ); -} - -export async function getDocumentsInIndex({ - esClient, - indexName, - ruleId, -}: { - esClient: Client; - indexName: string; - ruleId: string; -}): Promise { - return await esClient.search({ - index: indexName, - body: { - query: { - bool: { - must: [ - { - term: { - 'ruleId.keyword': ruleId, - }, - }, - ], - }, - }, - }, - }); -} - -export async function createIndex({ - esClient, - indexName, -}: { - esClient: Client; - indexName: string; -}) { - return await esClient.indices.create( - { - index: indexName, - body: {}, - }, - { meta: true } - ); -} - -export async function waitForAlertInIndex({ - esClient, - filter, - indexName, - ruleId, - num = 1, -}: { - esClient: Client; - filter: Date; - indexName: string; - ruleId: string; - num: number; -}): Promise>> { - return await pRetry( - async () => { - const response = await esClient.search({ - index: indexName, - body: { - query: { - bool: { - must: [ - { - term: { - 'kibana.alert.rule.uuid': ruleId, - }, - }, - { - range: { - '@timestamp': { - gte: filter.getTime().toString(), - }, - }, - }, - ], - }, - }, - }, - }); - if (response.hits.hits.length < num) { - throw new Error(`Only found ${response.hits.hits.length} / ${num} documents`); - } - return response; - }, - { retries: 10 } - ); -} - -export async function waitForAllTasksIdle({ - esClient, - filter, -}: { - esClient: Client; - filter: Date; -}): Promise { - return await pRetry( - async () => { - const response = await esClient.search({ - index: '.kibana_task_manager', - body: { - query: { - bool: { - must: [ - { - terms: { - 'task.scope': ['actions', 'alerting'], - }, - }, - { - range: { - 'task.scheduledAt': { - gte: filter.getTime().toString(), - }, - }, - }, - ], - must_not: [ - { - term: { - 'task.status': 'idle', - }, - }, - ], - }, - }, - }, - }); - if (response.hits.hits.length !== 0) { - throw new Error(`Expected 0 hits but received ${response.hits.hits.length}`); - } - return response; - }, - { retries: 10 } - ); -} - -export async function waitForAllTasks({ - esClient, - filter, - taskType, - attempts, -}: { - esClient: Client; - filter: Date; - taskType: string; - attempts: number; -}): Promise { - return await pRetry( - async () => { - const response = await esClient.search({ - index: '.kibana_task_manager', - body: { - query: { - bool: { - must: [ - { - term: { - 'task.status': 'idle', - }, - }, - { - term: { - 'task.attempts': attempts, - }, - }, - { - terms: { - 'task.scope': ['actions', 'alerting'], - }, - }, - { - term: { - 'task.taskType': taskType, - }, - }, - { - range: { - 'task.scheduledAt': { - gte: filter.getTime().toString(), - }, - }, - }, - ], - }, - }, - }, - }); - if (response.hits.hits.length === 0) { - throw new Error('No hits found'); - } - return response; - }, - { retries: 10 } - ); -} - -export async function waitForDisabled({ - esClient, - ruleId, - filter, -}: { - esClient: Client; - ruleId: string; - filter: Date; -}): Promise { - return await pRetry( - async () => { - const response = await esClient.search({ - index: '.kibana_task_manager', - body: { - query: { - bool: { - must: [ - { - term: { - 'task.id': `task:${ruleId}`, - }, - }, - { - terms: { - 'task.scope': ['actions', 'alerting'], - }, - }, - { - range: { - 'task.scheduledAt': { - gte: filter.getTime().toString(), - }, - }, - }, - { - term: { - 'task.enabled': true, - }, - }, - ], - }, - }, - }, - }); - if (response.hits.hits.length !== 0) { - throw new Error(`Expected 0 hits but received ${response.hits.hits.length}`); - } - return response; - }, - { retries: 10 } - ); -} - -export async function waitForExecutionEventLog({ - esClient, - filter, - ruleId, - num = 1, -}: { - esClient: Client; - filter: Date; - ruleId: string; - num?: number; -}): Promise { - return await pRetry( - async () => { - const response = await esClient.search({ - index: '.kibana-event-log*', - body: { - query: { - bool: { - filter: [ - { - term: { - 'rule.id': { - value: ruleId, - }, - }, - }, - { - term: { - 'event.provider': { - value: 'alerting', - }, - }, - }, - { - term: { - 'event.action': 'execute', - }, - }, - { - range: { - '@timestamp': { - gte: filter.getTime().toString(), - }, - }, - }, - ], - }, - }, - }, - }); - if (response.hits.hits.length < num) { - throw new Error('No hits found'); - } - return response; - }, - { retries: 10 } - ); -} - -export async function waitForNumRuleRuns({ - supertestWithoutAuth, - roleAuthc, - internalReqHeader, - numOfRuns, - ruleId, - esClient, - testStart, -}: { - supertestWithoutAuth: SupertestWithoutAuthProviderType; - roleAuthc: RoleCredentials; - internalReqHeader: InternalRequestHeader; - numOfRuns: number; - ruleId: string; - esClient: Client; - testStart: Date; -}) { - for (let i = 0; i < numOfRuns; i++) { - await pRetry( - async () => { - await runRule({ supertestWithoutAuth, roleAuthc, internalReqHeader, ruleId }); - await waitForExecutionEventLog({ - esClient, - filter: testStart, - ruleId, - num: i + 1, - }); - await waitForAllTasksIdle({ esClient, filter: testStart }); - }, - { retries: 10 } - ); - } -} diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts index 37b78a5e1b36f..593c10f371f09 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/rules.ts @@ -9,28 +9,6 @@ import { RULE_SAVED_OBJECT_TYPE } from '@kbn/alerting-plugin/server'; import expect from '@kbn/expect'; import { omit } from 'lodash'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { - createIndexConnector, - createEsQueryRule, - disableRule, - updateEsQueryRule, - runRule, - muteRule, - enableRule, - muteAlert, - unmuteRule, - createSlackConnector, -} from './helpers/alerting_api_helper'; -import { - createIndex, - getDocumentsInIndex, - waitForAllTasks, - waitForAllTasksIdle, - waitForDisabled, - waitForDocumentInIndex, - waitForExecutionEventLog, - waitForNumRuleRuns, -} from './helpers/alerting_wait_for_helpers'; import type { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { @@ -39,7 +17,8 @@ export default function ({ getService }: FtrProviderContext) { const esDeleteAllIndices = getService('esDeleteAllIndices'); const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); + const alertingApi = getService('alertingApi'); + let roleAdmin: RoleCredentials; let internalReqHeader: InternalRequestHeader; @@ -73,19 +52,15 @@ export default function ({ getService }: FtrProviderContext) { it('should schedule task, run rule and schedule actions when appropriate', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -130,10 +105,14 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Wait for the action to index a document before disabling the alert and waiting for tasks to finish - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, + retryOptions: { + retryCount: 12, + retryDelay: 2000, + }, }); expect(resp.hits.hits.length).to.be(1); @@ -151,7 +130,7 @@ export default function ({ getService }: FtrProviderContext) { tags: '', }); - const eventLogResp = await waitForExecutionEventLog({ + const eventLogResp = await alertingApi.helpers.waiting.waitForExecutionEventLog({ esClient, filter: testStart, ruleId, @@ -171,19 +150,15 @@ export default function ({ getService }: FtrProviderContext) { it('should pass updated rule params to executor', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -228,10 +203,11 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Wait for the action to index a document before disabling the alert and waiting for tasks to finish - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, + retryOptions: { retryDelay: 800, retryCount: 10 }, }); expect(resp.hits.hits.length).to.be(1); @@ -249,13 +225,13 @@ export default function ({ getService }: FtrProviderContext) { tags: '', }); - await waitForAllTasksIdle({ + await alertingApi.helpers.waiting.waitForAllTasksIdle({ esClient, filter: testStart, }); - await updateEsQueryRule({ - supertest, + await alertingApi.helpers.updateEsQueryRule({ + roleAuthc: roleAdmin, ruleId, updates: { name: 'def', @@ -263,15 +239,13 @@ export default function ({ getService }: FtrProviderContext) { }, }); - await runRule({ - supertestWithoutAuth, + await alertingApi.helpers.runRule({ roleAuthc: roleAdmin, - internalReqHeader, ruleId, }); // make sure alert info passed to executor is correct - const resp2 = await waitForDocumentInIndex({ + const resp2 = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -298,18 +272,14 @@ export default function ({ getService }: FtrProviderContext) { const testStart = new Date(); // Should fail - const createdConnector = await createSlackConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createSlackConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Slack Connector: Alerting API test', }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -341,7 +311,7 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Should retry when the the action fails - const resp = await waitForAllTasks({ + const resp = await alertingApi.helpers.waiting.waitForAllTasks({ esClient, filter: testStart, taskType: 'actions:.slack', @@ -353,19 +323,15 @@ export default function ({ getService }: FtrProviderContext) { it('should throttle alerts when appropriate', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -407,29 +373,27 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Wait until alerts ran at least 3 times before disabling the alert and waiting for tasks to finish - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 3, ruleId, esClient, testStart, }); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc: roleAdmin, ruleId, }); - await waitForDisabled({ + await alertingApi.helpers.waiting.waitForDisabled({ esClient, ruleId, filter: testStart, }); // Ensure actions only executed once - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -440,19 +404,15 @@ export default function ({ getService }: FtrProviderContext) { it('should throttle alerts with throttled action when appropriate', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -498,29 +458,27 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Wait until alerts ran at least 3 times before disabling the alert and waiting for tasks to finish - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 3, ruleId, esClient, testStart, }); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc: roleAdmin, ruleId, }); - await waitForDisabled({ + await alertingApi.helpers.waiting.waitForDisabled({ esClient, ruleId, filter: testStart, }); // Ensure actions only executed once - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -531,19 +489,15 @@ export default function ({ getService }: FtrProviderContext) { it('should reset throttle window when not firing and should not throttle when changing groups', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -614,21 +568,21 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Wait for the action to index a document - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waiting.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, }); expect(resp.hits.hits.length).to.be(1); - await waitForAllTasksIdle({ + await alertingApi.helpers.waiting.waitForAllTasksIdle({ esClient, filter: testStart, }); // Update the rule to recover - await updateEsQueryRule({ - supertest, + await alertingApi.helpers.updateEsQueryRule({ + roleAuthc: roleAdmin, ruleId, updates: { name: 'never fire', @@ -645,34 +599,36 @@ export default function ({ getService }: FtrProviderContext) { }, }); - await runRule({ - supertestWithoutAuth, + await alertingApi.helpers.runRule({ roleAuthc: roleAdmin, - internalReqHeader, ruleId, }); - const eventLogResp = await waitForExecutionEventLog({ + const eventLogResp = await alertingApi.helpers.waiting.waitForExecutionEventLog({ esClient, filter: testStart, ruleId, num: 2, + retryOptions: { + retryCount: 12, + retryDelay: 2000, + }, }); expect(eventLogResp.hits.hits.length).to.be(2); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc: roleAdmin, ruleId, }); - await waitForDisabled({ + await alertingApi.helpers.waiting.waitForDisabled({ esClient, ruleId, filter: testStart, }); // Ensure only 2 actions are executed - const resp2 = await waitForDocumentInIndex({ + const resp2 = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -683,21 +639,17 @@ export default function ({ getService }: FtrProviderContext) { it(`shouldn't schedule actions when alert is muted`, async () => { const testStart = new Date(); - await createIndex({ esClient, indexName: ALERT_ACTION_INDEX }); + await alertingApi.helpers.waiting.createIndex({ esClient, indexName: ALERT_ACTION_INDEX }); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, enabled: false, consumer: 'alerts', name: 'always fire', @@ -742,41 +694,39 @@ export default function ({ getService }: FtrProviderContext) { }); ruleId = createdRule.id; - await muteRule({ - supertest, + await alertingApi.helpers.muteRule({ + roleAuthc: roleAdmin, ruleId, }); - await enableRule({ - supertest, + await alertingApi.helpers.enableRule({ + roleAuthc: roleAdmin, ruleId, }); // Wait until alerts schedule actions twice to ensure actions had a chance to skip // execution once before disabling the alert and waiting for tasks to finish - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 2, ruleId, esClient, testStart, }); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc: roleAdmin, ruleId, }); - await waitForDisabled({ + await alertingApi.helpers.waiting.waitForDisabled({ esClient, ruleId, filter: testStart, }); // Should not have executed any action - const resp2 = await getDocumentsInIndex({ + const resp2 = await alertingApi.helpers.waiting.getDocumentsInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -786,21 +736,17 @@ export default function ({ getService }: FtrProviderContext) { it(`shouldn't schedule actions when alert instance is muted`, async () => { const testStart = new Date(); - await createIndex({ esClient, indexName: ALERT_ACTION_INDEX }); + await alertingApi.helpers.waiting.createIndex({ esClient, indexName: ALERT_ACTION_INDEX }); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, enabled: false, consumer: 'alerts', name: 'always fire', @@ -845,42 +791,40 @@ export default function ({ getService }: FtrProviderContext) { }); ruleId = createdRule.id; - await muteAlert({ - supertest, + await alertingApi.helpers.muteAlert({ + roleAuthc: roleAdmin, ruleId, alertId: 'query matched', }); - await enableRule({ - supertest, + await alertingApi.helpers.enableRule({ + roleAuthc: roleAdmin, ruleId, }); // Wait until alerts schedule actions twice to ensure actions had a chance to skip // execution once before disabling the alert and waiting for tasks to finish - await waitForNumRuleRuns({ - supertestWithoutAuth, + await alertingApi.helpers.waitForNumRuleRuns({ roleAuthc: roleAdmin, - internalReqHeader, numOfRuns: 2, ruleId, esClient, testStart, }); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc: roleAdmin, ruleId, }); - await waitForDisabled({ + await alertingApi.helpers.waiting.waitForDisabled({ esClient, ruleId, filter: testStart, }); // Should not have executed any action - const resp2 = await getDocumentsInIndex({ + const resp2 = await alertingApi.helpers.waiting.getDocumentsInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -889,19 +833,15 @@ export default function ({ getService }: FtrProviderContext) { }); it(`should unmute all instances when unmuting an alert`, async () => { - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, enabled: false, consumer: 'alerts', name: 'always fire', @@ -946,29 +886,29 @@ export default function ({ getService }: FtrProviderContext) { }); ruleId = createdRule.id; - await muteAlert({ - supertest, + await alertingApi.helpers.muteAlert({ + roleAuthc: roleAdmin, ruleId, alertId: 'query matched', }); - await muteRule({ - supertest, + await alertingApi.helpers.muteRule({ + roleAuthc: roleAdmin, ruleId, }); - await unmuteRule({ - supertest, + await alertingApi.helpers.unmuteRule({ + roleAuthc: roleAdmin, ruleId, }); - await enableRule({ - supertest, + await alertingApi.helpers.enableRule({ + roleAuthc: roleAdmin, ruleId, }); // Should have one document indexed by the action - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts index 995a7ee197610..2726af585e28f 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts @@ -29,25 +29,15 @@ import { } from '@kbn/rule-data-utils'; import { omit, padStart } from 'lodash'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { createIndexConnector, createEsQueryRule } from './helpers/alerting_api_helper'; -import { - createIndex, - getDocumentsInIndex, - waitForAlertInIndex, - waitForDocumentInIndex, -} from './helpers/alerting_wait_for_helpers'; -import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; +import { RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const esClient = getService('es'); const esDeleteAllIndices = getService('esDeleteAllIndices'); - - const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); + const alertingApi = getService('alertingApi'); let roleAdmin: RoleCredentials; - let internalReqHeader: InternalRequestHeader; describe('Summary actions', function () { const RULE_TYPE_ID = '.es-query'; @@ -75,7 +65,6 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { roleAdmin = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); - internalReqHeader = svlCommonApi.getInternalRequestHeader(); }); afterEach(async () => { @@ -98,19 +87,15 @@ export default function ({ getService }: FtrProviderContext) { it('should schedule actions for summary of alerts per rule run', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -158,19 +143,27 @@ export default function ({ getService }: FtrProviderContext) { }); ruleId = createdRule.id; - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, + retryOptions: { + retryCount: 20, + retryDelay: 15_000, + }, }); expect(resp.hits.hits.length).to.be(1); - const resp2 = await waitForAlertInIndex({ + const resp2 = await alertingApi.helpers.waitForAlertInIndex({ esClient, filter: testStart, indexName: ALERT_INDEX, ruleId, num: 1, + retryOptions: { + retryCount: 20, + retryDelay: 15_000, + }, }); expect(resp2.hits.hits.length).to.be(1); @@ -228,19 +221,15 @@ export default function ({ getService }: FtrProviderContext) { it('should filter alerts by kql', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -288,19 +277,27 @@ export default function ({ getService }: FtrProviderContext) { }); ruleId = createdRule.id; - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, + retryOptions: { + retryCount: 20, + retryDelay: 15_000, + }, }); expect(resp.hits.hits.length).to.be(1); - const resp2 = await waitForAlertInIndex({ + const resp2 = await alertingApi.helpers.waitForAlertInIndex({ esClient, filter: testStart, indexName: ALERT_INDEX, ruleId, num: 1, + retryOptions: { + retryCount: 20, + retryDelay: 15_000, + }, }); expect(resp2.hits.hits.length).to.be(1); @@ -365,21 +362,17 @@ export default function ({ getService }: FtrProviderContext) { const start = `${hour}:${minutes}`; const end = `${hour}:${minutes}`; - await createIndex({ esClient, indexName: ALERT_ACTION_INDEX }); + await alertingApi.helpers.waiting.createIndex({ esClient, indexName: ALERT_ACTION_INDEX }); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -433,7 +426,7 @@ export default function ({ getService }: FtrProviderContext) { ruleId = createdRule.id; // Should not have executed any action - const resp = await getDocumentsInIndex({ + const resp = await alertingApi.helpers.waiting.getDocumentsInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, @@ -443,19 +436,15 @@ export default function ({ getService }: FtrProviderContext) { it('should schedule actions for summary of alerts on a custom interval', async () => { const testStart = new Date(); - const createdConnector = await createIndexConnector({ - supertestWithoutAuth, + const createdConnector = await alertingApi.helpers.createIndexConnector({ roleAuthc: roleAdmin, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: ALERT_ACTION_INDEX, }); connectorId = createdConnector.id; - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc: roleAdmin, - internalReqHeader, consumer: 'alerts', name: 'always fire', ruleTypeId: RULE_TYPE_ID, @@ -501,20 +490,28 @@ export default function ({ getService }: FtrProviderContext) { }); ruleId = createdRule.id; - const resp = await waitForDocumentInIndex({ + const resp = await alertingApi.helpers.waitForDocumentInIndex({ esClient, indexName: ALERT_ACTION_INDEX, ruleId, num: 2, sort: 'asc', + retryOptions: { + retryCount: 20, + retryDelay: 10_000, + }, }); - const resp2 = await waitForAlertInIndex({ + const resp2 = await alertingApi.helpers.waitForAlertInIndex({ esClient, filter: testStart, indexName: ALERT_INDEX, ruleId, num: 1, + retryOptions: { + retryCount: 20, + retryDelay: 15_000, + }, }); expect(resp2.hits.hits.length).to.be(1); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts b/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts index 39edd9ba01eb9..8d627413ecbc0 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/es_query_rule/es_query_rule.ts @@ -12,7 +12,6 @@ */ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { createEsQueryRule } from '../../common/alerting/helpers/alerting_api_helper'; import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; export default function ({ getService }: FtrProviderContext) { @@ -22,7 +21,6 @@ export default function ({ getService }: FtrProviderContext) { const alertingApi = getService('alertingApi'); const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); let roleAuthc: RoleCredentials; let internalReqHeader: InternalRequestHeader; @@ -58,10 +56,8 @@ export default function ({ getService }: FtrProviderContext) { indexName: ALERT_ACTION_INDEX, }); - const createdRule = await createEsQueryRule({ - supertestWithoutAuth, + const createdRule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'observability', name: 'always fire', ruleTypeId: RULE_TYPE_ID, diff --git a/x-pack/test_serverless/functional/services/index.ts b/x-pack/test_serverless/functional/services/index.ts index c63a16b4402f1..770cdbb88c97a 100644 --- a/x-pack/test_serverless/functional/services/index.ts +++ b/x-pack/test_serverless/functional/services/index.ts @@ -7,7 +7,6 @@ import { services as deploymentAgnosticFunctionalServices } from './deployment_agnostic_services'; import { services as svlSharedServices } from '../../shared/services'; - import { SvlCommonNavigationServiceProvider } from './svl_common_navigation'; import { SvlObltNavigationServiceProvider } from './svl_oblt_navigation'; import { SvlSearchNavigationServiceProvider } from './svl_search_navigation'; @@ -17,6 +16,7 @@ import { SvlCasesServiceProvider } from '../../api_integration/services/svl_case import { MachineLearningProvider } from './ml'; import { LogsSynthtraceProvider } from './log'; import { UISettingsServiceProvider } from './ui_settings'; +import { services as SvlApiIntegrationSvcs } from '../../api_integration/services'; export const services = { // deployment agnostic FTR services @@ -34,4 +34,5 @@ export const services = { uiSettings: UISettingsServiceProvider, // log services svlLogsSynthtraceClient: LogsSynthtraceProvider, + alertingApi: SvlApiIntegrationSvcs.alertingApi, }; diff --git a/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts b/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts index c2b878511a4dd..6a0d515afd232 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/rules/rules_list.ts @@ -7,17 +7,7 @@ import { expect } from 'expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { - createAnomalyRule as createRule, - disableRule, - enableRule, - runRule, - createIndexConnector, - snoozeRule, - createLatencyThresholdRule, - createEsQueryRule, -} from '../../../../api_integration/test_suites/common/alerting/helpers/alerting_api_helper'; -import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; +import { RoleCredentials } from '../../../../shared/services'; export default ({ getPageObject, getService }: FtrProviderContext) => { const svlCommonPage = getPageObject('svlCommonPage'); @@ -31,11 +21,9 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const retry = getService('retry'); const toasts = getService('toasts'); const log = getService('log'); - const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); + const alertingApi = getService('alertingApi'); let roleAuthc: RoleCredentials; - let internalReqHeader: InternalRequestHeader; async function refreshRulesList() { const existsClearFilter = await testSubjects.exists('rules-list-clear-filter'); @@ -57,10 +45,13 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { numAttempts: number; }) { for (let i = 0; i < numAttempts; i++) { - await runRule({ supertestWithoutAuth, roleAuthc, internalReqHeader, ruleId }); + await alertingApi.helpers.runRule({ roleAuthc, ruleId }); await new Promise((resolve) => setTimeout(resolve, intervalMilliseconds)); - await disableRule({ supertest, ruleId }); + await alertingApi.helpers.disableRule({ + roleAuthc, + ruleId, + }); await new Promise((resolve) => setTimeout(resolve, intervalMilliseconds)); await refreshRulesList(); @@ -68,7 +59,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const rulesStatuses = result.map((item: { status: string }) => item.status); if (rulesStatuses.includes('Failed')) return; - await enableRule({ supertest, ruleId }); + await alertingApi.helpers.enableRule({ roleAuthc, ruleId }); } } @@ -84,7 +75,6 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { before(async () => { roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); - internalReqHeader = svlCommonApi.getInternalRequestHeader(); await svlCommonPage.loginWithPrivilegedRole(); await svlObltNavigation.navigateToLandingPage(); await svlCommonNavigation.sidenav.clickLink({ text: 'Alerts' }); @@ -107,10 +97,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should create an ES Query Rule and display it when consumer is observability', async () => { - const esQuery = await createEsQueryRule({ - supertestWithoutAuth, + const esQuery = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, name: 'ES Query', consumer: 'observability', ruleTypeId: '.es-query', @@ -134,10 +122,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should create an ES Query rule but not display it when consumer is stackAlerts', async () => { - const esQuery = await createEsQueryRule({ - supertestWithoutAuth, + const esQuery = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, name: 'ES Query', consumer: 'stackAlerts', ruleTypeId: '.es-query', @@ -159,7 +145,10 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should create and display an APM latency rule', async () => { - const apmLatency = await createLatencyThresholdRule({ supertest, name: 'Apm latency' }); + const apmLatency = await alertingApi.helpers.createLatencyThresholdRule({ + roleAuthc, + name: 'Apm latency', + }); ruleIdList = [apmLatency.id]; await refreshRulesList(); @@ -169,16 +158,16 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should display rules in alphabetical order', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'b', }); - const rule2 = await createRule({ - supertest, + const rule2 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'c', }); - const rule3 = await createRule({ - supertest, + const rule3 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'a', }); @@ -194,8 +183,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should search for rule', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; @@ -215,13 +204,13 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should update rule list on the search clear button click', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'a', }); - const rule2 = await createRule({ - supertest, + const rule2 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'b', tags: [], }); @@ -266,8 +255,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should search for tags', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'a', tags: ['tag', 'tagtag', 'taggity tag'], }); @@ -289,8 +278,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should display an empty list when search did not return any rules', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; @@ -301,8 +290,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should disable single rule', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; @@ -329,14 +318,17 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should re-enable single rule', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'a', }); ruleIdList = [rule1.id]; - await disableRule({ supertest, ruleId: rule1.id }); + await alertingApi.helpers.disableRule({ + roleAuthc, + ruleId: rule1.id, + }); await refreshRulesList(); await svlTriggersActionsUI.searchRules(rule1.name); @@ -360,13 +352,13 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should delete single rule', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'a', }); - const rule2 = await createRule({ - supertest, + const rule2 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'b', }); @@ -392,8 +384,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should disable all selection', async () => { - const createdRule1 = await createRule({ - supertest, + const createdRule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [createdRule1.id]; @@ -422,13 +414,16 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should enable all selection', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; - await disableRule({ supertest, ruleId: rule1.id }); + await alertingApi.helpers.disableRule({ + roleAuthc, + ruleId: rule1.id, + }); await refreshRulesList(); await svlTriggersActionsUI.searchRules(rule1.name); @@ -445,8 +440,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should render percentile column and cells correctly', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; @@ -481,8 +476,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should delete all selection', async () => { - const createdRule1 = await createRule({ - supertest, + const createdRule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [createdRule1.id]; @@ -508,12 +503,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it.skip('should filter rules by the status', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); - const failedRule = await createRule({ - supertest, + const failedRule = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id, failedRule.id]; @@ -558,8 +553,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it.skip('should display total rules by status and error banner only when exists rules with status error', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); await refreshRulesList(); @@ -582,8 +577,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { ); expect(alertsErrorBannerWhenNoErrors).toHaveLength(0); - const failedRule = await createRule({ - supertest, + const failedRule = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id, failedRule.id]; @@ -617,8 +612,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it.skip('Expand error in rules table when there is rule with an error associated', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, name: 'a', }); @@ -639,8 +634,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { let expandRulesErrorLink = await find.allByCssSelector('[data-test-subj="expandRulesError"]'); expect(expandRulesErrorLink).toHaveLength(0); - const failedRule = await createRule({ - supertest, + const failedRule = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id, failedRule.id]; @@ -666,12 +661,12 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should filter rules by the rule type', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); - const rule2 = await createLatencyThresholdRule({ - supertest, + const rule2 = await alertingApi.helpers.createLatencyThresholdRule({ + roleAuthc, }); ruleIdList = [rule1.id, rule2.id]; @@ -730,36 +725,36 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }; // Enabled alert - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); - const disabledRule = await createRule({ - supertest, + const disabledRule = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc, ruleId: disabledRule.id, }); - const snoozedRule = await createRule({ - supertest, + const snoozedRule = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); - await snoozeRule({ - supertest, + await alertingApi.helpers.snoozeRule({ + roleAuthc, ruleId: snoozedRule.id, }); - const snoozedAndDisabledRule = await createRule({ - supertest, + const snoozedAndDisabledRule = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); - await snoozeRule({ - supertest, + await alertingApi.helpers.snoozeRule({ + roleAuthc, ruleId: snoozedAndDisabledRule.id, }); - await disableRule({ - supertest, + await alertingApi.helpers.disableRule({ + roleAuthc, ruleId: snoozedAndDisabledRule.id, }); @@ -801,28 +796,28 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should filter rules by the tag', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, tags: ['a'], }); - const rule2 = await createRule({ - supertest, + const rule2 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, tags: ['b'], }); - const rule3 = await createRule({ - supertest, + const rule3 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, tags: ['a', 'b'], }); - const rule4 = await createRule({ - supertest, + const rule4 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, tags: ['b', 'c'], }); - const rule5 = await createRule({ - supertest, + const rule5 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, tags: ['c'], }); @@ -864,17 +859,15 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should not prevent rules with action execution capabilities from being edited', async () => { - const action = await createIndexConnector({ - supertestWithoutAuth, + const action = await alertingApi.helpers.createIndexConnector({ roleAuthc, - internalReqHeader, name: 'Index Connector: Alerting API test', indexName: '.alerts-observability.apm.alerts-default', }); expect(action).not.toBe(undefined); - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, actions: [ { group: 'threshold_met', @@ -902,8 +895,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should allow rules to be snoozed using the right side dropdown', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; @@ -922,8 +915,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should allow rules to be snoozed indefinitely using the right side dropdown', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; @@ -942,14 +935,14 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('should allow snoozed rules to be unsnoozed using the right side dropdown', async () => { - const rule1 = await createRule({ - supertest, + const rule1 = await alertingApi.helpers.createAnomalyRule({ + roleAuthc, }); ruleIdList = [rule1.id]; - await snoozeRule({ - supertest, + await alertingApi.helpers.snoozeRule({ + roleAuthc, ruleId: rule1.id, }); diff --git a/x-pack/test_serverless/functional/test_suites/search/rules/rule_details.ts b/x-pack/test_serverless/functional/test_suites/search/rules/rule_details.ts index 40d57101693bc..00363f21299de 100644 --- a/x-pack/test_serverless/functional/test_suites/search/rules/rule_details.ts +++ b/x-pack/test_serverless/functional/test_suites/search/rules/rule_details.ts @@ -7,13 +7,8 @@ import { expect } from 'expect'; import { v4 as uuidv4 } from 'uuid'; -import { InternalRequestHeader, RoleCredentials } from '../../../../shared/services'; +import { RoleCredentials } from '../../../../shared/services'; import { FtrProviderContext } from '../../../ftr_provider_context'; -import { - createEsQueryRule as createRule, - createSlackConnector, - createIndexConnector, -} from '../../../../api_integration/test_suites/common/alerting/helpers/alerting_api_helper'; export enum RuleNotifyWhen { CHANGE = 'onActionGroupChange', @@ -34,6 +29,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const toasts = getService('toasts'); const comboBox = getService('comboBox'); const config = getService('config'); + const alertingApi = getService('alertingApi'); const openFirstRule = async (ruleName: string) => { await svlTriggersActionsUI.searchRules(ruleName); @@ -66,15 +62,11 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { let ruleIdList: string[]; let connectorIdList: string[]; - const svlCommonApi = getService('svlCommonApi'); const svlUserManager = getService('svlUserManager'); - const supertestWithoutAuth = getService('supertestWithoutAuth'); let roleAuthc: RoleCredentials; - let internalReqHeader: InternalRequestHeader; before(async () => { roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); - internalReqHeader = svlCommonApi.getInternalRequestHeader(); await svlCommonPage.loginAsViewer(); }); @@ -88,10 +80,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const RULE_TYPE_ID = '.es-query'; before(async () => { - const rule = await createRule({ - supertestWithoutAuth, + const rule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'alerts', name: ruleName, ruleTypeId: RULE_TYPE_ID, @@ -261,10 +251,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const RULE_TYPE_ID = '.es-query'; before(async () => { - const rule = await createRule({ - supertestWithoutAuth, + const rule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'alerts', name: ruleName, ruleTypeId: RULE_TYPE_ID, @@ -369,26 +357,20 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { it('should show and update deleted connectors when there are existing connectors of the same type', async () => { const testRunUuid = uuidv4(); - const connector1 = await createSlackConnector({ - supertestWithoutAuth, + const connector1 = await alertingApi.helpers.createSlackConnector({ roleAuthc, - internalReqHeader, name: `slack-${testRunUuid}-${0}`, }); - const connector2 = await createSlackConnector({ - supertestWithoutAuth, + const connector2 = await alertingApi.helpers.createSlackConnector({ roleAuthc, - internalReqHeader, name: `slack-${testRunUuid}-${1}`, }); connectorIdList = [connector2.id]; - const rule = await createRule({ - supertestWithoutAuth, + const rule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'alerts', name: testRunUuid, ruleTypeId: RULE_TYPE_ID, @@ -450,18 +432,14 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { it('should show and update deleted connectors when there are no existing connectors of the same type', async () => { const testRunUuid = uuidv4(); - const connector = await createIndexConnector({ - supertestWithoutAuth, + const connector = await alertingApi.helpers.createIndexConnector({ roleAuthc, - internalReqHeader, name: `index-${testRunUuid}-${2}`, indexName: ALERT_ACTION_INDEX, }); - const rule = await createRule({ - supertestWithoutAuth, + const rule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'alerts', name: testRunUuid, ruleTypeId: RULE_TYPE_ID, @@ -576,26 +554,20 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const testRunUuid = uuidv4(); const RULE_TYPE_ID = '.es-query'; - const connector1 = await createSlackConnector({ - supertestWithoutAuth, + const connector1 = await alertingApi.helpers.createSlackConnector({ roleAuthc, - internalReqHeader, name: `slack-${testRunUuid}-${0}`, }); - const connector2 = await createSlackConnector({ - supertestWithoutAuth, + const connector2 = await alertingApi.helpers.createSlackConnector({ roleAuthc, - internalReqHeader, name: `slack-${testRunUuid}-${1}`, }); connectorIdList = [connector1.id, connector2.id]; - const rule = await createRule({ - supertestWithoutAuth, + const rule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'alerts', name: `test-rule-${testRunUuid}`, ruleTypeId: RULE_TYPE_ID, @@ -670,10 +642,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); it('renders a disabled rule details view in app button', async () => { - const rule = await createRule({ - supertestWithoutAuth, + const rule = await alertingApi.helpers.createEsQueryRule({ roleAuthc, - internalReqHeader, consumer: 'alerts', name: ruleName, ruleTypeId: RULE_TYPE_ID, diff --git a/x-pack/test_serverless/shared/services/alerting_api.ts b/x-pack/test_serverless/shared/services/alerting_api.ts new file mode 100644 index 0000000000000..afed22fbe2c9a --- /dev/null +++ b/x-pack/test_serverless/shared/services/alerting_api.ts @@ -0,0 +1,1032 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import moment from 'moment'; +import type { + AggregationsAggregate, + SearchResponse, +} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { Client } from '@elastic/elasticsearch'; +import { MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics'; +import { ThresholdParams } from '@kbn/observability-plugin/common/custom_threshold_rule/types'; +import { v4 as uuidv4 } from 'uuid'; +import type { TryWithRetriesOptions } from '@kbn/ftr-common-functional-services'; +import { RoleCredentials } from '.'; +import type { SloBurnRateRuleParams } from '../../api_integration/services/slo_api'; +import { FtrProviderContext } from '../../functional/ftr_provider_context'; + +interface CreateEsQueryRuleParams { + size: number; + thresholdComparator: string; + threshold: number[]; + timeWindowSize?: number; + timeWindowUnit?: string; + esQuery?: string; + timeField?: string; + searchConfiguration?: unknown; + indexName?: string; + excludeHitsFromPreviousRun?: boolean; + aggType?: string; + aggField?: string; + groupBy?: string; + termField?: string; + termSize?: number; + index?: string[]; +} +const RETRY_COUNT = 10; +const RETRY_DELAY = 1000; + +export function AlertingApiProvider({ getService }: FtrProviderContext) { + const retry = getService('retry'); + const es = getService('es'); + const requestTimeout = 30 * 1000; + const retryTimeout = 120 * 1000; + const logger = getService('log'); + const svlCommonApi = getService('svlCommonApi'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + + const generateUniqueKey = () => uuidv4().replace(/-/g, ''); + + const helpers = { + async waitForAlertInIndex({ + esClient, + filter, + indexName, + ruleId, + num = 1, + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + filter: Date; + indexName: string; + ruleId: string; + num: number; + retryOptions?: TryWithRetriesOptions; + }): Promise>> { + return await retry.tryWithRetries( + `Alerting API - waitForAlertInIndex, retryOptions: ${JSON.stringify(retryOptions)}`, + async () => { + const response = await esClient.search({ + index: indexName, + body: { + query: { + bool: { + must: [ + { + term: { + 'kibana.alert.rule.uuid': ruleId, + }, + }, + { + range: { + '@timestamp': { + gte: filter.getTime().toString(), + }, + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length < num) + throw new Error(`Only found ${response.hits.hits.length} / ${num} documents`); + + return response; + }, + retryOptions + ); + }, + + async waitForDocumentInIndex({ + esClient, + indexName, + ruleId, + num = 1, + sort = 'desc', + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + indexName: string; + ruleId: string; + num?: number; + sort?: 'asc' | 'desc'; + retryOptions?: TryWithRetriesOptions; + }): Promise { + return await retry.tryWithRetries( + `Alerting API - waitForDocumentInIndex, retryOptions: ${JSON.stringify(retryOptions)}`, + async () => { + const response = await esClient.search({ + index: indexName, + sort: `date:${sort}`, + body: { + query: { + bool: { + must: [ + { + term: { + 'ruleId.keyword': ruleId, + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length < num) { + throw new Error(`Only found ${response.hits.hits.length} / ${num} documents`); + } + return response; + }, + retryOptions + ); + }, + + async createIndexConnector({ + roleAuthc, + name, + indexName, + }: { + roleAuthc: RoleCredentials; + name: string; + indexName: string; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/actions/connector`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + name, + config: { + index: indexName, + refresh: true, + }, + connector_type_id: '.index', + }) + .expect(200); + return body; + }, + + async createSlackConnector({ roleAuthc, name }: { roleAuthc: RoleCredentials; name: string }) { + const { body } = await supertestWithoutAuth + .post(`/api/actions/connector`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + name, + config: {}, + secrets: { + webhookUrl: 'http://test', + }, + connector_type_id: '.slack', + }) + .expect(200); + return body; + }, + + async createEsQueryRule({ + roleAuthc, + name, + ruleTypeId, + params, + actions = [], + tags = [], + schedule, + consumer, + notifyWhen, + enabled = true, + }: { + roleAuthc: RoleCredentials; + ruleTypeId: string; + name: string; + params: CreateEsQueryRuleParams; + consumer: string; + actions?: any[]; + tags?: any[]; + schedule?: { interval: string }; + notifyWhen?: string; + enabled?: boolean; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + enabled, + params, + consumer, + schedule: schedule || { + interval: '1h', + }, + tags, + name, + rule_type_id: ruleTypeId, + actions, + ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), + }) + .expect(200); + return body; + }, + + async createAnomalyRule({ + roleAuthc, + name = generateUniqueKey(), + actions = [], + tags = ['foo', 'bar'], + schedule, + consumer = 'alerts', + notifyWhen, + enabled = true, + ruleTypeId = 'apm.anomaly', + params, + }: { + roleAuthc: RoleCredentials; + name?: string; + consumer?: string; + actions?: any[]; + tags?: any[]; + schedule?: { interval: string }; + notifyWhen?: string; + enabled?: boolean; + ruleTypeId?: string; + params?: any; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + enabled, + params: params || { + anomalySeverityType: 'critical', + anomalyDetectorTypes: ['txLatency'], + environment: 'ENVIRONMENT_ALL', + windowSize: 30, + windowUnit: 'm', + }, + consumer, + schedule: schedule || { + interval: '1m', + }, + tags, + name, + rule_type_id: ruleTypeId, + actions, + ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), + }) + .expect(200); + return body; + }, + + async createLatencyThresholdRule({ + roleAuthc, + name = generateUniqueKey(), + actions = [], + tags = ['foo', 'bar'], + schedule, + consumer = 'apm', + notifyWhen, + enabled = true, + ruleTypeId = 'apm.transaction_duration', + params, + }: { + roleAuthc: RoleCredentials; + name?: string; + consumer?: string; + actions?: any[]; + tags?: any[]; + schedule?: { interval: string }; + notifyWhen?: string; + enabled?: boolean; + ruleTypeId?: string; + params?: any; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + enabled, + params: params || { + aggregationType: 'avg', + environment: 'ENVIRONMENT_ALL', + threshold: 1500, + windowSize: 5, + windowUnit: 'm', + }, + consumer, + schedule: schedule || { + interval: '1m', + }, + tags, + name, + rule_type_id: ruleTypeId, + actions, + ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), + }); + return body; + }, + + async createInventoryRule({ + roleAuthc, + name = generateUniqueKey(), + actions = [], + tags = ['foo', 'bar'], + schedule, + consumer = 'alerts', + notifyWhen, + enabled = true, + ruleTypeId = 'metrics.alert.inventory.threshold', + params, + }: { + roleAuthc: RoleCredentials; + name?: string; + consumer?: string; + actions?: any[]; + tags?: any[]; + schedule?: { interval: string }; + notifyWhen?: string; + enabled?: boolean; + ruleTypeId?: string; + params?: any; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + enabled, + params: params || { + nodeType: 'host', + criteria: [ + { + metric: 'cpu', + comparator: '>', + threshold: [5], + timeSize: 1, + timeUnit: 'm', + customMetric: { + type: 'custom', + id: 'alert-custom-metric', + field: '', + aggregation: 'avg', + }, + }, + ], + sourceId: 'default', + }, + consumer, + schedule: schedule || { + interval: '1m', + }, + tags, + name, + rule_type_id: ruleTypeId, + actions, + ...(notifyWhen ? { notify_when: notifyWhen, throttle: '5m' } : {}), + }) + .expect(200); + return body; + }, + + async disableRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule/${ruleId}/_disable`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(204); + return body; + }, + + async updateEsQueryRule({ + roleAuthc, + ruleId, + updates, + }: { + roleAuthc: RoleCredentials; + ruleId: string; + updates: any; + }) { + const { body: r } = await supertestWithoutAuth + .get(`/api/alerting/rule/${ruleId}`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(200); + const body = await supertestWithoutAuth + .put(`/api/alerting/rule/${ruleId}`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + ...{ + name: r.name, + schedule: r.schedule, + throttle: r.throttle, + tags: r.tags, + params: r.params, + notify_when: r.notifyWhen, + actions: r.actions.map((action: any) => ({ + group: action.group, + params: action.params, + id: action.id, + frequency: action.frequency, + })), + }, + ...updates, + }) + .expect(200); + return body; + }, + + async runRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + const response = await supertestWithoutAuth + .post(`/internal/alerting/rule/${ruleId}/_run_soon`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(204); + return response; + }, + + async waitForNumRuleRuns({ + roleAuthc, + numOfRuns, + ruleId, + esClient, + testStart, + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + roleAuthc: RoleCredentials; + numOfRuns: number; + ruleId: string; + esClient: Client; + testStart: Date; + retryOptions?: TryWithRetriesOptions; + }) { + for (let i = 0; i < numOfRuns; i++) { + await retry.tryWithRetries( + `Alerting API - waitForNumRuleRuns, retryOptions: ${JSON.stringify(retryOptions)}`, + async () => { + await this.runRule({ roleAuthc, ruleId }); + await this.waiting.waitForExecutionEventLog({ + esClient, + filter: testStart, + ruleId, + num: i + 1, + }); + await this.waiting.waitForAllTasksIdle({ esClient, filter: testStart }); + }, + retryOptions + ); + } + }, + + async muteRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule/${ruleId}/_mute_all`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(204); + return body; + }, + + async enableRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule/${ruleId}/_enable`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(204); + return body; + }, + + async muteAlert({ + roleAuthc, + ruleId, + alertId, + }: { + roleAuthc: RoleCredentials; + ruleId: string; + alertId: string; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule/${ruleId}/alert/${alertId}/_mute`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(204); + return body; + }, + + async unmuteRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule/${ruleId}/_unmute_all`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .expect(204); + return body; + }, + + async snoozeRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + const { body } = await supertestWithoutAuth + .post(`/internal/alerting/rule/${ruleId}/_snooze`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + snooze_schedule: { + duration: 100000000, + rRule: { + count: 1, + dtstart: moment().format(), + tzid: 'UTC', + }, + }, + }) + .expect(204); + return body; + }, + + async findRule({ roleAuthc, ruleId }: { roleAuthc: RoleCredentials; ruleId: string }) { + if (!ruleId) { + throw new Error(`'ruleId' is undefined`); + } + const response = await supertestWithoutAuth + .get(`/api/alerting/rule/${ruleId}`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader); + return response.body || {}; + }, + + waiting: { + async waitForDocumentInIndex({ + esClient, + indexName, + ruleId, + num = 1, + sort = 'desc', + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + indexName: string; + ruleId: string; + num?: number; + sort?: 'asc' | 'desc'; + retryOptions?: TryWithRetriesOptions; + }): Promise { + return await retry.tryWithRetries( + `Alerting API - waiting.waitForDocumentInIndex, retryOptions: ${JSON.stringify( + retryOptions + )}`, + async () => { + const response = await esClient.search({ + index: indexName, + sort: `date:${sort}`, + body: { + query: { + bool: { + must: [ + { + term: { + 'ruleId.keyword': ruleId, + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length < num) { + throw new Error(`Only found ${response.hits.hits.length} / ${num} documents`); + } + return response; + }, + retryOptions + ); + }, + + async getDocumentsInIndex({ + esClient, + indexName, + ruleId, + }: { + esClient: Client; + indexName: string; + ruleId: string; + }): Promise { + return await esClient.search({ + index: indexName, + body: { + query: { + bool: { + must: [ + { + term: { + 'ruleId.keyword': ruleId, + }, + }, + ], + }, + }, + }, + }); + }, + + async waitForAllTasksIdle({ + esClient, + filter, + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + filter: Date; + retryOptions?: TryWithRetriesOptions; + }): Promise { + return await retry.tryWithRetries( + `Alerting API - waiting.waitForAllTasksIdle, retryOptions: ${JSON.stringify( + retryOptions + )}`, + async () => { + const response = await esClient.search({ + index: '.kibana_task_manager', + body: { + query: { + bool: { + must: [ + { + terms: { + 'task.scope': ['actions', 'alerting'], + }, + }, + { + range: { + 'task.scheduledAt': { + gte: filter.getTime().toString(), + }, + }, + }, + ], + must_not: [ + { + term: { + 'task.status': 'idle', + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length !== 0) { + throw new Error(`Expected 0 hits but received ${response.hits.hits.length}`); + } + return response; + }, + retryOptions + ); + }, + + async waitForExecutionEventLog({ + esClient, + filter, + ruleId, + num = 1, + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + filter: Date; + ruleId: string; + num?: number; + retryOptions?: TryWithRetriesOptions; + }): Promise { + return await retry.tryWithRetries( + `Alerting API - waiting.waitForExecutionEventLog, retryOptions: ${JSON.stringify( + retryOptions + )}`, + async () => { + const response = await esClient.search({ + index: '.kibana-event-log*', + body: { + query: { + bool: { + filter: [ + { + term: { + 'rule.id': { + value: ruleId, + }, + }, + }, + { + term: { + 'event.provider': { + value: 'alerting', + }, + }, + }, + { + term: { + 'event.action': 'execute', + }, + }, + { + range: { + '@timestamp': { + gte: filter.getTime().toString(), + }, + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length < num) { + throw new Error('No hits found'); + } + return response; + }, + retryOptions + ); + }, + + async createIndex({ esClient, indexName }: { esClient: Client; indexName: string }) { + return await esClient.indices.create( + { + index: indexName, + body: {}, + }, + { meta: true } + ); + }, + + async waitForAllTasks({ + esClient, + filter, + taskType, + attempts, + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + filter: Date; + taskType: string; + attempts: number; + retryOptions?: TryWithRetriesOptions; + }): Promise { + return await retry.tryWithRetries( + `Alerting API - waiting.waitForAllTasks, retryOptions: ${JSON.stringify(retryOptions)}`, + async () => { + const response = await esClient.search({ + index: '.kibana_task_manager', + body: { + query: { + bool: { + must: [ + { + term: { + 'task.status': 'idle', + }, + }, + { + term: { + 'task.attempts': attempts, + }, + }, + { + terms: { + 'task.scope': ['actions', 'alerting'], + }, + }, + { + term: { + 'task.taskType': taskType, + }, + }, + { + range: { + 'task.scheduledAt': { + gte: filter.getTime().toString(), + }, + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length === 0) { + throw new Error('No hits found'); + } + return response; + }, + retryOptions + ); + }, + + async waitForDisabled({ + esClient, + ruleId, + filter, + retryOptions = { retryCount: RETRY_COUNT, retryDelay: RETRY_DELAY }, + }: { + esClient: Client; + ruleId: string; + filter: Date; + retryOptions?: TryWithRetriesOptions; + }): Promise { + return await retry.tryWithRetries( + `Alerting API - waiting.waitForDisabled, retryOptions: ${JSON.stringify(retryOptions)}`, + async () => { + const response = await esClient.search({ + index: '.kibana_task_manager', + body: { + query: { + bool: { + must: [ + { + term: { + 'task.id': `task:${ruleId}`, + }, + }, + { + terms: { + 'task.scope': ['actions', 'alerting'], + }, + }, + { + range: { + 'task.scheduledAt': { + gte: filter.getTime().toString(), + }, + }, + }, + { + term: { + 'task.enabled': true, + }, + }, + ], + }, + }, + }, + }); + if (response.hits.hits.length !== 0) { + throw new Error(`Expected 0 hits but received ${response.hits.hits.length}`); + } + return response; + }, + retryOptions + ); + }, + }, + }; + + return { + helpers, + + async waitForRuleStatus({ + roleAuthc, + ruleId, + expectedStatus, + }: { + roleAuthc: RoleCredentials; + ruleId: string; + expectedStatus: string; + }) { + if (!ruleId) { + throw new Error(`'ruleId' is undefined`); + } + return await retry.tryForTime(retryTimeout, async () => { + const response = await supertestWithoutAuth + .get(`/api/alerting/rule/${ruleId}`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .timeout(requestTimeout); + const { execution_status: executionStatus } = response.body || {}; + const { status } = executionStatus || {}; + if (status !== expectedStatus) { + throw new Error(`waitForStatus(${expectedStatus}): got ${status}`); + } + return executionStatus?.status; + }); + }, + + async waitForDocumentInIndex({ + indexName, + docCountTarget = 1, + }: { + indexName: string; + docCountTarget?: number; + }): Promise>> { + return await retry.tryForTime(retryTimeout, async () => { + const response = await es.search({ + index: indexName, + rest_total_hits_as_int: true, + }); + logger.debug(`Found ${response.hits.total} docs, looking for at least ${docCountTarget}.`); + if (!response.hits.total || (response.hits.total as number) < docCountTarget) { + throw new Error('No hits found'); + } + return response; + }); + }, + + async waitForAlertInIndex({ + indexName, + ruleId, + }: { + indexName: string; + ruleId: string; + }): Promise>> { + if (!ruleId) { + throw new Error(`'ruleId' is undefined`); + } + return await retry.tryForTime(retryTimeout, async () => { + const response = await es.search({ + index: indexName, + body: { + query: { + term: { + 'kibana.alert.rule.uuid': ruleId, + }, + }, + }, + }); + if (response.hits.hits.length === 0) { + throw new Error('No hits found'); + } + return response; + }); + }, + + async createIndexConnector({ + roleAuthc, + name, + indexName, + }: { + roleAuthc: RoleCredentials; + name: string; + indexName: string; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/actions/connector`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + name, + config: { + index: indexName, + refresh: true, + }, + connector_type_id: '.index', + }); + return body.id as string; + }, + + async createRule({ + roleAuthc, + name, + ruleTypeId, + params, + actions = [], + tags = [], + schedule, + consumer, + }: { + roleAuthc: RoleCredentials; + ruleTypeId: string; + name: string; + params: MetricThresholdParams | ThresholdParams | SloBurnRateRuleParams; + actions?: any[]; + tags?: any[]; + schedule?: { interval: string }; + consumer: string; + }) { + const { body } = await supertestWithoutAuth + .post(`/api/alerting/rule`) + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader) + .send({ + params, + consumer, + schedule: schedule || { + interval: '5m', + }, + tags, + name, + rule_type_id: ruleTypeId, + actions, + }); + return body; + }, + + async findRule(roleAuthc: RoleCredentials, ruleId: string) { + if (!ruleId) { + throw new Error(`'ruleId' is undefined`); + } + const response = await supertestWithoutAuth + .get('/api/alerting/rules/_find') + .set(svlCommonApi.getInternalRequestHeader()) + .set(roleAuthc.apiKeyHeader); + return response.body.data.find((obj: any) => obj.id === ruleId); + }, + }; +} diff --git a/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts b/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts index 97a5963bd9e3b..2272890e52eb4 100644 --- a/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts +++ b/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts @@ -8,7 +8,7 @@ import _ from 'lodash'; import { services as apiIntegrationServices } from '@kbn/test-suites-xpack/api_integration/services'; - +import { AlertingApiProvider } from './alerting_api'; /* * Some FTR services from api integration stateful tests are compatible with serverless environment * While adding a new one, make sure to verify that it works on both Kibana CI and MKI @@ -35,4 +35,5 @@ const deploymentAgnosticApiIntegrationServices = _.pick(apiIntegrationServices, export const services = { // deployment agnostic FTR services ...deploymentAgnosticApiIntegrationServices, + alertingApi: AlertingApiProvider, }; From 6689169687977595f03a536ee2bbfda7b0135fb1 Mon Sep 17 00:00:00 2001 From: Nick Peihl Date: Mon, 16 Sep 2024 10:50:50 -0400 Subject: [PATCH 026/139] Move @elastic/kibana-gis ownership to @elastic/kibana-presentation (#192521) ## Summary The legacy `@elastic/kibana-gis` team is now a part of `@elastic/kibana-presentation`. So we should move ownership of all code to the correct team. --- .github/CODEOWNERS | 12 ++++++------ packages/kbn-mapbox-gl/kibana.jsonc | 2 +- renovate.json | 1 - src/plugins/maps_ems/kibana.jsonc | 2 +- .../third_party_maps_source_example/kibana.jsonc | 2 +- x-pack/packages/maps/vector_tile_utils/kibana.jsonc | 2 +- x-pack/plugins/file_upload/kibana.jsonc | 2 +- x-pack/plugins/maps/kibana.jsonc | 2 +- 8 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9adb05cb22ecc..457458ec5b1c6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -461,7 +461,7 @@ src/plugins/field_formats @elastic/kibana-data-discovery packages/kbn-field-types @elastic/kibana-data-discovery packages/kbn-field-utils @elastic/kibana-data-discovery x-pack/plugins/fields_metadata @elastic/obs-ux-logs-team -x-pack/plugins/file_upload @elastic/kibana-gis @elastic/ml-ui +x-pack/plugins/file_upload @elastic/kibana-presentation @elastic/ml-ui examples/files_example @elastic/appex-sharedux src/plugins/files_management @elastic/appex-sharedux src/plugins/files @elastic/appex-sharedux @@ -583,11 +583,11 @@ packages/kbn-management/settings/types @elastic/kibana-management packages/kbn-management/settings/utilities @elastic/kibana-management packages/kbn-management/storybook/config @elastic/kibana-management test/plugin_functional/plugins/management_test_plugin @elastic/kibana-management -packages/kbn-mapbox-gl @elastic/kibana-gis -x-pack/examples/third_party_maps_source_example @elastic/kibana-gis -src/plugins/maps_ems @elastic/kibana-gis -x-pack/plugins/maps @elastic/kibana-gis -x-pack/packages/maps/vector_tile_utils @elastic/kibana-gis +packages/kbn-mapbox-gl @elastic/kibana-presentation +x-pack/examples/third_party_maps_source_example @elastic/kibana-presentation +src/plugins/maps_ems @elastic/kibana-presentation +x-pack/plugins/maps @elastic/kibana-presentation +x-pack/packages/maps/vector_tile_utils @elastic/kibana-presentation x-pack/plugins/observability_solution/metrics_data_access @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team x-pack/packages/ml/agg_utils @elastic/ml-ui x-pack/packages/ml/anomaly_utils @elastic/ml-ui diff --git a/packages/kbn-mapbox-gl/kibana.jsonc b/packages/kbn-mapbox-gl/kibana.jsonc index 4238b33f6aefd..6cc7e1f7b2b30 100644 --- a/packages/kbn-mapbox-gl/kibana.jsonc +++ b/packages/kbn-mapbox-gl/kibana.jsonc @@ -1,5 +1,5 @@ { "type": "shared-common", "id": "@kbn/mapbox-gl", - "owner": "@elastic/kibana-gis" + "owner": "@elastic/kibana-presentation" } diff --git a/renovate.json b/renovate.json index 02ec0d0c127a4..6f3b61c6e1b12 100644 --- a/renovate.json +++ b/renovate.json @@ -371,7 +371,6 @@ "team:kibana-presentation", "team:kibana-data-discovery", "team:kibana-management", - "team:kibana-gis", "team:security-solution" ], "matchBaseBranches": ["main"], diff --git a/src/plugins/maps_ems/kibana.jsonc b/src/plugins/maps_ems/kibana.jsonc index f71542e94ae71..a341ad05f4e4b 100644 --- a/src/plugins/maps_ems/kibana.jsonc +++ b/src/plugins/maps_ems/kibana.jsonc @@ -1,7 +1,7 @@ { "type": "plugin", "id": "@kbn/maps-ems-plugin", - "owner": "@elastic/kibana-gis", + "owner": "@elastic/kibana-presentation", "plugin": { "id": "mapsEms", "server": true, diff --git a/x-pack/examples/third_party_maps_source_example/kibana.jsonc b/x-pack/examples/third_party_maps_source_example/kibana.jsonc index 6b1317437401d..5b987dcd966ab 100644 --- a/x-pack/examples/third_party_maps_source_example/kibana.jsonc +++ b/x-pack/examples/third_party_maps_source_example/kibana.jsonc @@ -1,7 +1,7 @@ { "type": "plugin", "id": "@kbn/maps-custom-raster-source-plugin", - "owner": "@elastic/kibana-gis", + "owner": "@elastic/kibana-presentation", "description": "An example plugin for creating a custom raster source for Elastic Maps", "plugin": { "id": "mapsCustomRasterSource", diff --git a/x-pack/packages/maps/vector_tile_utils/kibana.jsonc b/x-pack/packages/maps/vector_tile_utils/kibana.jsonc index 7fa54b903a4a5..5e1e9957ecdf3 100644 --- a/x-pack/packages/maps/vector_tile_utils/kibana.jsonc +++ b/x-pack/packages/maps/vector_tile_utils/kibana.jsonc @@ -1,5 +1,5 @@ { "type": "shared-common", "id": "@kbn/maps-vector-tile-utils", - "owner": "@elastic/kibana-gis" + "owner": "@elastic/kibana-presentation" } diff --git a/x-pack/plugins/file_upload/kibana.jsonc b/x-pack/plugins/file_upload/kibana.jsonc index 6c6e3fddd0e7c..9d8143dafcb46 100644 --- a/x-pack/plugins/file_upload/kibana.jsonc +++ b/x-pack/plugins/file_upload/kibana.jsonc @@ -1,7 +1,7 @@ { "type": "plugin", "id": "@kbn/file-upload-plugin", - "owner": ["@elastic/kibana-gis", "@elastic/ml-ui"], + "owner": ["@elastic/kibana-presentation", "@elastic/ml-ui"], "description": "The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON.", "plugin": { "id": "fileUpload", diff --git a/x-pack/plugins/maps/kibana.jsonc b/x-pack/plugins/maps/kibana.jsonc index b042d0250b0c2..421817e87344f 100644 --- a/x-pack/plugins/maps/kibana.jsonc +++ b/x-pack/plugins/maps/kibana.jsonc @@ -1,7 +1,7 @@ { "type": "plugin", "id": "@kbn/maps-plugin", - "owner": "@elastic/kibana-gis", + "owner": "@elastic/kibana-presentation", "plugin": { "id": "maps", "server": true, From f029f8086a6731b5f435775c915d46e110a34658 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Mon, 16 Sep 2024 16:58:13 +0200 Subject: [PATCH 027/139] [Observability] Create observability-specific setting for excluding data tiers from queries (#192570) part of [#190559](https://github.com/elastic/kibana/issues/190559) ## Summary This PR introduces a new `Advanced Settings` under `Observabilty` to provide a way of configuring the exclusion of indices in the `data_cold` and/or `data_frozen` tiers from queries. The change will help to address issues encountered in O11y, most specifically in APM, and could also affect Infra and other features, with unbounded queries targeting the frozen tier. ### For reviewers This PR replaces https://github.com/elastic/kibana/pull/192276 --------- Co-authored-by: Elastic Machine --- .../settings/setting_ids/index.ts | 1 + .../settings/observability_project/index.ts | 1 + .../server/collectors/management/schema.ts | 7 +++++++ .../server/collectors/management/types.ts | 1 + src/plugins/telemetry/schema/oss_plugins.json | 9 +++++++++ .../observability/common/ui_settings_keys.ts | 1 + .../observability/server/ui_settings.ts | 19 +++++++++++++++++++ 7 files changed, 39 insertions(+) diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index 08ce7f3579229..0f79a5fff0506 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -150,6 +150,7 @@ export const OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING = 'observability:aiAssistantSimulatedFunctionCalling'; export const OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN = 'observability:aiAssistantSearchConnectorIndexPattern'; +export const OBSERVABILITY_SEARCH_EXCLUDED_DATA_TIERS = 'observability:searchExcludedDataTiers'; // Reporting settings export const XPACK_REPORTING_CUSTOM_PDF_LOGO_ID = 'xpackReporting:customPdfLogo'; diff --git a/packages/serverless/settings/observability_project/index.ts b/packages/serverless/settings/observability_project/index.ts index 470964954d166..85f6327bf0a07 100644 --- a/packages/serverless/settings/observability_project/index.ts +++ b/packages/serverless/settings/observability_project/index.ts @@ -37,4 +37,5 @@ export const OBSERVABILITY_PROJECT_SETTINGS = [ settings.OBSERVABILITY_AI_ASSISTANT_LOGS_INDEX_PATTERN_ID, settings.OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING, settings.OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN, + settings.OBSERVABILITY_SEARCH_EXCLUDED_DATA_TIERS, ]; diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index d1ab81f3e60a7..52c0df738246a 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -694,4 +694,11 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, + 'observability:searchExcludedDataTiers': { + type: 'array', + items: { + type: 'keyword', + _meta: { description: 'Non-default value of setting.' }, + }, + }, }; diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index c66f4f07a296e..0a0ebe8ebbac6 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -181,4 +181,5 @@ export interface UsageStats { 'aiAssistant:preferredAIAssistantType': string; 'observability:profilingFetchTopNFunctionsFromStacktraces': boolean; 'securitySolution:excludedDataTiersForRuleExecution': string[]; + 'observability:searchExcludedDataTiers': string[]; } diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 70fbeec73bc5d..77e050334803b 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10355,6 +10355,15 @@ } } }, + "observability:searchExcludedDataTiers": { + "type": "array", + "items": { + "type": "keyword", + "_meta": { + "description": "Non-default value of setting." + } + } + }, "banners:placement": { "type": "keyword", "_meta": { diff --git a/x-pack/plugins/observability_solution/observability/common/ui_settings_keys.ts b/x-pack/plugins/observability_solution/observability/common/ui_settings_keys.ts index fe43cd30705db..efceaca9a0427 100644 --- a/x-pack/plugins/observability_solution/observability/common/ui_settings_keys.ts +++ b/x-pack/plugins/observability_solution/observability/common/ui_settings_keys.ts @@ -48,3 +48,4 @@ export const profilingAzureCostDiscountRate = 'observability:profilingAzureCostD export const apmEnableTransactionProfiling = 'observability:apmEnableTransactionProfiling'; export const profilingFetchTopNFunctionsFromStacktraces = 'observability:profilingFetchTopNFunctionsFromStacktraces'; +export const searchExcludedDataTiers = 'observability:searchExcludedDataTiers'; diff --git a/x-pack/plugins/observability_solution/observability/server/ui_settings.ts b/x-pack/plugins/observability_solution/observability/server/ui_settings.ts index d404606b4ce79..81c0596722106 100644 --- a/x-pack/plugins/observability_solution/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability_solution/observability/server/ui_settings.ts @@ -46,6 +46,7 @@ import { apmEnableServiceInventoryTableSearchBar, profilingFetchTopNFunctionsFromStacktraces, enableInfrastructureContainerAssetView, + searchExcludedDataTiers, } from '../common/ui_settings_keys'; const betaLabel = i18n.translate('xpack.observability.uiSettings.betaLabel', { @@ -640,6 +641,24 @@ export const uiSettings: Record = { schema: schema.boolean(), requiresPageReload: false, }, + [searchExcludedDataTiers]: { + category: [observabilityFeatureId], + name: i18n.translate('xpack.observability.searchExcludedDataTiers', { + defaultMessage: 'Excluded data tiers from search', + }), + description: i18n.translate( + 'xpack.observability.advancedSettings.searchExcludedDataTiersDesc', + { + defaultMessage: `Specify the data tiers to exclude from search, such as data_cold and/or data_frozen. + When configured, indices allocated in the selected tiers will be ignored from search requests. Affected apps: APM`, + } + ), + value: [], + schema: schema.arrayOf( + schema.oneOf([schema.literal('data_cold'), schema.literal('data_frozen')]) + ), + requiresPageReload: false, + }, }; function throttlingDocsLink({ href }: { href: string }) { From cd964f1229b1fdc919677768dae22cf1c05fa3e2 Mon Sep 17 00:00:00 2001 From: Tiago Vila Verde Date: Mon, 16 Sep 2024 17:15:10 +0200 Subject: [PATCH 028/139] [Security Solution][Entity Analytics] APIs for Entity Store engine (#191986) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR introduces the following API routes for setting up Entity Store "engines":
Initialise Engine | POST /api/entity_store/engines//init -- | -- Start Engine | POST /api/entity_store/engines//start Stop Engine | POST /api/entity_store/engines//stop Delete Engine | DELETE /api/entity_store/engines/ Get engine | GET  /api/entity_store/engines/ List Engines | GET /api/entity_store/engines
The PR includes the following: - Adding the `EntityManager` plugin (see elastic/obs-entities) as a dependency of the Security Solution - The OpenAPI schemas for the new routes - The actual Kibana side endpoints - A `Saved Object` to track the installed engines - A new `EntityStoreDataClient` - A new feature flag `entityStoreEngineRoutesEnabled` ### How to test 1. Add some host/user data * Easiest is to use [elastic/security-data-generator](https://github.com/elastic/security-documents-generator) 2. Make sure to add `entityStoreEngineRoutesEnabled` under `xpack.securitySolution.enableExperimental` in your `kibana.dev.yml` 3. In kibana dev tools or your terminal, call the `INIT` route for either `user` or `host`. 4. You should now see 2 transforms in kibana. Make sure to re-trigger them if needed so they process the documents. 5. Check that new entities have been observed by querying the new entities index via: * `GET .entities.v1.latest.ea*/_search` 6. Check the other endpoints are working (`START`, `STOP`, `LIST`, etc) 7. Calling `DELETE` should remove the transforms Implements https://github.com/elastic/security-team/issues/10230 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine --- .../current_fields.json | 6 + .../current_mappings.json | 17 ++ .../check_registered_types.test.ts | 1 + .../group3/type_registrations.test.ts | 1 + .../entity_store/common.gen.ts | 38 ++++ .../entity_store/common.schema.yaml | 37 ++++ .../entity_store/engine/delete.gen.ts | 43 ++++ .../entity_store/engine/delete.schema.yaml | 37 ++++ .../entity_store/engine/get.gen.ts | 33 +++ .../entity_store/engine/get.schema.yaml | 25 +++ .../entity_store/engine/init.gen.ts | 38 ++++ .../entity_store/engine/init.schema.yaml | 39 ++++ .../entity_store/engine/list.gen.ts | 25 +++ .../entity_store/engine/list.schema.yaml | 25 +++ .../entity_store/engine/start.gen.ts | 33 +++ .../entity_store/engine/start.schema.yaml | 31 +++ .../entity_store/engine/stats.gen.ts | 39 ++++ .../entity_store/engine/stats.schema.yaml | 41 ++++ .../entity_store/engine/stop.gen.ts | 33 +++ .../entity_store/engine/stop.schema.yaml | 30 +++ .../common/api/quickstart_client.gen.ts | 134 ++++++++++++ .../common/experimental_features.ts | 5 + ...alytics_api_2023_10_31.bundled.schema.yaml | 205 ++++++++++++++++++ ...alytics_api_2023_10_31.bundled.schema.yaml | 205 ++++++++++++++++++ x-pack/plugins/security_solution/kibana.jsonc | 5 +- .../routes/__mocks__/request_context.ts | 3 + .../entity_store/constants.ts | 21 ++ .../entity_store/definition.ts | 56 +++++ .../entity_store_data_client.mock.ts | 20 ++ .../entity_store/entity_store_data_client.ts | 120 ++++++++++ .../entity_store/routes/delete.ts | 64 ++++++ .../entity_store/routes/get.ts | 62 ++++++ .../entity_store/routes/index.ts | 8 + .../entity_store/routes/init.ts | 65 ++++++ .../entity_store/routes/list.ts | 57 +++++ .../routes/register_entity_store_routes.ts | 23 ++ .../entity_store/routes/start.ts | 59 +++++ .../entity_store/routes/stats.ts | 58 +++++ .../entity_store/routes/stop.ts | 59 +++++ .../saved_object/engine_descriptor.ts | 76 +++++++ .../saved_object/engine_descriptor_type.ts | 36 +++ .../entity_store/saved_object/index.ts | 8 + .../entity_store/utils/utils.ts | 33 +++ .../register_entity_analytics_routes.ts | 4 + .../server/request_context_factory.ts | 18 ++ .../security_solution/server/saved_objects.ts | 2 + .../plugins/security_solution/server/types.ts | 2 + .../plugins/security_solution/tsconfig.json | 2 + .../services/security_solution_api.gen.ts | 83 +++++++ .../platform_security/authorization.ts | 34 +++ 50 files changed, 2097 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts create mode 100644 x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.schema.yaml create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/constants.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/definition.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.mock.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/delete.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/get.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/index.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/init.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/list.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/register_entity_store_routes.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/start.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stop.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor_type.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/index.ts create mode 100644 x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/utils/utils.ts diff --git a/packages/kbn-check-mappings-update-cli/current_fields.json b/packages/kbn-check-mappings-update-cli/current_fields.json index 0447ba6a226dd..ec14f4519d344 100644 --- a/packages/kbn-check-mappings-update-cli/current_fields.json +++ b/packages/kbn-check-mappings-update-cli/current_fields.json @@ -312,6 +312,12 @@ "entity-discovery-api-key": [ "apiKey" ], + "entity-engine-status": [ + "filter", + "indexPattern", + "status", + "type" + ], "epm-packages": [ "additional_spaces_installed_kibana", "es_index_patterns", diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index bda2270001bd9..2bdf6e75ad1cb 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -1057,6 +1057,23 @@ } } }, + "entity-engine-status": { + "dynamic": false, + "properties": { + "filter": { + "type": "keyword" + }, + "indexPattern": { + "type": "keyword" + }, + "status": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, "epm-packages": { "properties": { "additional_spaces_installed_kibana": { diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index 92de0c925951b..170cfa5958782 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -93,6 +93,7 @@ describe('checking migration metadata changes on all registered SO types', () => "enterprise_search_telemetry": "9ac912e1417fc8681e0cd383775382117c9e3d3d", "entity-definition": "61be3e95966045122b55e181bb39658b1dc9bbe9", "entity-discovery-api-key": "c267a65c69171d1804362155c1378365f5acef88", + "entity-engine-status": "0738aa1a06d3361911740f8f166071ea43a00927", "epm-packages": "8042d4a1522f6c4e6f5486e791b3ffe3a22f88fd", "epm-packages-assets": "7a3e58efd9a14191d0d1a00b8aaed30a145fd0b1", "event-annotation-group": "715ba867d8c68f3c9438052210ea1c30a9362582", diff --git a/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts index 4320b0eb689d9..e95a82e63d0ff 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group3/type_registrations.test.ts @@ -124,6 +124,7 @@ const previouslyRegisteredTypes = [ 'security-rule', 'security-solution-signals-migration', 'risk-engine-configuration', + 'entity-engine-status', 'server', 'siem-detection-engine-rule-actions', 'siem-detection-engine-rule-execution-info', diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts new file mode 100644 index 0000000000000..e5f8c631fcbae --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.gen.ts @@ -0,0 +1,38 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Entity Store Common Schema + * version: 1 + */ + +import { z } from '@kbn/zod'; + +export type EntityType = z.infer; +export const EntityType = z.enum(['user', 'host']); +export type EntityTypeEnum = typeof EntityType.enum; +export const EntityTypeEnum = EntityType.enum; + +export type IndexPattern = z.infer; +export const IndexPattern = z.string(); + +export type EngineStatus = z.infer; +export const EngineStatus = z.enum(['installing', 'started', 'stopped']); +export type EngineStatusEnum = typeof EngineStatus.enum; +export const EngineStatusEnum = EngineStatus.enum; + +export type EngineDescriptor = z.infer; +export const EngineDescriptor = z.object({ + type: EntityType.optional(), + indexPattern: IndexPattern.optional(), + status: EngineStatus.optional(), + filter: z.string().optional(), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml new file mode 100644 index 0000000000000..dc17ad6193ee5 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/common.schema.yaml @@ -0,0 +1,37 @@ +openapi: 3.0.0 +info: + title: Entity Store Common Schema + description: Common schema for Entity Store + version: '1' +paths: {} +components: + schemas: + + EntityType: + type: string + enum: + - user + - host + + EngineDescriptor: + type: object + properties: + type: + $ref: '#/components/schemas/EntityType' + indexPattern: + $ref: '#/components/schemas/IndexPattern' + status: + $ref: '#/components/schemas/EngineStatus' + filter: + type: string + + EngineStatus: + type: string + enum: + - installing + - started + - stopped + + IndexPattern: + type: string + \ No newline at end of file diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts new file mode 100644 index 0000000000000..34acf2a802076 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.gen.ts @@ -0,0 +1,43 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Delete the entity store engine + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; +import { BooleanFromString } from '@kbn/zod-helpers'; + +import { EntityType } from '../common.gen'; + +export type DeleteEntityStoreRequestQuery = z.infer; +export const DeleteEntityStoreRequestQuery = z.object({ + /** + * Control flag to also delete the entity data. + */ + data: BooleanFromString.optional(), +}); +export type DeleteEntityStoreRequestQueryInput = z.input; + +export type DeleteEntityStoreRequestParams = z.infer; +export const DeleteEntityStoreRequestParams = z.object({ + /** + * The entity type of the store (either 'user' or 'host'). + */ + entityType: EntityType, +}); +export type DeleteEntityStoreRequestParamsInput = z.input; + +export type DeleteEntityStoreResponse = z.infer; +export const DeleteEntityStoreResponse = z.object({ + deleted: z.boolean().optional(), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.schema.yaml new file mode 100644 index 0000000000000..c766d9895c5fa --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/delete.schema.yaml @@ -0,0 +1,37 @@ +openapi: 3.0.0 + +info: + title: Delete the entity store engine + version: '2023-10-31' +paths: + /api/entity_store/engines/{entityType}: + delete: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: DeleteEntityStore + summary: Delete the Entity Store engine + parameters: + - name: entityType + in: path + required: true + schema: + $ref: '../common.schema.yaml#/components/schemas/EntityType' + description: The entity type of the store (either 'user' or 'host'). + + - name: data + in: query + required: false + schema: + type: boolean + description: Control flag to also delete the entity data. + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + deleted: + type: boolean + \ No newline at end of file diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts new file mode 100644 index 0000000000000..44f6f45844fc1 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.gen.ts @@ -0,0 +1,33 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Get Entity Store engine + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; + +import { EntityType, EngineDescriptor } from '../common.gen'; + +export type GetEntityStoreEngineRequestParams = z.infer; +export const GetEntityStoreEngineRequestParams = z.object({ + /** + * The entity type of the store (either 'user' or 'host'). + */ + entityType: EntityType, +}); +export type GetEntityStoreEngineRequestParamsInput = z.input< + typeof GetEntityStoreEngineRequestParams +>; + +export type GetEntityStoreEngineResponse = z.infer; +export const GetEntityStoreEngineResponse = EngineDescriptor; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.schema.yaml new file mode 100644 index 0000000000000..d65a5906e54d9 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/get.schema.yaml @@ -0,0 +1,25 @@ +openapi: 3.0.0 +info: + title: Get Entity Store engine + version: '2023-10-31' +paths: + /api/entity_store/engines/{entityType}: + get: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: GetEntityStoreEngine + summary: Get the Entity Store engine + parameters: + - name: entityType + in: path + required: true + schema: + $ref: '../common.schema.yaml#/components/schemas/EntityType' + description: The entity type of the store (either 'user' or 'host'). + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '../common.schema.yaml#/components/schemas/EngineDescriptor' diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts new file mode 100644 index 0000000000000..07f32f4cb7144 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.gen.ts @@ -0,0 +1,38 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Init Entity Store types + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; + +import { EntityType, IndexPattern, EngineDescriptor } from '../common.gen'; + +export type InitEntityStoreRequestParams = z.infer; +export const InitEntityStoreRequestParams = z.object({ + /** + * The entity type of the store (either 'user' or 'host'). + */ + entityType: EntityType, +}); +export type InitEntityStoreRequestParamsInput = z.input; + +export type InitEntityStoreRequestBody = z.infer; +export const InitEntityStoreRequestBody = z.object({ + indexPattern: IndexPattern.optional(), + filter: z.string().optional(), +}); +export type InitEntityStoreRequestBodyInput = z.input; + +export type InitEntityStoreResponse = z.infer; +export const InitEntityStoreResponse = EngineDescriptor; diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.schema.yaml new file mode 100644 index 0000000000000..8e826d57ce40a --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/init.schema.yaml @@ -0,0 +1,39 @@ +openapi: 3.0.0 + +info: + title: Init Entity Store types + version: '2023-10-31' +paths: + /api/entity_store/engines/{entityType}/init: + post: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: InitEntityStore + summary: Initialize the Entity Store + parameters: + - name: entityType + in: path + required: true + schema: + $ref: '../common.schema.yaml#/components/schemas/EntityType' + description: The entity type of the store (either 'user' or 'host'). + requestBody: + description: Schema for the engine initialization + required: true + content: + application/json: + schema: + type: object + properties: + indexPattern: + $ref: '../common.schema.yaml#/components/schemas/IndexPattern' + filter: + type: string + responses: + '200': + description: Successful response + content: + application/json: + schema: + $ref: '../common.schema.yaml#/components/schemas/EngineDescriptor' + diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts new file mode 100644 index 0000000000000..926549a329a4b --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.gen.ts @@ -0,0 +1,25 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: List Entity Store engines + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; + +import { EngineDescriptor } from '../common.gen'; + +export type ListEntityStoreEnginesResponse = z.infer; +export const ListEntityStoreEnginesResponse = z.object({ + count: z.number().int().optional(), + engines: z.array(EngineDescriptor).optional(), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.schema.yaml new file mode 100644 index 0000000000000..efad1a4380352 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/list.schema.yaml @@ -0,0 +1,25 @@ +openapi: 3.0.0 +info: + title: List Entity Store engines + version: '2023-10-31' +paths: + /api/entity_store/engines: + get: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: ListEntityStoreEngines + summary: List the Entity Store engines + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + count: + type: integer + engines: + type: array + items: + $ref: '../common.schema.yaml#/components/schemas/EngineDescriptor' \ No newline at end of file diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts new file mode 100644 index 0000000000000..b8e94d00551c0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.gen.ts @@ -0,0 +1,33 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Start the entity store engine + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; + +import { EntityType } from '../common.gen'; + +export type StartEntityStoreRequestParams = z.infer; +export const StartEntityStoreRequestParams = z.object({ + /** + * The entity type of the store (either 'user' or 'host'). + */ + entityType: EntityType, +}); +export type StartEntityStoreRequestParamsInput = z.input; + +export type StartEntityStoreResponse = z.infer; +export const StartEntityStoreResponse = z.object({ + started: z.boolean().optional(), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.schema.yaml new file mode 100644 index 0000000000000..5c048bf3d973c --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/start.schema.yaml @@ -0,0 +1,31 @@ +openapi: 3.0.0 + +info: + title: Start the entity store engine + version: '2023-10-31' +paths: + /api/entity_store/engines/{entityType}/start: + post: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: StartEntityStore + summary: Start the Entity Store engine + parameters: + - name: entityType + in: path + required: true + schema: + $ref: '../common.schema.yaml#/components/schemas/EntityType' + description: The entity type of the store (either 'user' or 'host'). + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + started: + type: boolean + + \ No newline at end of file diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts new file mode 100644 index 0000000000000..631399faebc96 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.gen.ts @@ -0,0 +1,39 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Get the entity store engine stats + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; + +import { EntityType, IndexPattern, EngineStatus } from '../common.gen'; + +export type GetEntityStoreStatsRequestParams = z.infer; +export const GetEntityStoreStatsRequestParams = z.object({ + /** + * The entity type of the store (either 'user' or 'host'). + */ + entityType: EntityType, +}); +export type GetEntityStoreStatsRequestParamsInput = z.input< + typeof GetEntityStoreStatsRequestParams +>; + +export type GetEntityStoreStatsResponse = z.infer; +export const GetEntityStoreStatsResponse = z.object({ + type: EntityType.optional(), + indexPattern: IndexPattern.optional(), + status: EngineStatus.optional(), + transforms: z.array(z.object({})).optional(), + indices: z.array(z.object({})).optional(), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml new file mode 100644 index 0000000000000..8d8327d5e6468 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stats.schema.yaml @@ -0,0 +1,41 @@ +openapi: 3.0.0 + +info: + title: Get the entity store engine stats + version: '2023-10-31' +paths: + /api/entity_store/engines/{entityType}/stats: + post: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: GetEntityStoreStats + summary: Get the Entity Store engine stats + parameters: + - name: entityType + in: path + required: true + schema: + $ref: '../common.schema.yaml#/components/schemas/EntityType' + description: The entity type of the store (either 'user' or 'host'). + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + type: + $ref : '../common.schema.yaml#/components/schemas/EntityType' + indexPattern: + $ref : '../common.schema.yaml#/components/schemas/IndexPattern' + status: + $ref : '../common.schema.yaml#/components/schemas/EngineStatus' + transforms: + type: array + items: + type: object + indices: + type: array + items: + type: object diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts new file mode 100644 index 0000000000000..ff3ef7a2f3eac --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.gen.ts @@ -0,0 +1,33 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + * + * info: + * title: Stop the entity store engine + * version: 2023-10-31 + */ + +import { z } from '@kbn/zod'; + +import { EntityType } from '../common.gen'; + +export type StopEntityStoreRequestParams = z.infer; +export const StopEntityStoreRequestParams = z.object({ + /** + * The entity type of the store (either 'user' or 'host'). + */ + entityType: EntityType, +}); +export type StopEntityStoreRequestParamsInput = z.input; + +export type StopEntityStoreResponse = z.infer; +export const StopEntityStoreResponse = z.object({ + stopped: z.boolean().optional(), +}); diff --git a/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.schema.yaml b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.schema.yaml new file mode 100644 index 0000000000000..214f803a76e34 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/entity_analytics/entity_store/engine/stop.schema.yaml @@ -0,0 +1,30 @@ +openapi: 3.0.0 + +info: + title: Stop the entity store engine + version: '2023-10-31' +paths: + /api/entity_store/engines/{entityType}/stop: + post: + x-labels: [ess, serverless] + x-codegen-enabled: true + operationId: StopEntityStore + summary: Stop the Entity Store engine + parameters: + - name: entityType + in: path + required: true + schema: + $ref: '../common.schema.yaml#/components/schemas/EntityType' + description: The entity type of the store (either 'user' or 'host'). + responses: + '200': + description: Successful response + content: + application/json: + schema: + type: object + properties: + stopped: + type: boolean + diff --git a/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts b/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts index edd0bfe89fc8c..c08f807d4926b 100644 --- a/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts +++ b/x-pack/plugins/security_solution/common/api/quickstart_client.gen.ts @@ -242,6 +242,33 @@ import type { InternalUploadAssetCriticalityRecordsResponse, UploadAssetCriticalityRecordsResponse, } from './entity_analytics/asset_criticality/upload_asset_criticality_csv.gen'; +import type { + DeleteEntityStoreRequestQueryInput, + DeleteEntityStoreRequestParamsInput, + DeleteEntityStoreResponse, +} from './entity_analytics/entity_store/engine/delete.gen'; +import type { + GetEntityStoreEngineRequestParamsInput, + GetEntityStoreEngineResponse, +} from './entity_analytics/entity_store/engine/get.gen'; +import type { + InitEntityStoreRequestParamsInput, + InitEntityStoreRequestBodyInput, + InitEntityStoreResponse, +} from './entity_analytics/entity_store/engine/init.gen'; +import type { ListEntityStoreEnginesResponse } from './entity_analytics/entity_store/engine/list.gen'; +import type { + StartEntityStoreRequestParamsInput, + StartEntityStoreResponse, +} from './entity_analytics/entity_store/engine/start.gen'; +import type { + GetEntityStoreStatsRequestParamsInput, + GetEntityStoreStatsResponse, +} from './entity_analytics/entity_store/engine/stats.gen'; +import type { + StopEntityStoreRequestParamsInput, + StopEntityStoreResponse, +} from './entity_analytics/entity_store/engine/stop.gen'; import type { DisableRiskEngineResponse } from './entity_analytics/risk_engine/engine_disable_route.gen'; import type { EnableRiskEngineResponse } from './entity_analytics/risk_engine/engine_enable_route.gen'; import type { InitRiskEngineResponse } from './entity_analytics/risk_engine/engine_init_route.gen'; @@ -620,6 +647,20 @@ Migrations are initiated per index. While the process is neither destructive nor }) .catch(catchAxiosErrorFormatAndThrow); } + async deleteEntityStore(props: DeleteEntityStoreProps) { + this.log.info(`${new Date().toISOString()} Calling API DeleteEntityStore`); + return this.kbnClient + .request({ + path: replaceParams('/api/entity_store/engines/{entityType}', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'DELETE', + + query: props.query, + }) + .catch(catchAxiosErrorFormatAndThrow); + } async deleteNote(props: DeleteNoteProps) { this.log.info(`${new Date().toISOString()} Calling API DeleteNote`); return this.kbnClient @@ -1155,6 +1196,30 @@ finalize it. }) .catch(catchAxiosErrorFormatAndThrow); } + async getEntityStoreEngine(props: GetEntityStoreEngineProps) { + this.log.info(`${new Date().toISOString()} Calling API GetEntityStoreEngine`); + return this.kbnClient + .request({ + path: replaceParams('/api/entity_store/engines/{entityType}', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'GET', + }) + .catch(catchAxiosErrorFormatAndThrow); + } + async getEntityStoreStats(props: GetEntityStoreStatsProps) { + this.log.info(`${new Date().toISOString()} Calling API GetEntityStoreStats`); + return this.kbnClient + .request({ + path: replaceParams('/api/entity_store/engines/{entityType}/stats', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'POST', + }) + .catch(catchAxiosErrorFormatAndThrow); + } /** * Gets notes */ @@ -1311,6 +1376,19 @@ finalize it. }) .catch(catchAxiosErrorFormatAndThrow); } + async initEntityStore(props: InitEntityStoreProps) { + this.log.info(`${new Date().toISOString()} Calling API InitEntityStore`); + return this.kbnClient + .request({ + path: replaceParams('/api/entity_store/engines/{entityType}/init', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'POST', + body: props.body, + }) + .catch(catchAxiosErrorFormatAndThrow); + } /** * Initializes the Risk Engine by creating the necessary indices and mappings, removing old transforms, and starting the new risk engine */ @@ -1367,6 +1445,18 @@ finalize it. }) .catch(catchAxiosErrorFormatAndThrow); } + async listEntityStoreEngines() { + this.log.info(`${new Date().toISOString()} Calling API ListEntityStoreEngines`); + return this.kbnClient + .request({ + path: '/api/entity_store/engines', + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'GET', + }) + .catch(catchAxiosErrorFormatAndThrow); + } /** * Update specific fields of an existing detection rule using the `rule_id` or `id` field. */ @@ -1699,6 +1789,30 @@ detection engine rules. }) .catch(catchAxiosErrorFormatAndThrow); } + async startEntityStore(props: StartEntityStoreProps) { + this.log.info(`${new Date().toISOString()} Calling API StartEntityStore`); + return this.kbnClient + .request({ + path: replaceParams('/api/entity_store/engines/{entityType}/start', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'POST', + }) + .catch(catchAxiosErrorFormatAndThrow); + } + async stopEntityStore(props: StopEntityStoreProps) { + this.log.info(`${new Date().toISOString()} Calling API StopEntityStore`); + return this.kbnClient + .request({ + path: replaceParams('/api/entity_store/engines/{entityType}/stop', props.params), + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '2023-10-31', + }, + method: 'POST', + }) + .catch(catchAxiosErrorFormatAndThrow); + } /** * Suggests user profiles. */ @@ -1809,6 +1923,10 @@ export interface CreateUpdateProtectionUpdatesNoteProps { export interface DeleteAssetCriticalityRecordProps { query: DeleteAssetCriticalityRecordRequestQueryInput; } +export interface DeleteEntityStoreProps { + query: DeleteEntityStoreRequestQueryInput; + params: DeleteEntityStoreRequestParamsInput; +} export interface DeleteNoteProps { body: DeleteNoteRequestBodyInput; } @@ -1902,6 +2020,12 @@ export interface GetEndpointSuggestionsProps { params: GetEndpointSuggestionsRequestParamsInput; body: GetEndpointSuggestionsRequestBodyInput; } +export interface GetEntityStoreEngineProps { + params: GetEntityStoreEngineRequestParamsInput; +} +export interface GetEntityStoreStatsProps { + params: GetEntityStoreStatsRequestParamsInput; +} export interface GetNotesProps { query: GetNotesRequestQueryInput; } @@ -1932,6 +2056,10 @@ export interface ImportRulesProps { export interface ImportTimelinesProps { body: ImportTimelinesRequestBodyInput; } +export interface InitEntityStoreProps { + params: InitEntityStoreRequestParamsInput; + body: InitEntityStoreRequestBodyInput; +} export interface InstallPrepackedTimelinesProps { body: InstallPrepackedTimelinesRequestBodyInput; } @@ -1984,6 +2112,12 @@ export interface SetAlertsStatusProps { export interface SetAlertTagsProps { body: SetAlertTagsRequestBodyInput; } +export interface StartEntityStoreProps { + params: StartEntityStoreRequestParamsInput; +} +export interface StopEntityStoreProps { + params: StopEntityStoreRequestParamsInput; +} export interface SuggestUserProfilesProps { query: SuggestUserProfilesRequestQueryInput; } diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index 7d3edafedd1a9..e11965653526f 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -223,6 +223,11 @@ export const allowedExperimentalValues = Object.freeze({ * Enables the new data ingestion hub */ dataIngestionHubEnabled: false, + + /** + * Enables the new Entity Store engine routes + */ + entityStoreEnabled: false, }); type ExperimentalConfigKeys = Array; diff --git a/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml b/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml index 7ee7a3748df4b..9e56395f2af75 100644 --- a/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/plugins/security_solution/docs/openapi/ess/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml @@ -256,6 +256,187 @@ paths: summary: List Asset Criticality Records tags: - Security Solution Entity Analytics API + /api/entity_store/engines: + get: + operationId: ListEntityStoreEngines + responses: + '200': + content: + application/json: + schema: + type: object + properties: + count: + type: integer + engines: + items: + $ref: '#/components/schemas/EngineDescriptor' + type: array + description: Successful response + summary: List the Entity Store engines + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}': + delete: + operationId: DeleteEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + - description: Control flag to also delete the entity data. + in: query + name: data + required: false + schema: + type: boolean + responses: + '200': + content: + application/json: + schema: + type: object + properties: + deleted: + type: boolean + description: Successful response + summary: Delete the Entity Store engine + tags: + - Security Solution Entity Analytics API + get: + operationId: GetEntityStoreEngine + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/EngineDescriptor' + description: Successful response + summary: Get the Entity Store engine + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/init': + post: + operationId: InitEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + requestBody: + content: + application/json: + schema: + type: object + properties: + filter: + type: string + indexPattern: + $ref: '#/components/schemas/IndexPattern' + description: Schema for the engine initialization + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/EngineDescriptor' + description: Successful response + summary: Initialize the Entity Store + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/start': + post: + operationId: StartEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + type: object + properties: + started: + type: boolean + description: Successful response + summary: Start the Entity Store engine + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/stats': + post: + operationId: GetEntityStoreStats + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + type: object + properties: + indexPattern: + $ref: '#/components/schemas/IndexPattern' + indices: + items: + type: object + type: array + status: + $ref: '#/components/schemas/EngineStatus' + transforms: + items: + type: object + type: array + type: + $ref: '#/components/schemas/EntityType' + description: Successful response + summary: Get the Entity Store engine stats + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/stop': + post: + operationId: StopEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + type: object + properties: + stopped: + type: boolean + description: Successful response + summary: Stop the Entity Store engine + tags: + - Security Solution Entity Analytics API /api/risk_score/engine/schedule_now: post: operationId: ScheduleRiskEngineNow @@ -351,11 +532,35 @@ components: $ref: '#/components/schemas/AssetCriticalityLevel' required: - criticality_level + EngineDescriptor: + type: object + properties: + filter: + type: string + indexPattern: + $ref: '#/components/schemas/IndexPattern' + status: + $ref: '#/components/schemas/EngineStatus' + type: + $ref: '#/components/schemas/EntityType' + EngineStatus: + enum: + - installing + - started + - stopped + type: string + EntityType: + enum: + - user + - host + type: string IdField: enum: - host.name - user.name type: string + IndexPattern: + type: string RiskEngineScheduleNowErrorResponse: type: object properties: diff --git a/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml b/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml index 845b4ced91545..754c8f94d1c63 100644 --- a/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml +++ b/x-pack/plugins/security_solution/docs/openapi/serverless/security_solution_entity_analytics_api_2023_10_31.bundled.schema.yaml @@ -256,6 +256,187 @@ paths: summary: List Asset Criticality Records tags: - Security Solution Entity Analytics API + /api/entity_store/engines: + get: + operationId: ListEntityStoreEngines + responses: + '200': + content: + application/json: + schema: + type: object + properties: + count: + type: integer + engines: + items: + $ref: '#/components/schemas/EngineDescriptor' + type: array + description: Successful response + summary: List the Entity Store engines + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}': + delete: + operationId: DeleteEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + - description: Control flag to also delete the entity data. + in: query + name: data + required: false + schema: + type: boolean + responses: + '200': + content: + application/json: + schema: + type: object + properties: + deleted: + type: boolean + description: Successful response + summary: Delete the Entity Store engine + tags: + - Security Solution Entity Analytics API + get: + operationId: GetEntityStoreEngine + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/EngineDescriptor' + description: Successful response + summary: Get the Entity Store engine + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/init': + post: + operationId: InitEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + requestBody: + content: + application/json: + schema: + type: object + properties: + filter: + type: string + indexPattern: + $ref: '#/components/schemas/IndexPattern' + description: Schema for the engine initialization + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/EngineDescriptor' + description: Successful response + summary: Initialize the Entity Store + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/start': + post: + operationId: StartEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + type: object + properties: + started: + type: boolean + description: Successful response + summary: Start the Entity Store engine + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/stats': + post: + operationId: GetEntityStoreStats + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + type: object + properties: + indexPattern: + $ref: '#/components/schemas/IndexPattern' + indices: + items: + type: object + type: array + status: + $ref: '#/components/schemas/EngineStatus' + transforms: + items: + type: object + type: array + type: + $ref: '#/components/schemas/EntityType' + description: Successful response + summary: Get the Entity Store engine stats + tags: + - Security Solution Entity Analytics API + '/api/entity_store/engines/{entityType}/stop': + post: + operationId: StopEntityStore + parameters: + - description: The entity type of the store (either 'user' or 'host'). + in: path + name: entityType + required: true + schema: + $ref: '#/components/schemas/EntityType' + responses: + '200': + content: + application/json: + schema: + type: object + properties: + stopped: + type: boolean + description: Successful response + summary: Stop the Entity Store engine + tags: + - Security Solution Entity Analytics API /api/risk_score/engine/schedule_now: post: operationId: ScheduleRiskEngineNow @@ -351,11 +532,35 @@ components: $ref: '#/components/schemas/AssetCriticalityLevel' required: - criticality_level + EngineDescriptor: + type: object + properties: + filter: + type: string + indexPattern: + $ref: '#/components/schemas/IndexPattern' + status: + $ref: '#/components/schemas/EngineStatus' + type: + $ref: '#/components/schemas/EntityType' + EngineStatus: + enum: + - installing + - started + - stopped + type: string + EntityType: + enum: + - user + - host + type: string IdField: enum: - host.name - user.name type: string + IndexPattern: + type: string RiskEngineScheduleNowErrorResponse: type: object properties: diff --git a/x-pack/plugins/security_solution/kibana.jsonc b/x-pack/plugins/security_solution/kibana.jsonc index f682ca478a17f..e5840a6662e79 100644 --- a/x-pack/plugins/security_solution/kibana.jsonc +++ b/x-pack/plugins/security_solution/kibana.jsonc @@ -53,7 +53,8 @@ "notifications", "savedSearch", "unifiedDocViewer", - "charts" + "charts", + "entityManager" ], "optionalPlugins": [ "cloudExperiments", @@ -87,4 +88,4 @@ "common" ] } -} +} \ No newline at end of file diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts index b39cba0cf4952..a5e0c8c60b1fc 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_context.ts @@ -36,6 +36,7 @@ import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint import type { EndpointAuthz } from '../../../../../common/endpoint/types/authz'; import { riskEngineDataClientMock } from '../../../entity_analytics/risk_engine/risk_engine_data_client.mock'; import { riskScoreDataClientMock } from '../../../entity_analytics/risk_score/risk_score_data_client.mock'; +import { entityStoreDataClientMock } from '../../../entity_analytics/entity_store/entity_store_data_client.mock'; import { assetCriticalityDataClientMock } from '../../../entity_analytics/asset_criticality/asset_criticality_data_client.mock'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; import { detectionRulesClientMock } from '../../rule_management/logic/detection_rules_client/__mocks__/detection_rules_client'; @@ -72,6 +73,7 @@ export const createMockClients = () => { riskEngineDataClient: riskEngineDataClientMock.create(), riskScoreDataClient: riskScoreDataClientMock.create(), assetCriticalityDataClient: assetCriticalityDataClientMock.create(), + entityStoreDataClient: entityStoreDataClientMock.create(), internalFleetServices: { packages: packageServiceMock.createClient(), @@ -159,6 +161,7 @@ const createSecuritySolutionRequestContextMock = ( getRiskScoreDataClient: jest.fn(() => clients.riskScoreDataClient), getAssetCriticalityDataClient: jest.fn(() => clients.assetCriticalityDataClient), getAuditLogger: jest.fn(() => mockAuditLogger), + getEntityStoreDataClient: jest.fn(() => clients.entityStoreDataClient), }; }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/constants.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/constants.ts new file mode 100644 index 0000000000000..ce5a61fa7e6c9 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/constants.ts @@ -0,0 +1,21 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EngineStatus } from '../../../../common/api/entity_analytics/entity_store/common.gen'; +import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants'; + +/** + * Default index pattern for entity store + * This is the same as the default index pattern for the SIEM app but might diverge in the future + */ +export const ENTITY_STORE_DEFAULT_SOURCE_INDICES = DEFAULT_INDEX_PATTERN; + +export const ENGINE_STATUS: Record, EngineStatus> = { + INSTALLING: 'installing', + STARTED: 'started', + STOPPED: 'stopped', +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/definition.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/definition.ts new file mode 100644 index 0000000000000..32859b9841e7f --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/definition.ts @@ -0,0 +1,56 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { entityDefinitionSchema, type EntityDefinition } from '@kbn/entities-schema'; +import { ENTITY_STORE_DEFAULT_SOURCE_INDICES } from './constants'; + +export const HOST_ENTITY_DEFINITION: EntityDefinition = entityDefinitionSchema.parse({ + id: 'ea_host_entity_store', + name: 'EA Host Store', + type: 'host', + indexPatterns: ENTITY_STORE_DEFAULT_SOURCE_INDICES, + identityFields: ['host.name'], + displayNameTemplate: '{{host.name}}', + metadata: [ + 'host.domain', + 'host.hostname', + 'host.id', + 'host.ip', + 'host.mac', + 'host.name', + 'host.type', + 'host.architecture', + ], + history: { + timestampField: '@timestamp', + interval: '1m', + }, + version: '1.0.0', +}); + +export const USER_ENTITY_DEFINITION: EntityDefinition = entityDefinitionSchema.parse({ + id: 'ea_user_entity_store', + name: 'EA User Store', + type: 'user', + indexPatterns: ENTITY_STORE_DEFAULT_SOURCE_INDICES, + identityFields: ['user.name'], + displayNameTemplate: '{{user.name}}', + metadata: [ + 'user.domain', + 'user.email', + 'user.full_name', + 'user.hash', + 'user.id', + 'user.name', + 'user.roles', + ], + history: { + timestampField: '@timestamp', + interval: '1m', + }, + version: '1.0.0', +}); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.mock.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.mock.ts new file mode 100644 index 0000000000000..095565343e130 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.mock.ts @@ -0,0 +1,20 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EntityStoreDataClient } from './entity_store_data_client'; + +const createEntityStoreDataClientMock = () => + ({ + init: jest.fn(), + start: jest.fn(), + stop: jest.fn(), + get: jest.fn(), + list: jest.fn(), + delete: jest.fn(), + } as unknown as jest.Mocked); + +export const entityStoreDataClientMock = { create: createEntityStoreDataClientMock }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts new file mode 100644 index 0000000000000..cb4d59139a25f --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/entity_store_data_client.ts @@ -0,0 +1,120 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Logger, ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import type { EntityClient } from '@kbn/entityManager-plugin/server/lib/entity_client'; + +import type { + InitEntityStoreRequestBody, + InitEntityStoreResponse, +} from '../../../../common/api/entity_analytics/entity_store/engine/init.gen'; +import type { + EngineDescriptor, + EntityType, +} from '../../../../common/api/entity_analytics/entity_store/common.gen'; +import { entityEngineDescriptorTypeName } from './saved_object'; +import { EngineDescriptorClient } from './saved_object/engine_descriptor'; +import { getEntityDefinition } from './utils/utils'; +import { ENGINE_STATUS } from './constants'; + +interface EntityStoreClientOpts { + logger: Logger; + esClient: ElasticsearchClient; + entityClient: EntityClient; + namespace: string; + soClient: SavedObjectsClientContract; +} + +export class EntityStoreDataClient { + private engineClient: EngineDescriptorClient; + constructor(private readonly options: EntityStoreClientOpts) { + this.engineClient = new EngineDescriptorClient(options.soClient); + } + + public async init( + entityType: EntityType, + { indexPattern = '', filter = '' }: InitEntityStoreRequestBody + ): Promise { + const definition = getEntityDefinition(entityType); + + this.options.logger.info(`Initializing entity store for ${entityType}`); + + const descriptor = await this.engineClient.init(entityType, definition, filter); + await this.options.entityClient.createEntityDefinition({ + definition: { + ...definition, + filter, + indexPatterns: indexPattern + ? [...definition.indexPatterns, ...indexPattern.split(',')] + : definition.indexPatterns, + }, + }); + const updated = await this.engineClient.update(definition.id, ENGINE_STATUS.STARTED); + + return { ...descriptor, ...updated }; + } + + public async start(entityType: EntityType) { + const definition = getEntityDefinition(entityType); + + const descriptor = await this.engineClient.get(entityType); + + if (descriptor.status !== ENGINE_STATUS.STOPPED) { + throw new Error( + `Cannot start Entity engine for ${entityType} when current status is: ${descriptor.status}` + ); + } + + this.options.logger.info(`Starting entity store for ${entityType}`); + await this.options.entityClient.startEntityDefinition(definition); + + return this.engineClient.update(definition.id, ENGINE_STATUS.STARTED); + } + + public async stop(entityType: EntityType) { + const definition = getEntityDefinition(entityType); + + const descriptor = await this.engineClient.get(entityType); + + if (descriptor.status !== ENGINE_STATUS.STARTED) { + throw new Error( + `Cannot stop Entity engine for ${entityType} when current status is: ${descriptor.status}` + ); + } + + this.options.logger.info(`Stopping entity store for ${entityType}`); + await this.options.entityClient.stopEntityDefinition(definition); + + return this.engineClient.update(definition.id, ENGINE_STATUS.STOPPED); + } + + public async get(entityType: EntityType) { + return this.engineClient.get(entityType); + } + + public async list() { + return this.options.soClient + .find({ + type: entityEngineDescriptorTypeName, + }) + .then(({ saved_objects: engines }) => ({ + engines: engines.map((engine) => engine.attributes), + count: engines.length, + })); + } + + public async delete(entityType: EntityType, deleteData: boolean) { + const { id } = getEntityDefinition(entityType); + + this.options.logger.info(`Deleting entity store for ${entityType}`); + + await this.options.entityClient.deleteEntityDefinition({ id, deleteData }); + await this.engineClient.delete(id); + + return { deleted: true }; + } +} diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/delete.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/delete.ts new file mode 100644 index 0000000000000..44352cfa47c57 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/delete.ts @@ -0,0 +1,64 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; + +import type { DeleteEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/delete.gen'; +import { + DeleteEntityStoreRequestQuery, + DeleteEntityStoreRequestParams, +} from '../../../../../common/api/entity_analytics/entity_store/engine/delete.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; +import type { EntityAnalyticsRoutesDeps } from '../../types'; + +export const deleteEntityEngineRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .delete({ + access: 'public', + path: '/api/entity_store/engines/{entityType}', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + query: buildRouteValidationWithZod(DeleteEntityStoreRequestQuery), + params: buildRouteValidationWithZod(DeleteEntityStoreRequestParams), + }, + }, + }, + + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + const secSol = await context.securitySolution; + const body = await secSol + .getEntityStoreDataClient() + .delete(request.params.entityType, !!request.query.data); + + return response.ok({ body }); + } catch (e) { + logger.error('Error in DeleteEntityStore:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/get.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/get.ts new file mode 100644 index 0000000000000..79a74303c49c2 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/get.ts @@ -0,0 +1,62 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; + +import type { GetEntityStoreEngineResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/get.gen'; +import { GetEntityStoreEngineRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/get.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; +import type { EntityAnalyticsRoutesDeps } from '../../types'; + +export const getEntityEngineRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .get({ + access: 'public', + path: '/api/entity_store/engines/{entityType}', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: buildRouteValidationWithZod(GetEntityStoreEngineRequestParams), + }, + }, + }, + + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + const secSol = await context.securitySolution; + const body = await secSol.getEntityStoreDataClient().get(request.params.entityType); + + return response.ok({ body }); + } catch (e) { + logger.error('Error in GetEntityStoreEngine:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/index.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/index.ts new file mode 100644 index 0000000000000..52aa6b22c2df8 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/index.ts @@ -0,0 +1,8 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { registerEntityStoreRoutes } from './register_entity_store_routes'; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/init.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/init.ts new file mode 100644 index 0000000000000..6159cd584b06d --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/init.ts @@ -0,0 +1,65 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; + +import type { InitEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/init.gen'; +import { + InitEntityStoreRequestBody, + InitEntityStoreRequestParams, +} from '../../../../../common/api/entity_analytics/entity_store/engine/init.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; +import type { EntityAnalyticsRoutesDeps } from '../../types'; + +export const initEntityEngineRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .post({ + access: 'public', + path: '/api/entity_store/engines/{entityType}/init', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: buildRouteValidationWithZod(InitEntityStoreRequestParams), + body: buildRouteValidationWithZod(InitEntityStoreRequestBody), + }, + }, + }, + + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + const secSol = await context.securitySolution; + + const body: InitEntityStoreResponse = await secSol + .getEntityStoreDataClient() + .init(request.params.entityType, request.body); + + return response.ok({ body }); + } catch (e) { + logger.error('Error in InitEntityStore:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/list.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/list.ts new file mode 100644 index 0000000000000..53d9a8521ce00 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/list.ts @@ -0,0 +1,57 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; + +import type { ListEntityStoreEnginesResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/list.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; + +import type { EntityAnalyticsRoutesDeps } from '../../types'; + +export const listEntityEnginesRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .get({ + access: 'public', + path: '/api/entity_store/engines', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: {}, + }, + + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + const secSol = await context.securitySolution; + const body = await secSol.getEntityStoreDataClient().list(); + + return response.ok({ body }); + } catch (e) { + logger.error('Error in ListEntityStoreEngines:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/register_entity_store_routes.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/register_entity_store_routes.ts new file mode 100644 index 0000000000000..b78316b02c91e --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/register_entity_store_routes.ts @@ -0,0 +1,23 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { EntityAnalyticsRoutesDeps } from '../../types'; +import { deleteEntityEngineRoute } from './delete'; +import { getEntityEngineRoute } from './get'; +import { initEntityEngineRoute } from './init'; +import { listEntityEnginesRoute } from './list'; +import { startEntityEngineRoute } from './start'; +import { stopEntityEngineRoute } from './stop'; + +export const registerEntityStoreRoutes = ({ router, logger }: EntityAnalyticsRoutesDeps) => { + initEntityEngineRoute(router, logger); + startEntityEngineRoute(router, logger); + stopEntityEngineRoute(router, logger); + deleteEntityEngineRoute(router, logger); + getEntityEngineRoute(router, logger); + listEntityEnginesRoute(router, logger); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/start.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/start.ts new file mode 100644 index 0000000000000..6ec6674a5473d --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/start.ts @@ -0,0 +1,59 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; + +import type { StartEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/start.gen'; +import { StartEntityStoreRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/start.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; +import type { EntityAnalyticsRoutesDeps } from '../../types'; +import { ENGINE_STATUS } from '../constants'; + +export const startEntityEngineRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .post({ + access: 'public', + path: '/api/entity_store/engines/{entityType}/start', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: buildRouteValidationWithZod(StartEntityStoreRequestParams), + }, + }, + }, + + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + const secSol = await context.securitySolution; + const engine = await secSol.getEntityStoreDataClient().start(request.params.entityType); + + return response.ok({ body: { started: engine.status === ENGINE_STATUS.STARTED } }); + } catch (e) { + logger.error('Error in StartEntityStore:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts new file mode 100644 index 0000000000000..1d7534c17f747 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts @@ -0,0 +1,58 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; + +import type { GetEntityStoreStatsResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/stats.gen'; +import { GetEntityStoreStatsRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/stats.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; +import type { EntityAnalyticsRoutesDeps } from '../../types'; + +export const getEntityEngineStatsRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .post({ + access: 'public', + path: '/api/entity_store/engines/{entityType}/stats', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: buildRouteValidationWithZod(GetEntityStoreStatsRequestParams), + }, + }, + }, + + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + // TODO + throw new Error('Not implemented'); + + // return response.ok({ body }); + } catch (e) { + logger.error('Error in GetEntityStoreStats:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stop.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stop.ts new file mode 100644 index 0000000000000..e1ddb464d1204 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stop.ts @@ -0,0 +1,59 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IKibanaResponse, Logger } from '@kbn/core/server'; +import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; +import { transformError } from '@kbn/securitysolution-es-utils'; +import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; + +import type { StopEntityStoreResponse } from '../../../../../common/api/entity_analytics/entity_store/engine/stop.gen'; +import { StopEntityStoreRequestParams } from '../../../../../common/api/entity_analytics/entity_store/engine/stop.gen'; +import { API_VERSIONS, APP_ID } from '../../../../../common/constants'; +import type { EntityAnalyticsRoutesDeps } from '../../types'; +import { ENGINE_STATUS } from '../constants'; + +export const stopEntityEngineRoute = ( + router: EntityAnalyticsRoutesDeps['router'], + logger: Logger +) => { + router.versioned + .post({ + access: 'public', + path: '/api/entity_store/engines/{entityType}/stop', + options: { + tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], + }, + }) + .addVersion( + { + version: API_VERSIONS.public.v1, + validate: { + request: { + params: buildRouteValidationWithZod(StopEntityStoreRequestParams), + }, + }, + }, + + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + + try { + const secSol = await context.securitySolution; + const engine = await secSol.getEntityStoreDataClient().stop(request.params.entityType); + + return response.ok({ body: { stopped: engine.status === ENGINE_STATUS.STOPPED } }); + } catch (e) { + logger.error('Error in StopEntityStore:', e); + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } + ); +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor.ts new file mode 100644 index 0000000000000..9d6a7821a2a9b --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor.ts @@ -0,0 +1,76 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + SavedObjectsClientContract, + SavedObjectsFindResponse, +} from '@kbn/core-saved-objects-api-server'; +import type { EntityDefinition } from '@kbn/entities-schema'; +import type { + EngineDescriptor, + EngineStatus, + EntityType, +} from '../../../../../common/api/entity_analytics/entity_store/common.gen'; + +import { entityEngineDescriptorTypeName } from './engine_descriptor_type'; +import { getByEntityTypeQuery, getEntityDefinition } from '../utils/utils'; +import { ENGINE_STATUS } from '../constants'; + +export class EngineDescriptorClient { + constructor(private readonly soClient: SavedObjectsClientContract) {} + + async init(entityType: EntityType, definition: EntityDefinition, filter: string) { + const engineDescriptor = await this.find(entityType); + + if (engineDescriptor.total > 0) + throw new Error(`Entity engine for ${entityType} already exists`); + + const { attributes } = await this.soClient.create( + entityEngineDescriptorTypeName, + { + status: ENGINE_STATUS.INSTALLING, + type: entityType, + indexPattern: definition.indexPatterns.join(','), + filter, + }, + { id: definition.id } + ); + return attributes; + } + + async update(id: string, status: EngineStatus) { + const { attributes } = await this.soClient.update( + entityEngineDescriptorTypeName, + id, + { status }, + { refresh: 'wait_for' } + ); + return attributes; + } + + async find(entityType: EntityType): Promise> { + return this.soClient.find({ + type: entityEngineDescriptorTypeName, + filter: getByEntityTypeQuery(entityType), + }); + } + + async get(entityType: EntityType): Promise { + const { id } = getEntityDefinition(entityType); + + const { attributes } = await this.soClient.get( + entityEngineDescriptorTypeName, + id + ); + + return attributes; + } + + async delete(id: string) { + return this.soClient.delete(entityEngineDescriptorTypeName, id); + } +} diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor_type.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor_type.ts new file mode 100644 index 0000000000000..8513dfc018623 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/engine_descriptor_type.ts @@ -0,0 +1,36 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; +import type { SavedObjectsType } from '@kbn/core/server'; + +export const entityEngineDescriptorTypeName = 'entity-engine-status'; + +export const entityEngineDescriptorTypeMappings: SavedObjectsType['mappings'] = { + dynamic: false, + properties: { + indexPattern: { + type: 'keyword', + }, + filter: { + type: 'keyword', + }, + type: { + type: 'keyword', // EntityType: user | host + }, + status: { + type: 'keyword', // EngineStatus: installing | started | stopped + }, + }, +}; +export const entityEngineDescriptorType: SavedObjectsType = { + name: entityEngineDescriptorTypeName, + indexPattern: SECURITY_SOLUTION_SAVED_OBJECT_INDEX, + hidden: false, + namespaceType: 'multiple-isolated', + mappings: entityEngineDescriptorTypeMappings, +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/index.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/index.ts new file mode 100644 index 0000000000000..d86800da1b5be --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/saved_object/index.ts @@ -0,0 +1,8 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './engine_descriptor_type'; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/utils/utils.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/utils/utils.ts new file mode 100644 index 0000000000000..864fdb2367eb5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/utils/utils.ts @@ -0,0 +1,33 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectsFindResponse } from '@kbn/core-saved-objects-api-server'; +import type { + EngineDescriptor, + EntityType, +} from '../../../../../common/api/entity_analytics/entity_store/common.gen'; +import { HOST_ENTITY_DEFINITION, USER_ENTITY_DEFINITION } from '../definition'; +import { entityEngineDescriptorTypeName } from '../saved_object'; + +export const getEntityDefinition = (entityType: EntityType) => { + if (entityType === 'host') return HOST_ENTITY_DEFINITION; + if (entityType === 'user') return USER_ENTITY_DEFINITION; + + throw new Error(`Unsupported entity type: ${entityType}`); +}; + +export const ensureEngineExists = + (entityType: EntityType) => (results: SavedObjectsFindResponse) => { + if (results.total === 0) { + throw new Error(`Entity engine for ${entityType} does not exist`); + } + return results.saved_objects[0].attributes; + }; + +export const getByEntityTypeQuery = (entityType: EntityType) => { + return `${entityEngineDescriptorTypeName}.attributes.type: ${entityType}`; +}; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/register_entity_analytics_routes.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/register_entity_analytics_routes.ts index 31a7ccbb6f30c..b4eb0d36e21fb 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/register_entity_analytics_routes.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/register_entity_analytics_routes.ts @@ -9,9 +9,13 @@ import { registerAssetCriticalityRoutes } from './asset_criticality/routes'; import { registerRiskScoreRoutes } from './risk_score/routes'; import { registerRiskEngineRoutes } from './risk_engine/routes'; import type { EntityAnalyticsRoutesDeps } from './types'; +import { registerEntityStoreRoutes } from './entity_store/routes'; export const registerEntityAnalyticsRoutes = (routeDeps: EntityAnalyticsRoutesDeps) => { registerAssetCriticalityRoutes(routeDeps); registerRiskScoreRoutes(routeDeps); registerRiskEngineRoutes(routeDeps); + if (routeDeps.config.experimentalFeatures.entityStoreEnabled) { + registerEntityStoreRoutes(routeDeps); + } }; diff --git a/x-pack/plugins/security_solution/server/request_context_factory.ts b/x-pack/plugins/security_solution/server/request_context_factory.ts index 4bda7e0338aa8..6316ed3622841 100644 --- a/x-pack/plugins/security_solution/server/request_context_factory.ts +++ b/x-pack/plugins/security_solution/server/request_context_factory.ts @@ -10,6 +10,7 @@ import { memoize } from 'lodash'; import type { Logger, KibanaRequest, RequestHandlerContext } from '@kbn/core/server'; import type { BuildFlavor } from '@kbn/config'; +import { EntityClient } from '@kbn/entityManager-plugin/server/lib/entity_client'; import { DEFAULT_SPACE_ID } from '../common/constants'; import { AppClientFactory } from './client'; import type { ConfigType } from './config'; @@ -31,6 +32,7 @@ import { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_scor import { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality'; import { createDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client'; import { buildMlAuthz } from './lib/machine_learning/authz'; +import { EntityStoreDataClient } from './lib/entity_analytics/entity_store/entity_store_data_client'; export interface IRequestContextFactory { create( @@ -190,6 +192,22 @@ export class RequestContextFactory implements IRequestContextFactory { auditLogger: getAuditLogger(), }) ), + getEntityStoreDataClient: memoize(() => { + const esClient = coreContext.elasticsearch.client.asCurrentUser; + const logger = options.logger; + const soClient = coreContext.savedObjects.client; + return new EntityStoreDataClient({ + namespace: getSpaceId(), + esClient, + logger, + soClient, + entityClient: new EntityClient({ + esClient, + soClient, + logger, + }), + }); + }), }; } } diff --git a/x-pack/plugins/security_solution/server/saved_objects.ts b/x-pack/plugins/security_solution/server/saved_objects.ts index 3659b15a04714..9412e62e6315c 100644 --- a/x-pack/plugins/security_solution/server/saved_objects.ts +++ b/x-pack/plugins/security_solution/server/saved_objects.ts @@ -15,6 +15,7 @@ import { prebuiltRuleAssetType } from './lib/detection_engine/prebuilt_rules'; import { type as signalsMigrationType } from './lib/detection_engine/migrations/saved_objects'; import { manifestType, unifiedManifestType } from './endpoint/lib/artifacts/saved_object_mappings'; import { riskEngineConfigurationType } from './lib/entity_analytics/risk_engine/saved_object'; +import { entityEngineDescriptorType } from './lib/entity_analytics/entity_store/saved_object'; const types = [ noteType, @@ -26,6 +27,7 @@ const types = [ unifiedManifestType, signalsMigrationType, riskEngineConfigurationType, + entityEngineDescriptorType, protectionUpdatesNoteType, ]; diff --git a/x-pack/plugins/security_solution/server/types.ts b/x-pack/plugins/security_solution/server/types.ts index 121eb7b1758f4..31e10b70adbcf 100644 --- a/x-pack/plugins/security_solution/server/types.ts +++ b/x-pack/plugins/security_solution/server/types.ts @@ -34,6 +34,7 @@ import type { RiskEngineDataClient } from './lib/entity_analytics/risk_engine/ri import type { RiskScoreDataClient } from './lib/entity_analytics/risk_score/risk_score_data_client'; import type { AssetCriticalityDataClient } from './lib/entity_analytics/asset_criticality'; import type { IDetectionRulesClient } from './lib/detection_engine/rule_management/logic/detection_rules_client/detection_rules_client_interface'; +import type { EntityStoreDataClient } from './lib/entity_analytics/entity_store/entity_store_data_client'; export { AppClient }; export interface SecuritySolutionApiRequestHandlerContext { @@ -55,6 +56,7 @@ export interface SecuritySolutionApiRequestHandlerContext { getRiskEngineDataClient: () => RiskEngineDataClient; getRiskScoreDataClient: () => RiskScoreDataClient; getAssetCriticalityDataClient: () => AssetCriticalityDataClient; + getEntityStoreDataClient: () => EntityStoreDataClient; } export type SecuritySolutionRequestHandlerContext = CustomRequestHandlerContext<{ diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 6ccd61fd34394..8264a50988956 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -223,5 +223,7 @@ "@kbn/cloud-security-posture", "@kbn/security-solution-distribution-bar", "@kbn/cloud-security-posture-common", + "@kbn/entityManager-plugin", + "@kbn/entities-schema", ] } diff --git a/x-pack/test/api_integration/services/security_solution_api.gen.ts b/x-pack/test/api_integration/services/security_solution_api.gen.ts index cf9722e89b408..6a3d0cf8f3dce 100644 --- a/x-pack/test/api_integration/services/security_solution_api.gen.ts +++ b/x-pack/test/api_integration/services/security_solution_api.gen.ts @@ -37,6 +37,10 @@ import { CreateUpdateProtectionUpdatesNoteRequestBodyInput, } from '@kbn/security-solution-plugin/common/api/endpoint/protection_updates_note/protection_updates_note.gen'; import { DeleteAssetCriticalityRecordRequestQueryInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/asset_criticality/delete_asset_criticality.gen'; +import { + DeleteEntityStoreRequestQueryInput, + DeleteEntityStoreRequestParamsInput, +} from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/delete.gen'; import { DeleteNoteRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/delete_note/delete_note_route.gen'; import { DeleteRuleRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen'; import { DeleteTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/delete_timelines/delete_timelines_route.gen'; @@ -76,6 +80,8 @@ import { GetEndpointSuggestionsRequestParamsInput, GetEndpointSuggestionsRequestBodyInput, } from '@kbn/security-solution-plugin/common/api/endpoint/suggestions/get_suggestions.gen'; +import { GetEntityStoreEngineRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/get.gen'; +import { GetEntityStoreStatsRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/stats.gen'; import { GetNotesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_notes/get_notes_route.gen'; import { GetPolicyResponseRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/policy_response.gen'; import { GetProtectionUpdatesNoteRequestParamsInput } from '@kbn/security-solution-plugin/common/api/endpoint/protection_updates_note/protection_updates_note.gen'; @@ -91,6 +97,10 @@ import { GetTimelineRequestQueryInput } from '@kbn/security-solution-plugin/comm import { GetTimelinesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/timeline/get_timelines/get_timelines_route.gen'; import { ImportRulesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen'; import { ImportTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/import_timelines/import_timelines_route.gen'; +import { + InitEntityStoreRequestParamsInput, + InitEntityStoreRequestBodyInput, +} from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/init.gen'; import { InstallPrepackedTimelinesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/install_prepackaged_timelines/install_prepackaged_timelines_route.gen'; import { PatchRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen'; import { PatchTimelineRequestBodyInput } from '@kbn/security-solution-plugin/common/api/timeline/patch_timelines/patch_timeline_route.gen'; @@ -110,6 +120,8 @@ import { SearchAlertsRequestBodyInput } from '@kbn/security-solution-plugin/comm import { SetAlertAssigneesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen'; import { SetAlertsStatusRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/signals/set_signal_status/set_signals_status_route.gen'; import { SetAlertTagsRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/alert_tags/set_alert_tags/set_alert_tags.gen'; +import { StartEntityStoreRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/start.gen'; +import { StopEntityStoreRequestParamsInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/entity_store/engine/stop.gen'; import { SuggestUserProfilesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/users/suggest_user_profiles_route.gen'; import { TriggerRiskScoreCalculationRequestBodyInput } from '@kbn/security-solution-plugin/common/api/entity_analytics/risk_engine/entity_calculation_route.gen'; import { UpdateRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen'; @@ -313,6 +325,14 @@ Migrations are initiated per index. While the process is neither destructive nor .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .query(props.query); }, + deleteEntityStore(props: DeleteEntityStoreProps) { + return supertest + .delete(replaceParams('/api/entity_store/engines/{entityType}', props.params)) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .query(props.query); + }, deleteNote(props: DeleteNoteProps) { return supertest .delete('/api/note') @@ -668,6 +688,20 @@ finalize it. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + getEntityStoreEngine(props: GetEntityStoreEngineProps) { + return supertest + .get(replaceParams('/api/entity_store/engines/{entityType}', props.params)) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + }, + getEntityStoreStats(props: GetEntityStoreStatsProps) { + return supertest + .post(replaceParams('/api/entity_store/engines/{entityType}/stats', props.params)) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + }, /** * Gets notes */ @@ -764,6 +798,14 @@ finalize it. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + initEntityStore(props: InitEntityStoreProps) { + return supertest + .post(replaceParams('/api/entity_store/engines/{entityType}/init', props.params)) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(props.body as object); + }, /** * Initializes the Risk Engine by creating the necessary indices and mappings, removing old transforms, and starting the new risk engine */ @@ -799,6 +841,13 @@ finalize it. .set(ELASTIC_HTTP_VERSION_HEADER, '1') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, + listEntityStoreEngines() { + return supertest + .get('/api/entity_store/engines') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + }, /** * Update specific fields of an existing detection rule using the `rule_id` or `id` field. */ @@ -1018,6 +1067,20 @@ detection engine rules. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + startEntityStore(props: StartEntityStoreProps) { + return supertest + .post(replaceParams('/api/entity_store/engines/{entityType}/start', props.params)) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + }, + stopEntityStore(props: StopEntityStoreProps) { + return supertest + .post(replaceParams('/api/entity_store/engines/{entityType}/stop', props.params)) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); + }, /** * Suggests user profiles. */ @@ -1107,6 +1170,10 @@ export interface CreateUpdateProtectionUpdatesNoteProps { export interface DeleteAssetCriticalityRecordProps { query: DeleteAssetCriticalityRecordRequestQueryInput; } +export interface DeleteEntityStoreProps { + query: DeleteEntityStoreRequestQueryInput; + params: DeleteEntityStoreRequestParamsInput; +} export interface DeleteNoteProps { body: DeleteNoteRequestBodyInput; } @@ -1200,6 +1267,12 @@ export interface GetEndpointSuggestionsProps { params: GetEndpointSuggestionsRequestParamsInput; body: GetEndpointSuggestionsRequestBodyInput; } +export interface GetEntityStoreEngineProps { + params: GetEntityStoreEngineRequestParamsInput; +} +export interface GetEntityStoreStatsProps { + params: GetEntityStoreStatsRequestParamsInput; +} export interface GetNotesProps { query: GetNotesRequestQueryInput; } @@ -1229,6 +1302,10 @@ export interface ImportRulesProps { export interface ImportTimelinesProps { body: ImportTimelinesRequestBodyInput; } +export interface InitEntityStoreProps { + params: InitEntityStoreRequestParamsInput; + body: InitEntityStoreRequestBodyInput; +} export interface InstallPrepackedTimelinesProps { body: InstallPrepackedTimelinesRequestBodyInput; } @@ -1278,6 +1355,12 @@ export interface SetAlertsStatusProps { export interface SetAlertTagsProps { body: SetAlertTagsRequestBodyInput; } +export interface StartEntityStoreProps { + params: StartEntityStoreRequestParamsInput; +} +export interface StopEntityStoreProps { + params: StopEntityStoreRequestParamsInput; +} export interface SuggestUserProfilesProps { query: SuggestUserProfilesRequestQueryInput; } diff --git a/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts index 07dbcf7ded031..5cf491188ba96 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/platform_security/authorization.ts @@ -349,6 +349,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:risk-engine-configuration/delete", "saved_object:risk-engine-configuration/bulk_delete", "saved_object:risk-engine-configuration/share_to_space", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", + "saved_object:entity-engine-status/create", + "saved_object:entity-engine-status/bulk_create", + "saved_object:entity-engine-status/update", + "saved_object:entity-engine-status/bulk_update", + "saved_object:entity-engine-status/delete", + "saved_object:entity-engine-status/bulk_delete", + "saved_object:entity-engine-status/share_to_space", "saved_object:policy-settings-protection-updates-note/bulk_get", "saved_object:policy-settings-protection-updates-note/get", "saved_object:policy-settings-protection-updates-note/find", @@ -1182,6 +1194,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:risk-engine-configuration/delete", "saved_object:risk-engine-configuration/bulk_delete", "saved_object:risk-engine-configuration/share_to_space", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", + "saved_object:entity-engine-status/create", + "saved_object:entity-engine-status/bulk_create", + "saved_object:entity-engine-status/update", + "saved_object:entity-engine-status/bulk_update", + "saved_object:entity-engine-status/delete", + "saved_object:entity-engine-status/bulk_delete", + "saved_object:entity-engine-status/share_to_space", "saved_object:policy-settings-protection-updates-note/bulk_get", "saved_object:policy-settings-protection-updates-note/get", "saved_object:policy-settings-protection-updates-note/find", @@ -1779,6 +1803,11 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:risk-engine-configuration/find", "saved_object:risk-engine-configuration/open_point_in_time", "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", "saved_object:policy-settings-protection-updates-note/bulk_get", "saved_object:policy-settings-protection-updates-note/get", "saved_object:policy-settings-protection-updates-note/find", @@ -2135,6 +2164,11 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:risk-engine-configuration/find", "saved_object:risk-engine-configuration/open_point_in_time", "saved_object:risk-engine-configuration/close_point_in_time", + "saved_object:entity-engine-status/bulk_get", + "saved_object:entity-engine-status/get", + "saved_object:entity-engine-status/find", + "saved_object:entity-engine-status/open_point_in_time", + "saved_object:entity-engine-status/close_point_in_time", "saved_object:policy-settings-protection-updates-note/bulk_get", "saved_object:policy-settings-protection-updates-note/get", "saved_object:policy-settings-protection-updates-note/find", From 6755cc180860653c9ec6f3891231a8f69f929c69 Mon Sep 17 00:00:00 2001 From: Stef Nestor <26751266+stefnestor@users.noreply.github.com> Date: Mon, 16 Sep 2024 09:38:46 -0600 Subject: [PATCH 029/139] (Doc+) link video to checking health (#193023) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary 👋 howdy team! Ongoing improvement for common support topic, this links [this video walkthrough](https://www.youtube.com/watch?v=AlgGYcpGvOA&list=PL_mJOmq4zsHbQlfEMEh_30_LuV_hZp-3d&index=3) on checking Kibana health. ### Checklist NA ### Risk Matrix NA ### For maintainers NA --------- Co-authored-by: florent-leborgne --- docs/setup/access.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/setup/access.asciidoc b/docs/setup/access.asciidoc index a0bd1207a6a35..3b6457b42f04d 100644 --- a/docs/setup/access.asciidoc +++ b/docs/setup/access.asciidoc @@ -65,4 +65,4 @@ For example: * When {kib} is unable to connect to a healthy {es} cluster, errors like `master_not_discovered_exception` or `unable to revive connection` or `license is not available` errors appear. * When one or more {kib}-backing indices are unhealthy, the `index_not_green_timeout` error appears. -For more information, refer to our https://www.elastic.co/blog/troubleshooting-kibana-health[walkthrough on troubleshooting Kibana Health]. +You can find a Kibana health troubleshooting walkthrough in https://www.elastic.co/blog/troubleshooting-kibana-health[this blog] or in link:https://www.youtube.com/watch?v=AlgGYcpGvOA[this video]. From 4d488818dc5503c40617d01512cd89c05e1e0345 Mon Sep 17 00:00:00 2001 From: Joe McElroy Date: Mon, 16 Sep 2024 17:03:01 +0100 Subject: [PATCH 030/139] [Onboarding] Connection details + Quick Stats (#192636) ## Summary Adding in the connection details and quickstats for the search_details page. ![Screenshot 2024-09-11 at 20 36 31](https://github.com/user-attachments/assets/5f030c06-4a98-4d9d-a465-c6719998ca56) ![Screenshot 2024-09-11 at 20 36 27](https://github.com/user-attachments/assets/d96be2f1-bcaa-42e5-9d32-1612e090b916) ![Screenshot 2024-09-11 at 20 36 09](https://github.com/user-attachments/assets/1f7995ae-5a0d-4810-acfb-3fafe33be451) ### Checklist Delete any items that are not applicable to this PR. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Liam Thompson <32779855+leemthompo@users.noreply.github.com> --- packages/kbn-doc-links/src/get_doc_links.ts | 1 + packages/kbn-doc-links/src/types.ts | 1 + .../search_indices/common/doc_links.ts | 2 + .../connection_details/connection_details.tsx | 73 ++++++++ .../components/indices/details_page.tsx | 32 +++- .../quick_stats/mappings_convertor.test.ts | 41 +++++ .../quick_stats/mappings_convertor.ts | 62 +++++++ .../components/quick_stats/quick_stat.tsx | 116 ++++++++++++ .../components/quick_stats/quick_stats.tsx | 167 ++++++++++++++++++ .../components/start/create_index_code.tsx | 10 +- .../public/hooks/api/use_index_mappings.ts | 22 +++ .../public/hooks/use_elasticsearch_url.ts | 18 ++ x-pack/plugins/search_indices/public/types.ts | 8 + .../svl_search_index_detail_page.ts | 34 ++++ .../test_suites/search/search_index_detail.ts | 25 +++ 15 files changed, 603 insertions(+), 9 deletions(-) create mode 100644 x-pack/plugins/search_indices/public/components/connection_details/connection_details.tsx create mode 100644 x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.test.ts create mode 100644 x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.ts create mode 100644 x-pack/plugins/search_indices/public/components/quick_stats/quick_stat.tsx create mode 100644 x-pack/plugins/search_indices/public/components/quick_stats/quick_stats.tsx create mode 100644 x-pack/plugins/search_indices/public/hooks/api/use_index_mappings.ts create mode 100644 x-pack/plugins/search_indices/public/hooks/use_elasticsearch_url.ts diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index d2ac9c6678797..3ad5d271bde47 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -219,6 +219,7 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D searchApplicationsSearch: `${ELASTICSEARCH_DOCS}search-application-client.html`, searchLabs: `${SEARCH_LABS_URL}`, searchLabsRepo: `${SEARCH_LABS_REPO}`, + semanticSearch: `${ELASTICSEARCH_DOCS}semantic-search.html`, searchTemplates: `${ELASTICSEARCH_DOCS}search-template.html`, semanticTextField: `${ELASTICSEARCH_DOCS}semantic-text.html`, start: `${ENTERPRISE_SEARCH_DOCS}start.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index ae6e56a9ac385..cbf085623c3a6 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -183,6 +183,7 @@ export interface DocLinks { readonly searchApplicationsSearch: string; readonly searchLabs: string; readonly searchLabsRepo: string; + readonly semanticSearch: string; readonly searchTemplates: string; readonly semanticTextField: string; readonly start: string; diff --git a/x-pack/plugins/search_indices/common/doc_links.ts b/x-pack/plugins/search_indices/common/doc_links.ts index dbffa8f9f0f33..8cceb45041ab9 100644 --- a/x-pack/plugins/search_indices/common/doc_links.ts +++ b/x-pack/plugins/search_indices/common/doc_links.ts @@ -9,11 +9,13 @@ import { DocLinks } from '@kbn/doc-links'; class SearchIndicesDocLinks { public apiReference: string = ''; + public setupSemanticSearch: string = ''; constructor() {} setDocLinks(newDocLinks: DocLinks) { this.apiReference = newDocLinks.apiReference; + this.setupSemanticSearch = newDocLinks.enterpriseSearch.semanticSearch; } } export const docLinks = new SearchIndicesDocLinks(); diff --git a/x-pack/plugins/search_indices/public/components/connection_details/connection_details.tsx b/x-pack/plugins/search_indices/public/components/connection_details/connection_details.tsx new file mode 100644 index 0000000000000..d7ce8f308b683 --- /dev/null +++ b/x-pack/plugins/search_indices/public/components/connection_details/connection_details.tsx @@ -0,0 +1,73 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { + EuiButtonIcon, + EuiCopy, + EuiFlexGroup, + EuiFlexItem, + EuiTitle, + useEuiTheme, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { FormattedMessage } from '@kbn/i18n-react'; +import { useElasticsearchUrl } from '../../hooks/use_elasticsearch_url'; + +export const ConnectionDetails: React.FC = () => { + const { euiTheme } = useEuiTheme(); + const elasticsearchUrl = useElasticsearchUrl(); + + return ( + + + +

+ +

+
+
+ +

+ {elasticsearchUrl} +

+
+ + + {(copy) => ( + + )} + + +
+ ); +}; diff --git a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx index afa798814d864..85021e79edbf2 100644 --- a/x-pack/plugins/search_indices/public/components/indices/details_page.tsx +++ b/x-pack/plugins/search_indices/public/components/indices/details_page.tsx @@ -27,13 +27,22 @@ import { i18n } from '@kbn/i18n'; import { SectionLoading } from '@kbn/es-ui-shared-plugin/public'; import { useIndex } from '../../hooks/api/use_index'; import { useKibana } from '../../hooks/use_kibana'; +import { ConnectionDetails } from '../connection_details/connection_details'; +import { QuickStats } from '../quick_stats/quick_stats'; +import { useIndexMapping } from '../../hooks/api/use_index_mappings'; import { DeleteIndexModal } from './delete_index_modal'; import { IndexloadingError } from './details_page_loading_error'; export const SearchIndexDetailsPage = () => { const indexName = decodeURIComponent(useParams<{ indexName: string }>().indexName); const { console: consolePlugin, docLinks, application } = useKibana().services; - const { data: index, refetch, isSuccess, isInitialLoading } = useIndex(indexName); + + const { data: index, refetch, isError: isIndexError, isInitialLoading } = useIndex(indexName); + const { + data: mappings, + isError: isMappingsError, + isInitialLoading: isMappingsInitialLoading, + } = useIndexMapping(indexName); const embeddableConsole = useMemo( () => (consolePlugin?.EmbeddableConsole ? : null), @@ -87,7 +96,7 @@ export const SearchIndexDetailsPage = () => { /> ); - if (isInitialLoading) { + if (isInitialLoading || isMappingsInitialLoading) { return ( {i18n.translate('xpack.searchIndices.loadingDescription', { @@ -103,9 +112,10 @@ export const SearchIndexDetailsPage = () => { restrictWidth={false} data-test-subj="searchIndicesDetailsPage" grow={false} - bottomBorder={false} + panelled + bottomBorder > - {!isSuccess || !index ? ( + {isIndexError || isMappingsError || !index || !mappings ? ( { navigateToIndexListPage={navigateToIndexListPage} /> )} + + + + + + {/* TODO: API KEY */} + + + -
+ + + + )} {embeddableConsole} diff --git a/x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.test.ts b/x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.test.ts new file mode 100644 index 0000000000000..da182123ab4c1 --- /dev/null +++ b/x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.test.ts @@ -0,0 +1,41 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Mappings } from '../../types'; +import { countVectorBasedTypesFromMappings } from './mappings_convertor'; + +describe('mappings convertor', () => { + it('should count vector based types from mappings', () => { + const mappings = { + mappings: { + properties: { + field1: { + type: 'dense_vector', + }, + field2: { + type: 'dense_vector', + }, + field3: { + type: 'sparse_vector', + }, + field4: { + type: 'dense_vector', + }, + field5: { + type: 'semantic_text', + }, + }, + }, + }; + const result = countVectorBasedTypesFromMappings(mappings as unknown as Mappings); + expect(result).toEqual({ + dense_vector: 3, + sparse_vector: 1, + semantic_text: 1, + }); + }); +}); diff --git a/x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.ts b/x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.ts new file mode 100644 index 0000000000000..749fe05de1f54 --- /dev/null +++ b/x-pack/plugins/search_indices/public/components/quick_stats/mappings_convertor.ts @@ -0,0 +1,62 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + MappingProperty, + MappingPropertyBase, +} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { Mappings } from '../../types'; + +interface VectorFieldTypes { + semantic_text: number; + dense_vector: number; + sparse_vector: number; +} + +export function countVectorBasedTypesFromMappings(mappings: Mappings): VectorFieldTypes { + const typeCounts: VectorFieldTypes = { + semantic_text: 0, + dense_vector: 0, + sparse_vector: 0, + }; + + const typeCountKeys = Object.keys(typeCounts); + + function recursiveCount(fields: MappingProperty | Mappings | MappingPropertyBase['fields']) { + if (!fields) { + return; + } + if ('mappings' in fields) { + recursiveCount(fields.mappings); + } + if ('properties' in fields && fields.properties) { + Object.keys(fields.properties).forEach((key) => { + const value = (fields.properties as Record)?.[key]; + + if (value && value.type) { + if (typeCountKeys.includes(value.type)) { + const type = value.type as keyof VectorFieldTypes; + typeCounts[type] = typeCounts[type] + 1; + } + + if ('fields' in value) { + recursiveCount(value.fields); + } + + if ('properties' in value) { + recursiveCount(value.properties); + } + } else if (value.properties || value.fields) { + recursiveCount(value); + } + }); + } + } + + recursiveCount(mappings); + return typeCounts; +} diff --git a/x-pack/plugins/search_indices/public/components/quick_stats/quick_stat.tsx b/x-pack/plugins/search_indices/public/components/quick_stats/quick_stat.tsx new file mode 100644 index 0000000000000..0d72835ad5779 --- /dev/null +++ b/x-pack/plugins/search_indices/public/components/quick_stats/quick_stat.tsx @@ -0,0 +1,116 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { + EuiAccordion, + EuiDescriptionList, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, + EuiPanel, + EuiText, + useEuiTheme, + useGeneratedHtmlId, +} from '@elastic/eui'; + +interface BaseQuickStatProps { + icon: string; + iconColor: string; + title: string; + secondaryTitle: React.ReactNode; + open: boolean; + content?: React.ReactNode; + stats: Array<{ + title: string; + description: NonNullable; + }>; + setOpen: (open: boolean) => void; + first?: boolean; +} + +export const QuickStat: React.FC = ({ + icon, + title, + stats, + open, + setOpen, + first, + secondaryTitle, + iconColor, + content, + ...rest +}) => { + const { euiTheme } = useEuiTheme(); + + const id = useGeneratedHtmlId({ + prefix: 'formAccordion', + suffix: title, + }); + + return ( + setOpen(!open)} + paddingSize="none" + id={id} + buttonElement="div" + arrowDisplay="right" + {...rest} + css={{ + borderLeft: euiTheme.border.thin, + ...(first ? { borderLeftWidth: 0 } : {}), + '.euiAccordion__arrow': { + marginRight: euiTheme.size.s, + }, + '.euiAccordion__triggerWrapper': { + background: euiTheme.colors.ghost, + }, + '.euiAccordion__children': { + borderTop: euiTheme.border.thin, + padding: euiTheme.size.m, + }, + }} + buttonContent={ + + + + + + + +

{title}

+
+
+ + {secondaryTitle} + +
+
+ } + > + {content ? ( + content + ) : ( + + + + + + )} +
+ ); +}; diff --git a/x-pack/plugins/search_indices/public/components/quick_stats/quick_stats.tsx b/x-pack/plugins/search_indices/public/components/quick_stats/quick_stats.tsx new file mode 100644 index 0000000000000..cece2b1d39910 --- /dev/null +++ b/x-pack/plugins/search_indices/public/components/quick_stats/quick_stats.tsx @@ -0,0 +1,167 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo, useState } from 'react'; +import type { Index } from '@kbn/index-management-shared-types'; + +import { + EuiFlexGroup, + EuiFlexItem, + EuiI18nNumber, + EuiPanel, + EuiText, + useEuiTheme, + EuiButton, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { Mappings } from '../../types'; +import { countVectorBasedTypesFromMappings } from './mappings_convertor'; +import { QuickStat } from './quick_stat'; +import { useKibana } from '../../hooks/use_kibana'; + +export interface QuickStatsProps { + index: Index; + mappings: Mappings; +} + +export const SetupAISearchButton: React.FC = () => { + const { + services: { docLinks }, + } = useKibana(); + return ( + + + + +
+ {i18n.translate('xpack.searchIndices.quickStats.setup_ai_search_description', { + defaultMessage: 'Build AI-powered search experiences with Elastic', + })} +
+
+
+ + + {i18n.translate('xpack.searchIndices.quickStats.setup_ai_search_button', { + defaultMessage: 'Set up now', + })} + + +
+
+ ); +}; + +export const QuickStats: React.FC = ({ index, mappings }) => { + const [open, setOpen] = useState(false); + const { euiTheme } = useEuiTheme(); + const mappingStats = useMemo(() => countVectorBasedTypesFromMappings(mappings), [mappings]); + const vectorFieldCount = + mappingStats.sparse_vector + mappingStats.dense_vector + mappingStats.semantic_text; + + return ( + ({ + border: euiTheme.border.thin, + background: euiTheme.colors.lightestShade, + overflow: 'hidden', + })} + > + + + } + stats={[ + { + title: i18n.translate('xpack.searchIndices.quickStats.documents.totalTitle', { + defaultMessage: 'Total', + }), + description: , + }, + { + title: i18n.translate('xpack.searchIndices.quickStats.documents.indexSize', { + defaultMessage: 'Index Size', + }), + description: index.size ?? '0b', + }, + ]} + first + /> + + + 0 + ? i18n.translate('xpack.searchIndices.quickStats.total_count', { + defaultMessage: '{value, plural, one {# Field} other {# Fields}}', + values: { + value: vectorFieldCount, + }, + }) + : i18n.translate('xpack.searchIndices.quickStats.no_vector_fields', { + defaultMessage: 'Not configured', + }) + } + content={vectorFieldCount === 0 && } + stats={[ + { + title: i18n.translate('xpack.searchIndices.quickStats.sparse_vector', { + defaultMessage: 'Sparse Vector', + }), + description: i18n.translate('xpack.searchIndices.quickStats.sparse_vector_count', { + defaultMessage: '{value, plural, one {# Field} other {# Fields}}', + values: { value: mappingStats.sparse_vector }, + }), + }, + { + title: i18n.translate('xpack.searchIndices.quickStats.dense_vector', { + defaultMessage: 'Dense Vector', + }), + description: i18n.translate('xpack.searchIndices.quickStats.dense_vector_count', { + defaultMessage: '{value, plural, one {# Field} other {# Fields}}', + values: { value: mappingStats.dense_vector }, + }), + }, + { + title: i18n.translate('xpack.searchIndices.quickStats.semantic_text', { + defaultMessage: 'Semantic Text', + }), + description: i18n.translate('xpack.searchIndices.quickStats.semantic_text_count', { + defaultMessage: '{value, plural, one {# Field} other {# Fields}}', + values: { value: mappingStats.semantic_text }, + }), + }, + ]} + /> + + + + ); +}; diff --git a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx index b58bf6c0926f1..4901847eeed22 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx @@ -12,12 +12,12 @@ import { TryInConsoleButton } from '@kbn/try-in-console'; import { useKibana } from '../../hooks/use_kibana'; import { CodeSample } from './code_sample'; import { CreateIndexFormState } from './types'; -import { ELASTICSEARCH_URL_PLACEHOLDER } from '../../constants'; import { Languages, AvailableLanguages, LanguageOptions } from '../../code_examples'; import { DenseVectorSeverlessCodeExamples } from '../../code_examples/create_index'; import { LanguageSelector } from '../shared/language_selector'; +import { useElasticsearchUrl } from '../../hooks/use_elasticsearch_url'; export interface CreateIndexCodeViewProps { createIndexForm: CreateIndexFormState; @@ -27,15 +27,17 @@ export interface CreateIndexCodeViewProps { const SelectedCodeExamples = DenseVectorSeverlessCodeExamples; export const CreateIndexCodeView = ({ createIndexForm }: CreateIndexCodeViewProps) => { - const { application, cloud, share, console: consolePlugin } = useKibana().services; + const { application, share, console: consolePlugin } = useKibana().services; // TODO: initing this should be dynamic and possibly saved in the form state const [selectedLanguage, setSelectedLanguage] = useState('python'); + const elasticsearchUrl = useElasticsearchUrl(); + const codeParams = useMemo(() => { return { indexName: createIndexForm.indexName || undefined, - elasticsearchURL: cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER, + elasticsearchURL: elasticsearchUrl, }; - }, [createIndexForm.indexName, cloud]); + }, [createIndexForm.indexName, elasticsearchUrl]); const selectedCodeExample = useMemo(() => { return SelectedCodeExamples[selectedLanguage]; }, [selectedLanguage]); diff --git a/x-pack/plugins/search_indices/public/hooks/api/use_index_mappings.ts b/x-pack/plugins/search_indices/public/hooks/api/use_index_mappings.ts new file mode 100644 index 0000000000000..a91198f70b4e8 --- /dev/null +++ b/x-pack/plugins/search_indices/public/hooks/api/use_index_mappings.ts @@ -0,0 +1,22 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useQuery } from '@tanstack/react-query'; +import { useKibana } from '../use_kibana'; +import { Mappings } from '../../types'; + +export const useIndexMapping = (indexName: string) => { + const { http } = useKibana().services; + const queryKey = ['fetchMapping', indexName]; + const result = useQuery({ + queryKey, + refetchOnWindowFocus: 'always', + queryFn: () => + http.fetch(`/api/index_management/mapping/${encodeURIComponent(indexName)}`), + }); + return { queryKey, ...result }; +}; diff --git a/x-pack/plugins/search_indices/public/hooks/use_elasticsearch_url.ts b/x-pack/plugins/search_indices/public/hooks/use_elasticsearch_url.ts new file mode 100644 index 0000000000000..d07cc62b210de --- /dev/null +++ b/x-pack/plugins/search_indices/public/hooks/use_elasticsearch_url.ts @@ -0,0 +1,18 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useKibana } from './use_kibana'; + +import { ELASTICSEARCH_URL_PLACEHOLDER } from '../constants'; + +export const useElasticsearchUrl = (): string => { + const { + services: { cloud }, + } = useKibana(); + + return cloud?.elasticsearchUrl ?? ELASTICSEARCH_URL_PLACEHOLDER; +}; diff --git a/x-pack/plugins/search_indices/public/types.ts b/x-pack/plugins/search_indices/public/types.ts index 8e7853543f76f..6e0192e34f87c 100644 --- a/x-pack/plugins/search_indices/public/types.ts +++ b/x-pack/plugins/search_indices/public/types.ts @@ -11,6 +11,7 @@ import type { AppMountParameters, CoreStart } from '@kbn/core/public'; import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public'; +import type { MappingPropertyBase } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; export interface SearchIndicesPluginSetup { enabled: boolean; @@ -44,11 +45,18 @@ export interface AppUsageTracker { load: (eventName: string | string[]) => void; } +export interface Mappings { + mappings: { + properties: MappingPropertyBase['properties']; + }; +} + export interface CodeSnippetParameters { indexName?: string; apiKey?: string; elasticsearchURL: string; } + export type CodeSnippetFunction = (params: CodeSnippetParameters) => string; export interface CodeLanguage { diff --git a/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts b/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts index 5ac440ce6c4f4..09b69aaed5332 100644 --- a/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts +++ b/x-pack/test_serverless/functional/page_objects/svl_search_index_detail_page.ts @@ -32,6 +32,40 @@ export function SvlSearchIndexDetailPageProvider({ getService }: FtrProviderCont async expectBackToIndicesButtonRedirectsToListPage() { await testSubjects.existOrFail('indicesList'); }, + async expectConnectionDetails() { + await testSubjects.existOrFail('connectionDetailsEndpoint', { timeout: 2000 }); + expect(await (await testSubjects.find('connectionDetailsEndpoint')).getVisibleText()).to.be( + 'https://fakeprojectid.es.fake-domain.cld.elstc.co:443' + ); + }, + async expectQuickStats() { + await testSubjects.existOrFail('quickStats', { timeout: 2000 }); + const quickStatsElem = await testSubjects.find('quickStats'); + const quickStatsDocumentElem = await quickStatsElem.findByTestSubject( + 'QuickStatsDocumentCount' + ); + expect(await quickStatsDocumentElem.getVisibleText()).to.contain('Document count\n0'); + expect(await quickStatsDocumentElem.getVisibleText()).not.to.contain('Index Size\n0b'); + await quickStatsDocumentElem.click(); + expect(await quickStatsDocumentElem.getVisibleText()).to.contain('Index Size\n0b'); + }, + async expectQuickStatsAIMappings() { + await testSubjects.existOrFail('quickStats', { timeout: 2000 }); + const quickStatsElem = await testSubjects.find('quickStats'); + const quickStatsAIMappingsElem = await quickStatsElem.findByTestSubject( + 'QuickStatsAIMappings' + ); + await quickStatsAIMappingsElem.click(); + await testSubjects.existOrFail('setupAISearchButton', { timeout: 2000 }); + }, + + async expectQuickStatsAIMappingsToHaveVectorFields() { + const quickStatsDocumentElem = await testSubjects.find('QuickStatsAIMappings'); + await quickStatsDocumentElem.click(); + expect(await quickStatsDocumentElem.getVisibleText()).to.contain('AI Search\n1 Field'); + await testSubjects.missingOrFail('setupAISearchButton', { timeout: 2000 }); + }, + async expectMoreOptionsActionButtonExists() { await testSubjects.existOrFail('moreOptionsActionButton'); }, diff --git a/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts b/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts index 9450dca44df57..cd39079274d0a 100644 --- a/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts +++ b/x-pack/test_serverless/functional/test_suites/search/search_index_detail.ts @@ -26,6 +26,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { after(async () => { await esDeleteAllIndices(indexName); }); + describe('index details page overview', () => { before(async () => { await es.indices.create({ index: indexName }); @@ -41,11 +42,35 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('should have embedded dev console', async () => { await testHasEmbeddedConsole(pageObjects); }); + it('should have connection details', async () => { + await pageObjects.svlSearchIndexDetailPage.expectConnectionDetails(); + }); + + it('should have quick stats', async () => { + await pageObjects.svlSearchIndexDetailPage.expectQuickStats(); + await pageObjects.svlSearchIndexDetailPage.expectQuickStatsAIMappings(); + await es.indices.putMapping({ + index: indexName, + body: { + properties: { + my_field: { + type: 'dense_vector', + dims: 3, + }, + }, + }, + }); + await svlSearchNavigation.navigateToIndexDetailPage(indexName); + + await pageObjects.svlSearchIndexDetailPage.expectQuickStatsAIMappingsToHaveVectorFields(); + }); + it('back to indices button should redirect to list page', async () => { await pageObjects.svlSearchIndexDetailPage.expectBackToIndicesButtonExists(); await pageObjects.svlSearchIndexDetailPage.clickBackToIndicesButton(); await pageObjects.svlSearchIndexDetailPage.expectBackToIndicesButtonRedirectsToListPage(); }); + describe('page loading error', () => { before(async () => { await svlSearchNavigation.navigateToIndexDetailPage(indexName); From 684da232053c70c8bf3009fb40357c33e607a640 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Mon, 16 Sep 2024 12:16:07 -0400 Subject: [PATCH 031/139] chore(rca): Hide X axis on ESQL item (#192696) --- .../items/esql_item/register_esql_item.tsx | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx index 5f2f95807b4e0..7e64db5557fc2 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx @@ -4,8 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; -import { css } from '@emotion/css'; +import { EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; import type { DataView } from '@kbn/data-views-plugin/common'; import type { ESQLSearchResponse } from '@kbn/es-types'; import { i18n } from '@kbn/i18n'; @@ -123,29 +122,24 @@ export function EsqlWidget({ suggestion, dataView, esqlQuery, dateHistogramResul [dataView, lens, dateHistogramResults] ); + // in the case of a lnsDatatable, we want to render the preview of the histogram and not the datable (input) itself if (input.attributes.visualizationType === 'lnsDatatable') { let innerElement: React.ReactElement; if (previewInput.error) { innerElement = ; } else if (previewInput.value) { - innerElement = ; + innerElement = ( + + ); } else { innerElement = ; } - return ( - - div { - height: 128px; - } - `} - > - {innerElement} - - - ); + + return {innerElement}; } return ( From 3ad697b74fdf09049464c4a7a8f2cd44550709f0 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Mon, 16 Sep 2024 12:20:33 -0400 Subject: [PATCH 032/139] [Synthetics] persist refresh interval in local storage (#191333) ## Summary Stores refresh interval and refresh paused state in local storage. Also defaults refresh to paused rather than active. --------- Co-authored-by: Shahzad --- .../constants/synthetics/client_defaults.ts | 6 +- .../common/components/auto_refresh_button.tsx | 64 ++----------------- .../common/components/last_refreshed.tsx | 6 +- .../hooks/use_selected_monitor.tsx | 5 +- .../contexts/synthetics_refresh_context.tsx | 55 ++++++++++++++-- .../apps/synthetics/state/ui/actions.ts | 2 - .../public/apps/synthetics/state/ui/index.ts | 14 ---- .../apps/synthetics/state/ui/selectors.ts | 9 --- .../__mocks__/synthetics_store.mock.ts | 2 - .../get_supported_url_params.test.ts | 9 +-- .../url_params/get_supported_url_params.ts | 11 +--- .../url_params/stringify_url_params.test.ts | 10 +-- .../utils/url_params/stringify_url_params.ts | 9 +-- 13 files changed, 64 insertions(+), 138 deletions(-) diff --git a/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/client_defaults.ts b/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/client_defaults.ts index 6ae9dbfef955f..3e5722ce59f10 100644 --- a/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/client_defaults.ts +++ b/x-pack/plugins/observability_solution/synthetics/common/constants/synthetics/client_defaults.ts @@ -16,11 +16,11 @@ export const CLIENT_DEFAULTS_SYNTHETICS = { DATE_RANGE_END: 'now', /** - * The application auto refreshes every 30s by default. + * The application auto refreshes every 60s by default. */ AUTOREFRESH_INTERVAL_SECONDS: 60, /** - * The application's autorefresh feature is enabled. + * The application's autorefresh feature is disabled by default. */ - AUTOREFRESH_IS_PAUSED: false, + AUTOREFRESH_IS_PAUSED: true, }; diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/auto_refresh_button.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/auto_refresh_button.tsx index 6f40b000a6873..cea6a7d726926 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/auto_refresh_button.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/auto_refresh_button.tsx @@ -5,69 +5,17 @@ * 2.0. */ -import React, { useEffect, useRef } from 'react'; +import React from 'react'; import { EuiAutoRefreshButton, OnRefreshChangeProps } from '@elastic/eui'; -import { useDispatch, useSelector } from 'react-redux'; -import { CLIENT_DEFAULTS_SYNTHETICS } from '../../../../../../common/constants/synthetics/client_defaults'; -import { SyntheticsUrlParams } from '../../../utils/url_params'; -import { useUrlParams } from '../../../hooks'; -import { - selectRefreshInterval, - selectRefreshPaused, - setRefreshIntervalAction, - setRefreshPausedAction, -} from '../../../state'; -const { AUTOREFRESH_INTERVAL_SECONDS, AUTOREFRESH_IS_PAUSED } = CLIENT_DEFAULTS_SYNTHETICS; +import { useSyntheticsRefreshContext } from '../../../contexts/synthetics_refresh_context'; -const replaceDefaults = ({ refreshPaused, refreshInterval }: Partial) => { - return { - refreshInterval: refreshInterval === AUTOREFRESH_INTERVAL_SECONDS ? undefined : refreshInterval, - refreshPaused: refreshPaused === AUTOREFRESH_IS_PAUSED ? undefined : refreshPaused, - }; -}; export const AutoRefreshButton = () => { - const dispatch = useDispatch(); - - const refreshPaused = useSelector(selectRefreshPaused); - const refreshInterval = useSelector(selectRefreshInterval); - - const [getUrlsParams, updateUrlParams] = useUrlParams(); - - const { refreshInterval: urlRefreshInterval, refreshPaused: urlIsPaused } = getUrlsParams(); - - const isFirstRender = useRef(true); - - useEffect(() => { - if (isFirstRender.current) { - // sync url state with redux state on first render - dispatch(setRefreshIntervalAction(urlRefreshInterval)); - dispatch(setRefreshPausedAction(urlIsPaused)); - isFirstRender.current = false; - } else { - // sync redux state with url state on subsequent renders - if (urlRefreshInterval !== refreshInterval || urlIsPaused !== refreshPaused) { - updateUrlParams( - replaceDefaults({ - refreshInterval, - refreshPaused, - }), - true - ); - } - } - }, [updateUrlParams, refreshInterval, refreshPaused, urlRefreshInterval, urlIsPaused, dispatch]); + const { refreshInterval, setRefreshInterval, refreshPaused, setRefreshPaused } = + useSyntheticsRefreshContext(); const onRefreshChange = (newProps: OnRefreshChangeProps) => { - dispatch(setRefreshIntervalAction(newProps.refreshInterval / 1000)); - dispatch(setRefreshPausedAction(newProps.isPaused)); - - updateUrlParams( - replaceDefaults({ - refreshInterval: newProps.refreshInterval / 1000, - refreshPaused: newProps.isPaused, - }), - true - ); + setRefreshPaused(newProps.isPaused); + setRefreshInterval(newProps.refreshInterval / 1000); }; return ( diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx index bc086f67c822b..210170b7e3b8f 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/common/components/last_refreshed.tsx @@ -9,16 +9,12 @@ import React, { useEffect, useState } from 'react'; import moment from 'moment'; import { EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useSelector } from 'react-redux'; import { useSyntheticsRefreshContext } from '../../../contexts'; -import { selectRefreshPaused } from '../../../state'; export function LastRefreshed() { - const { lastRefresh: lastRefreshed } = useSyntheticsRefreshContext(); + const { lastRefresh: lastRefreshed, refreshPaused } = useSyntheticsRefreshContext(); const [refresh, setRefresh] = useState(() => Date.now()); - const refreshPaused = useSelector(selectRefreshPaused); - useEffect(() => { const interVal = setInterval(() => { setRefresh(Date.now()); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_selected_monitor.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_selected_monitor.tsx index 622dcff46e902..1f2eadb7c09fc 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_selected_monitor.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/hooks/use_selected_monitor.tsx @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import { useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; @@ -16,7 +15,6 @@ import { selectMonitorListState, selectorMonitorDetailsState, selectorError, - selectRefreshInterval, } from '../../../state'; export const useSelectedMonitor = (monId?: string) => { @@ -27,14 +25,13 @@ export const useSelectedMonitor = (monId?: string) => { } const monitorsList = useSelector(selectEncryptedSyntheticsSavedMonitors); const { loading: monitorListLoading } = useSelector(selectMonitorListState); - const refreshInterval = useSelector(selectRefreshInterval); const monitorFromList = useMemo( () => monitorsList.find((monitor) => monitor[ConfigKey.CONFIG_ID] === monitorId) ?? null, [monitorId, monitorsList] ); const error = useSelector(selectorError); - const { lastRefresh } = useSyntheticsRefreshContext(); + const { lastRefresh, refreshInterval } = useSyntheticsRefreshContext(); const { syntheticsMonitor, syntheticsMonitorLoading, syntheticsMonitorDispatchedAt } = useSelector(selectorMonitorDetailsState); const dispatch = useDispatch(); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx index b53620921fdd1..9f3902b8ccaf2 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/contexts/synthetics_refresh_context.tsx @@ -14,15 +14,21 @@ import React, { useState, FC, } from 'react'; -import { useSelector } from 'react-redux'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; import { useEvent } from 'react-use'; import moment from 'moment'; import { Subject } from 'rxjs'; -import { selectRefreshInterval, selectRefreshPaused } from '../state'; +import { i18n } from '@kbn/i18n'; +import { CLIENT_DEFAULTS_SYNTHETICS } from '../../../../common/constants/synthetics/client_defaults'; +const { AUTOREFRESH_INTERVAL_SECONDS, AUTOREFRESH_IS_PAUSED } = CLIENT_DEFAULTS_SYNTHETICS; interface SyntheticsRefreshContext { lastRefresh: number; refreshApp: () => void; + refreshInterval: number; + refreshPaused: boolean; + setRefreshInterval: (interval: number) => void; + setRefreshPaused: (paused: boolean) => void; } const defaultContext: SyntheticsRefreshContext = { @@ -30,6 +36,22 @@ const defaultContext: SyntheticsRefreshContext = { refreshApp: () => { throw new Error('App refresh was not initialized, set it when you invoke the context'); }, + refreshInterval: AUTOREFRESH_INTERVAL_SECONDS, + refreshPaused: AUTOREFRESH_IS_PAUSED, + setRefreshInterval: () => { + throw new Error( + i18n.translate('xpack.synthetics.refreshContext.intervalNotInitialized', { + defaultMessage: 'Refresh interval was not initialized, set it when you invoke the context', + }) + ); + }, + setRefreshPaused: () => { + throw new Error( + i18n.translate('xpack.synthetics.refreshContext.pausedNotInitialized', { + defaultMessage: 'Refresh paused was not initialized, set it when you invoke the context', + }) + ); + }, }; export const SyntheticsRefreshContext = createContext(defaultContext); @@ -41,8 +63,14 @@ export const SyntheticsRefreshContextProvider: FC< > = ({ children, reload$ }) => { const [lastRefresh, setLastRefresh] = useState(Date.now()); - const refreshPaused = useSelector(selectRefreshPaused); - const refreshInterval = useSelector(selectRefreshInterval); + const [refreshInterval, setRefreshInterval] = useLocalStorage( + 'xpack.synthetics.refreshInterval', + AUTOREFRESH_INTERVAL_SECONDS + ); + const [refreshPaused, setRefreshPaused] = useLocalStorage( + 'xpack.synthetics.refreshPaused', + AUTOREFRESH_IS_PAUSED + ); const refreshApp = useCallback(() => { const refreshTime = Date.now(); @@ -66,13 +94,26 @@ export const SyntheticsRefreshContextProvider: FC< return { lastRefresh, refreshApp, + refreshInterval: refreshInterval ?? AUTOREFRESH_INTERVAL_SECONDS, + refreshPaused: refreshPaused ?? AUTOREFRESH_IS_PAUSED, + setRefreshInterval, + setRefreshPaused, }; - }, [lastRefresh, refreshApp]); + }, [ + lastRefresh, + refreshApp, + refreshInterval, + refreshPaused, + setRefreshInterval, + setRefreshPaused, + ]); useEvent( 'visibilitychange', () => { - const isOutdated = moment().diff(new Date(lastRefresh), 'seconds') > refreshInterval; + const isOutdated = + moment().diff(new Date(lastRefresh), 'seconds') > + (refreshInterval || AUTOREFRESH_INTERVAL_SECONDS); if (document.visibilityState !== 'hidden' && !refreshPaused && isOutdated) { refreshApp(); } @@ -88,7 +129,7 @@ export const SyntheticsRefreshContextProvider: FC< if (document.visibilityState !== 'hidden') { refreshApp(); } - }, refreshInterval * 1000); + }, (refreshInterval || AUTOREFRESH_INTERVAL_SECONDS) * 1000); return () => clearInterval(interval); }, [refreshPaused, refreshApp, refreshInterval]); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/actions.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/actions.ts index e3738f3737cf0..06b9506ead191 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/actions.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/actions.ts @@ -31,5 +31,3 @@ export const toggleIntegrationsPopover = createAction( ); export const setSelectedMonitorId = createAction('[UI] SET MONITOR ID'); -export const setRefreshPausedAction = createAction('[UI] SET REFRESH PAUSED'); -export const setRefreshIntervalAction = createAction('[UI] SET REFRESH INTERVAL'); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/index.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/index.ts index 6c6ef93bbf3a7..2c7d5e5ce3d4c 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/index.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/index.ts @@ -11,7 +11,6 @@ import { SYNTHETICS_STATUS_RULE, SYNTHETICS_TLS_RULE, } from '../../../../../common/constants/synthetics_alerts'; -import { CLIENT_DEFAULTS_SYNTHETICS } from '../../../../../common/constants/synthetics/client_defaults'; import { PopoverState, toggleIntegrationsPopover, @@ -20,10 +19,7 @@ import { setAlertFlyoutVisible, setSearchTextAction, setSelectedMonitorId, - setRefreshPausedAction, - setRefreshIntervalAction, } from './actions'; -const { AUTOREFRESH_INTERVAL_SECONDS, AUTOREFRESH_IS_PAUSED } = CLIENT_DEFAULTS_SYNTHETICS; export interface UiState { alertFlyoutVisible: typeof SYNTHETICS_TLS_RULE | typeof SYNTHETICS_STATUS_RULE | null; @@ -32,8 +28,6 @@ export interface UiState { searchText: string; integrationsPopoverOpen: PopoverState | null; monitorId: string; - refreshInterval: number; - refreshPaused: boolean; } const initialState: UiState = { @@ -43,8 +37,6 @@ const initialState: UiState = { searchText: '', integrationsPopoverOpen: null, monitorId: '', - refreshInterval: AUTOREFRESH_INTERVAL_SECONDS, - refreshPaused: AUTOREFRESH_IS_PAUSED, }; export const uiReducer = createReducer(initialState, (builder) => { @@ -66,12 +58,6 @@ export const uiReducer = createReducer(initialState, (builder) => { }) .addCase(setSelectedMonitorId, (state, action) => { state.monitorId = action.payload; - }) - .addCase(setRefreshPausedAction, (state, action) => { - state.refreshPaused = action.payload; - }) - .addCase(setRefreshIntervalAction, (state, action) => { - state.refreshInterval = action.payload; }); }); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/selectors.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/selectors.ts index 4e365d8343555..f02b1fb564c37 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/selectors.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/ui/selectors.ts @@ -14,12 +14,3 @@ export const selectAlertFlyoutVisibility = createSelector( uiStateSelector, ({ alertFlyoutVisible }) => alertFlyoutVisible ); - -export const selectRefreshPaused = createSelector( - uiStateSelector, - ({ refreshPaused }) => refreshPaused -); -export const selectRefreshInterval = createSelector( - uiStateSelector, - ({ refreshInterval }) => refreshInterval -); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts index b861fe36b9b96..aa52c54c21b78 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/testing/__mocks__/synthetics_store.mock.ts @@ -30,8 +30,6 @@ export const mockState: SyntheticsAppState = { integrationsPopoverOpen: null, searchText: '', monitorId: '', - refreshInterval: 60, - refreshPaused: true, }, serviceLocations: { throttling: DEFAULT_THROTTLING, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.test.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.test.ts index efabb2034e434..2a01b9d7aeefb 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.test.ts @@ -51,12 +51,7 @@ describe('getSupportedUrlParams', () => { it('returns default values', () => { const { FILTERS, SEARCH, STATUS_FILTER } = CLIENT_DEFAULTS; - const { - DATE_RANGE_START, - DATE_RANGE_END, - AUTOREFRESH_INTERVAL_SECONDS, - AUTOREFRESH_IS_PAUSED, - } = CLIENT_DEFAULTS_SYNTHETICS; + const { DATE_RANGE_START, DATE_RANGE_END } = CLIENT_DEFAULTS_SYNTHETICS; const result = getSupportedUrlParams({}); expect(result).toEqual({ absoluteDateRangeStart: MOCK_DATE_VALUE, @@ -75,8 +70,6 @@ describe('getSupportedUrlParams', () => { projects: [], schedules: [], tags: [], - refreshInterval: AUTOREFRESH_INTERVAL_SECONDS, - refreshPaused: AUTOREFRESH_IS_PAUSED, }); }); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.ts index ce2eb6f30829f..8b4612b1e0f39 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/get_supported_url_params.ts @@ -7,8 +7,6 @@ import { MonitorOverviewState } from '../../state'; import { CLIENT_DEFAULTS_SYNTHETICS } from '../../../../../common/constants/synthetics/client_defaults'; -import { parseIsPaused } from './parse_is_paused'; -import { parseUrlInt } from './parse_url_int'; import { CLIENT_DEFAULTS } from '../../../../../common/constants'; import { parseAbsoluteDate } from './parse_absolute_date'; @@ -16,8 +14,6 @@ import { parseAbsoluteDate } from './parse_absolute_date'; export interface SyntheticsUrlParams { absoluteDateRangeStart: number; absoluteDateRangeEnd: number; - refreshInterval: number; - refreshPaused: boolean; dateRangeStart: string; dateRangeEnd: string; pagination?: string; @@ -43,8 +39,7 @@ export interface SyntheticsUrlParams { const { ABSOLUTE_DATE_RANGE_START, ABSOLUTE_DATE_RANGE_END, SEARCH, FILTERS, STATUS_FILTER } = CLIENT_DEFAULTS; -const { DATE_RANGE_START, DATE_RANGE_END, AUTOREFRESH_INTERVAL_SECONDS, AUTOREFRESH_IS_PAUSED } = - CLIENT_DEFAULTS_SYNTHETICS; +const { DATE_RANGE_START, DATE_RANGE_END } = CLIENT_DEFAULTS_SYNTHETICS; /** * Gets the current URL values for the application. If no item is present @@ -76,8 +71,6 @@ export const getSupportedUrlParams = (params: { }); const { - refreshInterval, - refreshPaused, dateRangeStart, dateRangeEnd, filters, @@ -112,8 +105,6 @@ export const getSupportedUrlParams = (params: { ABSOLUTE_DATE_RANGE_END, { roundUp: true } ), - refreshInterval: parseUrlInt(refreshInterval, AUTOREFRESH_INTERVAL_SECONDS), - refreshPaused: parseIsPaused(refreshPaused, AUTOREFRESH_IS_PAUSED), dateRangeStart: dateRangeStart || DATE_RANGE_START, dateRangeEnd: dateRangeEnd || DATE_RANGE_END, filters: filters || FILTERS, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.test.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.test.ts index 6f9ace8634d64..c8f8649fd56db 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.test.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.test.ts @@ -12,8 +12,6 @@ describe('stringifyUrlParams', () => { const result = stringifyUrlParams({ absoluteDateRangeStart: 1000, absoluteDateRangeEnd: 2000, - refreshInterval: 50000, - refreshPaused: false, dateRangeStart: 'now-15m', dateRangeEnd: 'now', filters: 'monitor.id: bar', @@ -22,7 +20,7 @@ describe('stringifyUrlParams', () => { statusFilter: 'up', }); expect(result).toMatchInlineSnapshot( - `"?absoluteDateRangeStart=1000&absoluteDateRangeEnd=2000&refreshInterval=50000&refreshPaused=false&dateRangeStart=now-15m&dateRangeEnd=now&filters=monitor.id%3A%20bar&focusConnectorField=true&search=monitor.id%3A%20foo&statusFilter=up"` + `"?absoluteDateRangeStart=1000&absoluteDateRangeEnd=2000&dateRangeStart=now-15m&dateRangeEnd=now&filters=monitor.id%3A%20bar&focusConnectorField=true&search=monitor.id%3A%20foo&statusFilter=up"` ); }); @@ -31,8 +29,6 @@ describe('stringifyUrlParams', () => { { absoluteDateRangeStart: 1000, absoluteDateRangeEnd: 2000, - refreshInterval: 50000, - refreshPaused: false, dateRangeStart: 'now-15m', dateRangeEnd: 'now', filters: 'monitor.id: bar', @@ -43,9 +39,7 @@ describe('stringifyUrlParams', () => { }, true ); - expect(result).toMatchInlineSnapshot( - `"?refreshInterval=50000&dateRangeStart=now-15m&filters=monitor.id%3A%20bar"` - ); + expect(result).toMatchInlineSnapshot(`"?dateRangeStart=now-15m&filters=monitor.id%3A%20bar"`); expect(result.includes('pagination')).toBeFalsy(); expect(result.includes('search')).toBeFalsy(); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.ts index 7f0dd94237593..7f465e7272dc6 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/utils/url_params/stringify_url_params.ts @@ -12,8 +12,7 @@ import { CLIENT_DEFAULTS } from '../../../../../common/constants'; const { FOCUS_CONNECTOR_FIELD } = CLIENT_DEFAULTS; -const { DATE_RANGE_START, DATE_RANGE_END, AUTOREFRESH_INTERVAL_SECONDS, AUTOREFRESH_IS_PAUSED } = - CLIENT_DEFAULTS_SYNTHETICS; +const { DATE_RANGE_START, DATE_RANGE_END } = CLIENT_DEFAULTS_SYNTHETICS; export const stringifyUrlParams = (params: Partial, ignoreEmpty = false) => { if (ignoreEmpty) { @@ -41,12 +40,6 @@ const replaceDefaults = (params: Partial) => { if (key === 'dateRangeEnd' && val === DATE_RANGE_END) { delete params[key]; } - if (key === 'refreshPaused' && val === AUTOREFRESH_IS_PAUSED) { - delete params[key]; - } - if (key === 'refreshInterval' && val === AUTOREFRESH_INTERVAL_SECONDS) { - delete params[key]; - } if (key === 'focusConnectorField' && val === FOCUS_CONNECTOR_FIELD) { delete params[key]; } From 010a362f34869f01ef39d21c0986d90cffc21f50 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 17 Sep 2024 02:55:22 +1000 Subject: [PATCH 033/139] skip failing test suite (#193036) --- .../test_suites/common/index_management/inference_endpoints.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/inference_endpoints.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/inference_endpoints.ts index f5f712fc7d5a1..83ac02779b5f0 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/inference_endpoints.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/inference_endpoints.ts @@ -26,7 +26,8 @@ export default function ({ getService }: FtrProviderContext) { let roleAuthc: RoleCredentials; let internalReqHeader: InternalRequestHeader; - describe('Inference endpoints', function () { + // Failing: See https://github.com/elastic/kibana/issues/193036 + describe.skip('Inference endpoints', function () { before(async () => { roleAuthc = await svlUserManager.createM2mApiKeyWithRoleScope('admin'); internalReqHeader = svlCommonApi.getInternalRequestHeader(); From 6680f35ef94286d34dd5c56e28575b31eab70836 Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Mon, 16 Sep 2024 13:19:39 -0400 Subject: [PATCH 034/139] [Security Solution] Test plan for `query` fields diff algorithm (#192529) ## Summary Related ticket: https://github.com/elastic/kibana/issues/187658 Adds test plan for diff algorithm for arrays of scalar values implemented here: https://github.com/elastic/kibana/pull/190179 ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../upgrade_review_algorithms.md | 144 ++++++++++++------ 1 file changed, 96 insertions(+), 48 deletions(-) diff --git a/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/upgrade_review_algorithms.md b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/upgrade_review_algorithms.md index 26b01da200903..e65d366e0f44c 100644 --- a/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/upgrade_review_algorithms.md +++ b/x-pack/plugins/security_solution/docs/testing/test_plans/detection_response/prebuilt_rules/upgrade_review_algorithms.md @@ -29,10 +29,11 @@ Status: `in progress`. - [**Scenario: `ABC` - Rule field is an array of scalar values**](#scenario-abc---rule-field-is-an-array-of-scalar-values) - [**Scenario: `ABC` - Rule field is a solvable `data_source` object**](#scenario-abc---rule-field-is-a-solvable-data_source-object) - [**Scenario: `ABC` - Rule field is a non-solvable `data_source` object**](#scenario-abc---rule-field-is-a-non-solvable-data_source-object) + - [**Scenario: `ABC` - Rule field is a `kql_query`, `eql_query`, or `esql_query` object**](#scenario-abc---rule-field-is-a-kql_query-eql_query-or-esql_query-object) - [Rule field has an update and a custom value that are the same and the rule base version doesn't exist - `-AA`](#rule-field-has-an-update-and-a-custom-value-that-are-the-same-and-the-rule-base-version-doesnt-exist----aa) - [**Scenario: `-AA` - Rule field is any type**](#scenario--aa---rule-field-is-any-type) - [Rule field has an update and a custom value that are NOT the same and the rule base version doesn't exist - `-AB`](#rule-field-has-an-update-and-a-custom-value-that-are-not-the-same-and-the-rule-base-version-doesnt-exist----ab) - - [**Scenario: `-AB` - Rule field is a number or single line string**](#scenario--ab---rule-field-is-a-number-or-single-line-string) + - [**Scenario: `-AB` - Rule field is a number, single line string, multi line string, `data_source` object, `kql_query` object, `eql_query` object, or `esql_query` object**](#scenario--ab---rule-field-is-a-number-single-line-string-multi-line-string-data_source-object-kql_query-object-eql_query-object-or-esql_query-object) - [**Scenario: `-AB` - Rule field is an array of scalar values**](#scenario--ab---rule-field-is-an-array-of-scalar-values) - [**Scenario: `-AB` - Rule field is a solvable `data_source` object**](#scenario--ab---rule-field-is-a-solvable-data_source-object) - [**Scenario: `-AB` - Rule field is a non-solvable `data_source` object**](#scenario--ab---rule-field-is-a-non-solvable-data_source-object) @@ -58,6 +59,9 @@ Status: `in progress`. - **Grouped fields** - `data_source`: an object that contains a `type` field with a value of `data_view_id` or `index_patterns` and another field that's either `data_view_id` of type string OR `index_patterns` of type string array + - `kql_query`: an object that contains a `type` field with a value of `inline_query` or `saved_query` and other fields based on whichever type is defined. If it's `inline_query`, the object contains a `query` string field, a `language` field that's either `kuery` or `lucene`, and a `filters` field which is an array of kibana filters. If the type field is `saved_query`, the object only contains a `saved_query_id` string field. + - `eql_query`: an object that contains a `query` string field, a `language` field that always has the value: `eql`, and a `filters` field that contains an array of kibana filters. + - `esql_query`: an object that contains a `query` string field and a `language` field that always has the value: `esql`. ### Assumptions @@ -70,7 +74,7 @@ Status: `in progress`. #### **Scenario: `AAA` - Rule field is any type** -**Automation**: 6 integration tests with mock rules + a set of unit tests for each algorithm +**Automation**: 10 integration tests with mock rules + a set of unit tests for each algorithm ```Gherkin Given field is not customized by the user (current version == base version) @@ -80,20 +84,24 @@ And field should not be returned from the `upgrade/_review` API end And field should not be shown in the upgrade preview UI Examples: -| algorithm | field_name | base_version | current_version | target_version | merged_version | -| single line string | name | "A" | "A" | "A" | "A" | -| multi line string | description | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My description.\nThis is a second line." | -| number | risk_score | 1 | 1 | 1 | 1 | -| array of scalars | tags | ["one", "two", "three"] | ["one", "three", "two"] | ["three", "one", "two"] | ["one", "three", "two"] | -| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | -| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| single line string | name | "A" | "A" | "A" | "A" | +| multi line string | description | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My description.\nThis is a second line." | +| number | risk_score | 1 | 1 | 1 | 1 | +| array of scalars | tags | ["one", "two", "three"] | ["one", "three", "two"] | ["three", "one", "two"] | ["one", "three", "two"] | +| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | +| kql_query | kql_query | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | +| kql_query | kql_query | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | +| eql_query | eql_query | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | +| esql_query | esql_query | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | ``` ### Rule field doesn't have an update but has a custom value - `ABA` #### **Scenario: `ABA` - Rule field is any type** -**Automation**: 6 integration tests with mock rules + a set of unit tests for each algorithm +**Automation**: 10 integration tests with mock rules + a set of unit tests for each algorithm ```Gherkin Given field is customized by the user (current version != base version) @@ -103,20 +111,24 @@ And field should be returned from the `upgrade/_review` API endpoin And field should be shown in the upgrade preview UI Examples: -| algorithm | field_name | base_version | current_version | target_version | merged_version | -| single line string | name | "A" | "B" | "A" | "B" | -| multi line string | description | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | -| number | risk_score | 1 | 2 | 1 | 2 | -| array of scalars | tags | ["one", "two", "three"] | ["one", "two", "four"] | ["one", "two", "three"] | ["one", "two", "four"] | -| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | -| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| single line string | name | "A" | "B" | "A" | "B" | +| multi line string | description | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | +| number | risk_score | 1 | 2 | 1 | 2 | +| array of scalars | tags | ["one", "two", "three"] | ["one", "two", "four"] | ["one", "two", "three"] | ["one", "two", "four"] | +| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | +| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| kql_query | kql_query | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = false", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = false", language: "kuery", filters: []} | +| kql_query | kql_query | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | +| eql_query | eql_query | {query: "query where true", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | +| esql_query | esql_query | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | ``` ### Rule field has an update and doesn't have a custom value - `AAB` #### **Scenario: `AAB` - Rule field is any type** -**Automation**: 6 integration tests with mock rules + a set of unit tests for each algorithm +**Automation**: 10 integration tests with mock rules + a set of unit tests for each algorithm ```Gherkin Given field is not customized by the user (current version == base version) @@ -126,20 +138,24 @@ And field should be returned from the `upgrade/_review` API endpoin And field should be shown in the upgrade preview UI Examples: -| algorithm | field_name | base_version | current_version | target_version | merged_version | -| single line string | name | "A" | "A" | "B" | "B" | -| multi line string | description | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | -| number | risk_score | 1 | 1 | 2 | 2 | -| array of scalars | tags | ["one", "two", "three"] | ["one", "two", "three"] | ["one", "two", "four"] | ["one", "two", "four"] | -| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | -| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| single line string | name | "A" | "A" | "B" | "B" | +| multi line string | description | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | +| number | risk_score | 1 | 1 | 2 | 2 | +| array of scalars | tags | ["one", "two", "three"] | ["one", "two", "three"] | ["one", "two", "four"] | ["one", "two", "four"] | +| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | +| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| kql_query | kql_query | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | +| kql_query | kql_query | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | +| eql_query | eql_query | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: [{ field: 'some query' }]} | {query: "query where true", language: "eql", filters: [{ field: 'some query' }]} | +| esql_query | esql_query | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | ``` ### Rule field has an update and a custom value that are the same - `ABB` #### **Scenario: `ABB` - Rule field is any type** -**Automation**: 6 integration tests with mock rules + a set of unit tests for each algorithm +**Automation**: 10 integration tests with mock rules + a set of unit tests for each algorithm ```Gherkin Given field is customized by the user (current version != base version) @@ -150,13 +166,17 @@ And field should be returned from the `upgrade/_review` API endpoin And field should be shown in the upgrade preview UI Examples: -| algorithm | field_name | base_version | current_version | target_version | merged_version | -| single line string | name | "A" | "B" | "B" | "B" | -| multi line string | description | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | -| number | risk_score | 1 | 2 | 2 | 2 | -| array of scalars | tags | ["one", "two", "three"] | ["one", "two", "four"] | ["one", "two", "four"] | ["one", "two", "four"] | -| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | -| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| single line string | name | "A" | "B" | "B" | "B" | +| multi line string | description | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | +| number | risk_score | 1 | 2 | 2 | 2 | +| array of scalars | tags | ["one", "two", "three"] | ["one", "two", "four"] | ["one", "two", "four"] | ["one", "two", "four"] | +| data_source | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | +| data_source | data_source | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| kql_query | kql_query | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "lucene", filters: []} | {type: "inline_query", query: "query string = true", language: "lucene", filters: []} | {type: "inline_query", query: "query string = true", language: "lucene", filters: []} | +| kql_query | kql_query | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | +| eql_query | eql_query | {query: "query where true", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | +| esql_query | esql_query | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | ``` ### Rule field has an update and a custom value that are NOT the same - `ABC` @@ -284,11 +304,31 @@ Examples: | data_source | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "data_view", "data_view_id": "A"} | {type: "index_patterns", "index_patterns": ["one", "two", "five"]} | {type: "data_view", "data_view_id": "A"} | ``` +#### **Scenario: `ABC` - Rule field is a `kql_query`, `eql_query`, or `esql_query` object** + +**Automation**: 4 integration tests with mock rules + a set of unit tests for the algorithms + +```Gherkin +Given field is customized by the user (current version != base version) +And field is updated by Elastic in this upgrade (target version != base version) +And customized field is different than the Elastic update in this upgrade (current version != target version) +Then for field the diff algorithm should output the current version as the merged one with a non-solvable conflict +And field should be returned from the `upgrade/_review` API endpoint +And field should be shown in the upgrade preview UI + +Examples: +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| kql_query | kql_query | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "inline_query", query: "query string = false", language: "kuery", filters: []} | {type: "saved_query", saved_query_id: 'saved-query-id'} | +| kql_query | kql_query | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | +| eql_query | eql_query | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: [{ field: 'some query' }]} | {query: "query where false", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: [{ field: 'some query' }]} | +| esql_query | esql_query | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | {query: "FROM different query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | +``` + ### Rule field has an update and a custom value that are the same and the rule base version doesn't exist - `-AA` #### **Scenario: `-AA` - Rule field is any type** -**Automation**: 5 integration tests with mock rules + a set of unit tests for each algorithm +**Automation**: 9 integration tests with mock rules + a set of unit tests for each algorithm ```Gherkin Given at least 1 installed prebuilt rule has a new version available @@ -299,20 +339,24 @@ And field should not be returned from the `upgrade/_review` API end And field should not be shown in the upgrade preview UI Examples: -| algorithm | field_name | base_version | current_version | target_version | merged_version | -| single line string | name | N/A | "A" | "A" | "A" | -| multi line string | description | N/A | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My description.\nThis is a second line." | -| number | risk_score | N/A | 1 | 1 | 1 | -| array of scalars | tags | N/A | ["one", "three", "two"] | ["three", "one", "two"] | ["one", "three", "two"] | -| data_source | data_source | N/A | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | -| data_source | data_source | N/A | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| single line string | name | N/A | "A" | "A" | "A" | +| multi line string | description | N/A | "My description.\nThis is a second line." | "My description.\nThis is a second line." | "My description.\nThis is a second line." | +| number | risk_score | N/A | 1 | 1 | 1 | +| array of scalars | tags | N/A | ["one", "three", "two"] | ["three", "one", "two"] | ["one", "three", "two"] | +| data_source | data_source | N/A | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | {type: "index_patterns", "index_patterns": ["one", "two", "three"]} | +| data_source | data_source | N/A | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "A"} | +| kql_query | kql_query | N/A | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | +| kql_query | kql_query | N/A | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'saved-query-id'} | +| eql_query | eql_query | N/A | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | {query: "query where true", language: "eql", filters: []} | +| esql_query | esql_query | N/A | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE true", language: "esql"} | ``` ### Rule field has an update and a custom value that are NOT the same and the rule base version doesn't exist - `-AB` -#### **Scenario: `-AB` - Rule field is a number or single line string** +#### **Scenario: `-AB` - Rule field is a number, single line string, multi line string, `data_source` object, `kql_query` object, `eql_query` object, or `esql_query` object** -**Automation**: 4 integration tests with mock rules + a set of unit tests for the algorithms +**Automation**: 8 integration tests with mock rules + a set of unit tests for the algorithms ```Gherkin Given at least 1 installed prebuilt rule has a new version available @@ -323,11 +367,15 @@ And field should be returned from the `upgrade/_review` API endpoin And field should be shown in the upgrade preview UI Examples: -| algorithm | field_name | base_version | current_version | target_version | merged_version | -| single line string | name | N/A | "B" | "C" | "C" | -| multi line string | description | N/A | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | -| number | risk_score | N/A | 2 | 3 | 3 | -| data_source | data_source | N/A | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "B"} | {type: "data_view", "data_view_id": "B"} | +| algorithm | field_name | base_version | current_version | target_version | merged_version | +| single line string | name | N/A | "B" | "C" | "C" | +| multi line string | description | N/A | "My description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | "My GREAT description.\nThis is a second line." | +| number | risk_score | N/A | 2 | 3 | 3 | +| data_source | data_source | N/A | {type: "data_view", "data_view_id": "A"} | {type: "data_view", "data_view_id": "B"} | {type: "data_view", "data_view_id": "B"} | +| kql_query | kql_query | N/A | {type: "inline_query", query: "query string = true", language: "kuery", filters: []} | {type: "inline_query", query: "query string = false", language: "kuery", filters: []} | {type: "inline_query", query: "query string = false", language: "kuery", filters: []} | +| kql_query | kql_query | N/A | {type: "saved_query", saved_query_id: 'saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | {type: "saved_query", saved_query_id: 'new-saved-query-id'} | +| eql_query | eql_query | N/A | {query: "query where true", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | {query: "query where false", language: "eql", filters: []} | +| esql_query | esql_query | N/A | {query: "FROM query WHERE true", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | {query: "FROM query WHERE false", language: "esql"} | ``` #### **Scenario: `-AB` - Rule field is an array of scalar values** From 0c63a7b73394e9bfe348de8b2d0755c557098eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?= Date: Mon, 16 Sep 2024 13:45:08 -0400 Subject: [PATCH 035/139] Fix flaky test around search cancellation (#193008) Resolves https://github.com/elastic/kibana/issues/192914 In this PR, I'm fixing the flakiness in tests where sometimes rules fail with a different message on timeout. This is expected as it's a race condition between the Elasticsearch request timing out and the alerting rule getting cancelled. So we can expect one of two messages. Note: Test is not skipped as of PR creation --- .../builtin_alert_types/cancellable/rule.ts | 27 ++++++++++++------- .../builtin_alert_types/long_running/rule.ts | 9 ++++--- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/cancellable/rule.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/cancellable/rule.ts index 41a12004e256a..8a254447b4a4e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/cancellable/rule.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/cancellable/rule.ts @@ -127,9 +127,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { events.filter((event) => event?.event?.action === 'execute'); expect(events[0]?.event?.outcome).to.eql('failure'); expect(events[0]?.kibana?.alerting?.status).to.eql('error'); - expect(events[0]?.error?.message).to.eql( - 'Search has been aborted due to cancelled execution' - ); + // Timeouts will encounter one of the following two messages + const expectedMessages = [ + 'Request timed out', + 'Search has been aborted due to cancelled execution', + ]; + expect(expectedMessages.includes(events[0]?.error?.message || '')).to.be(true); // rule execution status should be in error with reason timeout const { status, body: rule } = await supertest.get( @@ -137,9 +140,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { ); expect(status).to.eql(200); expect(rule.execution_status.status).to.eql('error'); - expect(rule.execution_status.error.message).to.eql( - `test.cancellableRule:${ruleId}: execution cancelled due to timeout - exceeded rule type timeout of 3s` - ); + expect( + [ + 'Request timed out', + `test.cancellableRule:${ruleId}: execution cancelled due to timeout - exceeded rule type timeout of 3s`, + ].includes(rule.execution_status.error.message) + ).to.eql(true); expect(rule.execution_status.error.reason).to.eql('timeout'); }); @@ -183,9 +189,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { ); expect(status).to.eql(200); expect(rule.execution_status.status).to.eql('error'); - expect(rule.execution_status.error.message).to.eql( - `test.cancellableRule:${ruleId}: execution cancelled due to timeout - exceeded rule type timeout of 3s` - ); + expect( + [ + 'Request timed out', + `test.cancellableRule:${ruleId}: execution cancelled due to timeout - exceeded rule type timeout of 3s`, + ].includes(rule.execution_status.error.message) + ).to.eql(true); expect(rule.execution_status.error.reason).to.eql('timeout'); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/long_running/rule.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/long_running/rule.ts index 43524a57cb225..effd35d392a3f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/long_running/rule.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/builtin_alert_types/long_running/rule.ts @@ -74,9 +74,12 @@ export default function ruleTests({ getService }: FtrProviderContext) { expect(errorStatuses.length).to.be.greaterThan(0); const lastErrorStatus = errorStatuses.pop(); expect(lastErrorStatus?.status).to.eql('error'); - expect(lastErrorStatus?.error.message).to.eql( - `test.patternLongRunning.cancelAlertsOnRuleTimeout:${ruleId}: execution cancelled due to timeout - exceeded rule type timeout of 3s` - ); + expect( + [ + 'Request timed out', + `test.patternLongRunning.cancelAlertsOnRuleTimeout:${ruleId}: execution cancelled due to timeout - exceeded rule type timeout of 3s`, + ].includes(lastErrorStatus?.error.message || '') + ).to.eql(true); expect(lastErrorStatus?.error.reason).to.eql('timeout'); }); From 7a7cd7b540239cc88a573a4a5260806b68f04288 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Mon, 16 Sep 2024 13:51:18 -0400 Subject: [PATCH 036/139] feat(rca): search and filter investigations (#192920) --- .../src/rest_specs/find.ts | 6 +- .../rest_specs/get_all_investigation_tags.ts | 21 +++ .../src/rest_specs/index.ts | 2 + .../src/schema/investigation.ts | 1 + .../src/schema/investigation_item.ts | 1 + .../src/schema/investigation_note.ts | 1 + .../fields/tags_field.tsx | 6 +- .../public/hooks/query_key_factory.ts | 3 +- .../hooks/use_fetch_all_investigation_tags.ts | 59 ++++++++ .../hooks/use_fetch_investigation_list.ts | 11 ++ .../list/components/investigation_list.tsx | 136 ++++++++++++------ .../list/components/investigations_error.tsx | 34 +++++ .../list/components/search_bar/search_bar.tsx | 52 +++++++ .../components/search_bar/status_filter.tsx | 85 +++++++++++ .../components/search_bar/tags_filter.tsx | 86 +++++++++++ ...investigate_app_server_route_repository.ts | 25 +++- .../server/saved_objects/investigation.ts | 1 + .../server/services/create_investigation.ts | 4 +- .../services/create_investigation_item.ts | 4 +- .../services/create_investigation_note.ts | 4 +- .../server/services/find_investigations.ts | 28 +++- .../services/get_all_investigation_tags.ts | 19 +++ .../services/investigation_repository.ts | 41 +++++- .../services/update_investigation_note.ts | 2 +- 24 files changed, 568 insertions(+), 64 deletions(-) create mode 100644 packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_tags.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigations_error.tsx create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/search_bar.tsx create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/status_filter.tsx create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/tags_filter.tsx create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_tags.ts diff --git a/packages/kbn-investigation-shared/src/rest_specs/find.ts b/packages/kbn-investigation-shared/src/rest_specs/find.ts index 2a3eab76fbb54..7a938212cfba4 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/find.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/find.ts @@ -15,8 +15,10 @@ const findInvestigationsParamsSchema = z query: z .object({ alertId: z.string(), - page: z.string(), - perPage: z.string(), + search: z.string(), + filter: z.string(), + page: z.coerce.number(), + perPage: z.coerce.number(), }) .partial(), }) diff --git a/packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts b/packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts new file mode 100644 index 0000000000000..35665b1b3c695 --- /dev/null +++ b/packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts @@ -0,0 +1,21 @@ +/* + * 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 { z } from '@kbn/zod'; + +const getAllInvestigationTagsParamsSchema = z.object({ + query: z.object({}), +}); + +const getAllInvestigationTagsResponseSchema = z.string().array(); + +type GetAllInvestigationTagsResponse = z.output; + +export { getAllInvestigationTagsParamsSchema, getAllInvestigationTagsResponseSchema }; +export type { GetAllInvestigationTagsResponse }; diff --git a/packages/kbn-investigation-shared/src/rest_specs/index.ts b/packages/kbn-investigation-shared/src/rest_specs/index.ts index eb30920430673..9b81aca896f55 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/index.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/index.ts @@ -17,6 +17,7 @@ export type * from './find'; export type * from './get'; export type * from './get_items'; export type * from './get_notes'; +export type * from './get_all_investigation_tags'; export type * from './investigation'; export type * from './investigation_item'; export type * from './investigation_note'; @@ -34,6 +35,7 @@ export * from './find'; export * from './get'; export * from './get_items'; export * from './get_notes'; +export * from './get_all_investigation_tags'; export * from './investigation'; export * from './investigation_item'; export * from './investigation_note'; diff --git a/packages/kbn-investigation-shared/src/schema/investigation.ts b/packages/kbn-investigation-shared/src/schema/investigation.ts index cd99de702c9e5..47d198665657d 100644 --- a/packages/kbn-investigation-shared/src/schema/investigation.ts +++ b/packages/kbn-investigation-shared/src/schema/investigation.ts @@ -25,6 +25,7 @@ const investigationSchema = z.object({ title: z.string(), createdAt: z.number(), createdBy: z.string(), + updatedAt: z.number(), params: z.object({ timeRange: z.object({ from: z.number(), to: z.number() }), }), diff --git a/packages/kbn-investigation-shared/src/schema/investigation_item.ts b/packages/kbn-investigation-shared/src/schema/investigation_item.ts index e7578977bd254..820db8500e5dc 100644 --- a/packages/kbn-investigation-shared/src/schema/investigation_item.ts +++ b/packages/kbn-investigation-shared/src/schema/investigation_item.ts @@ -20,6 +20,7 @@ const investigationItemSchema = z.intersection( id: z.string(), createdAt: z.number(), createdBy: z.string(), + updatedAt: z.number(), }), itemSchema ); diff --git a/packages/kbn-investigation-shared/src/schema/investigation_note.ts b/packages/kbn-investigation-shared/src/schema/investigation_note.ts index a4ca46158e1bb..ff877ab884127 100644 --- a/packages/kbn-investigation-shared/src/schema/investigation_note.ts +++ b/packages/kbn-investigation-shared/src/schema/investigation_note.ts @@ -13,6 +13,7 @@ const investigationNoteSchema = z.object({ id: z.string(), content: z.string(), createdAt: z.number(), + updatedAt: z.number(), createdBy: z.string(), }); diff --git a/x-pack/plugins/observability_solution/investigate_app/public/components/investigation_edit_form/fields/tags_field.tsx b/x-pack/plugins/observability_solution/investigate_app/public/components/investigation_edit_form/fields/tags_field.tsx index fb6555de53f34..a912a6d61eb7b 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/components/investigation_edit_form/fields/tags_field.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/components/investigation_edit_form/fields/tags_field.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { InvestigationForm } from '../investigation_edit_form'; +import { useFetchAllInvestigationTags } from '../../../hooks/use_fetch_all_investigation_tags'; const I18N_TAGS_LABEL = i18n.translate( 'xpack.investigateApp.investigationEditForm.span.tagsLabel', @@ -18,6 +19,7 @@ const I18N_TAGS_LABEL = i18n.translate( export function TagsField() { const { control, getFieldState } = useFormContext(); + const { isLoading, data: tags } = useFetchAllInvestigationTags(); return ( @@ -32,10 +34,10 @@ export function TagsField() { aria-label={I18N_TAGS_LABEL} placeholder={I18N_TAGS_LABEL} fullWidth - noSuggestions isInvalid={fieldState.invalid} isClearable - options={[]} + isLoading={isLoading} + options={tags?.map((tag) => ({ label: tag, value: tag })) ?? []} selectedOptions={generateTagOptions(field.value)} onChange={(selected) => { if (selected.length) { diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts index 253c38a972fbc..454c77ddf56e0 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts @@ -9,8 +9,9 @@ export const investigationKeys = { all: ['investigations'] as const, + tags: () => [...investigationKeys.all, 'tags'] as const, lists: () => [...investigationKeys.all, 'list'] as const, - list: (params: { page: number; perPage: number }) => + list: (params: { page: number; perPage: number; search?: string; filter?: string }) => [...investigationKeys.lists(), params] as const, details: () => [...investigationKeys.all, 'detail'] as const, detail: (investigationId: string) => [...investigationKeys.details(), investigationId] as const, diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_tags.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_tags.ts new file mode 100644 index 0000000000000..083742f09b685 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_tags.ts @@ -0,0 +1,59 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { useQuery } from '@tanstack/react-query'; +import { investigationKeys } from './query_key_factory'; +import { useKibana } from './use_kibana'; + +export interface Response { + isInitialLoading: boolean; + isLoading: boolean; + isRefetching: boolean; + isSuccess: boolean; + isError: boolean; + data: string[] | undefined; +} + +export function useFetchAllInvestigationTags(): Response { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({ + queryKey: investigationKeys.tags(), + queryFn: async ({ signal }) => { + return await http.get(`/api/observability/investigations/_tags`, { + version: '2023-10-31', + signal, + }); + }, + cacheTime: 600 * 1000, // 10_minutes + staleTime: 0, + refetchOnWindowFocus: false, + retry: false, + onError: (error: Error) => { + toasts.addError(error, { + title: i18n.translate('xpack.investigateApp.useFetchAllInvestigationTags.errorTitle', { + defaultMessage: 'Something went wrong while fetching the investigation tags', + }), + }); + }, + }); + + return { + data, + isInitialLoading, + isLoading, + isRefetching, + isSuccess, + isError, + }; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts index 2423a76e06464..cadd0de89a8e3 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_investigation_list.ts @@ -16,6 +16,8 @@ const DEFAULT_PAGE_SIZE = 25; export interface InvestigationListParams { page?: number; perPage?: number; + search?: string; + filter?: string; } export interface UseFetchInvestigationListResponse { @@ -30,6 +32,8 @@ export interface UseFetchInvestigationListResponse { export function useFetchInvestigationList({ page = 1, perPage = DEFAULT_PAGE_SIZE, + search, + filter, }: InvestigationListParams = {}): UseFetchInvestigationListResponse { const { core: { @@ -42,6 +46,8 @@ export function useFetchInvestigationList({ queryKey: investigationKeys.list({ page, perPage, + search, + filter, }), queryFn: async ({ signal }) => { return await http.get(`/api/observability/investigations`, { @@ -49,12 +55,17 @@ export function useFetchInvestigationList({ query: { ...(page !== undefined && { page }), ...(perPage !== undefined && { perPage }), + ...(!!search && { search }), + ...(!!filter && { filter }), }, signal, }); }, + retry: false, refetchInterval: 60 * 1000, refetchOnWindowFocus: false, + cacheTime: 600 * 1000, // 10 minutes + staleTime: 0, onError: (error: Error) => { toasts.addError(error, { title: i18n.translate('xpack.investigateApp.useFetchInvestigationList.errorTitle', { diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx index ec16e4244d6d1..8e1bc793b545e 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx @@ -9,43 +9,45 @@ import { EuiBadge, EuiBasicTable, EuiBasicTableColumn, + EuiFlexGroup, EuiLink, EuiLoadingSpinner, + EuiText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { InvestigationResponse } from '@kbn/investigation-shared/src/rest_specs/investigation'; import moment from 'moment'; import React, { useState } from 'react'; import { paths } from '../../../../common/paths'; -import { InvestigationNotFound } from '../../../components/investigation_not_found/investigation_not_found'; import { InvestigationStatusBadge } from '../../../components/investigation_status_badge/investigation_status_badge'; import { useFetchInvestigationList } from '../../../hooks/use_fetch_investigation_list'; import { useKibana } from '../../../hooks/use_kibana'; import { InvestigationListActions } from './investigation_list_actions'; +import { InvestigationsError } from './investigations_error'; +import { SearchBar } from './search_bar/search_bar'; export function InvestigationList() { - const [pageIndex, setPageIndex] = useState(0); - const [pageSize, setPageSize] = useState(10); const { core: { http: { basePath }, uiSettings, }, } = useKibana(); - const { data, isLoading, isError } = useFetchInvestigationList({ - page: pageIndex + 1, - perPage: pageSize, - }); const dateFormat = uiSettings.get('dateFormat'); const tz = uiSettings.get('dateFormat:tz'); - if (isLoading) { - return ; - } + const [pageIndex, setPageIndex] = useState(0); + const [pageSize, setPageSize] = useState(10); + const [search, setSearch] = useState(undefined); + const [status, setStatus] = useState([]); + const [tags, setTags] = useState([]); - if (isError) { - return ; - } + const { data, isLoading, isError } = useFetchInvestigationList({ + page: pageIndex + 1, + perPage: pageSize, + search, + filter: toFilter(status, tags), + }); const investigations = data?.results ?? []; const totalItemCount = data?.total ?? 0; @@ -74,6 +76,19 @@ export function InvestigationList() { }), truncateText: true, }, + { + field: 'tags', + name: i18n.translate('xpack.investigateApp.investigationList.tagsLabel', { + defaultMessage: 'Tags', + }), + render: (value: InvestigationResponse['tags']) => { + return value.map((tag) => ( + + {tag} + + )); + }, + }, { field: 'notes', name: i18n.translate('xpack.investigateApp.investigationList.notesLabel', { @@ -82,32 +97,22 @@ export function InvestigationList() { render: (notes: InvestigationResponse['notes']) => {notes?.length || 0}, }, { - field: 'createdAt', - name: i18n.translate('xpack.investigateApp.investigationList.createdAtLabel', { - defaultMessage: 'Created at', + field: 'updatedAt', + name: i18n.translate('xpack.investigateApp.investigationList.updatedAtLabel', { + defaultMessage: 'Updated at', }), - render: (createdAt: InvestigationResponse['createdAt']) => ( - {moment(createdAt).tz(tz).format(dateFormat)} + render: (updatedAt: InvestigationResponse['updatedAt']) => ( + {moment(updatedAt).tz(tz).format(dateFormat)} ), }, { field: 'status', name: 'Status', - render: (status: InvestigationResponse['status']) => { - return ; - }, - }, - { - field: 'tags', - name: 'Tags', - render: (tags: InvestigationResponse['tags']) => { - return tags.map((tag) => ( - - {tag} - - )); + render: (s: InvestigationResponse['status']) => { + return ; }, }, + { name: 'Actions', render: (investigation: InvestigationResponse) => ( @@ -120,10 +125,24 @@ export function InvestigationList() { pageIndex, pageSize, totalItemCount, - pageSizeOptions: [10, 50], + pageSizeOptions: [10, 25, 50, 100], showPerPageOptions: true, }; + const resultsCount = + pageSize === 0 + ? i18n.translate('xpack.investigateApp.investigationList.allLabel', { + defaultMessage: 'Showing All', + }) + : i18n.translate('xpack.investigateApp.investigationList.showingLabel', { + defaultMessage: 'Showing {startItem}-{endItem} of {totalItemCount}', + values: { + startItem: pageSize * pageIndex + 1, + endItem: pageSize * pageIndex + pageSize, + totalItemCount, + }, + }); + const onTableChange = ({ page }: Criteria) => { if (page) { const { index, size } = page; @@ -133,15 +152,48 @@ export function InvestigationList() { }; return ( - + + setSearch(value)} + onStatusFilterChange={(selected) => setStatus(selected)} + onTagsFilterChange={(selected) => setTags(selected)} + /> + + {isLoading && } + {isError && } + {!isLoading && !isError && ( + <> + {resultsCount} + + + )} + + ); } + +function toFilter(status: string[], tags: string[]) { + const statusFitler = status.map((s) => `investigation.attributes.status:${s}`).join(' OR '); + const tagsFilter = tags.map((tag) => `investigation.attributes.tags:${tag}`).join(' OR '); + + if (statusFitler && tagsFilter) { + return `(${statusFitler}) AND (${tagsFilter})`; + } + if (statusFitler) { + return statusFitler; + } + + if (tagsFilter) { + return tagsFilter; + } +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigations_error.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigations_error.tsx new file mode 100644 index 0000000000000..232dc7a417e93 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigations_error.tsx @@ -0,0 +1,34 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiEmptyPrompt } from '@elastic/eui'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; + +export function InvestigationsError() { + return ( + + {i18n.translate('xpack.investigateApp.InvestigationsNotFound.title', { + defaultMessage: 'Unable to load investigations', + })} + + } + body={ +

+ {i18n.translate('xpack.investigateApp.InvestigationsNotFound.body', { + defaultMessage: + 'There was an error loading the investigations. Contact your administrator for help.', + })} +

+ } + /> + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/search_bar.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/search_bar.tsx new file mode 100644 index 0000000000000..6c89df8532b71 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/search_bar.tsx @@ -0,0 +1,52 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { StatusFilter } from './status_filter'; +import { TagsFilter } from './tags_filter'; + +interface Props { + isLoading: boolean; + onSearch: (value: string) => void; + onStatusFilterChange: (status: string[]) => void; + onTagsFilterChange: (tags: string[]) => void; +} + +const SEARCH_LABEL = i18n.translate('xpack.investigateApp.investigationList.searchField.label', { + defaultMessage: 'Search...', +}); + +export function SearchBar({ + onSearch, + onStatusFilterChange, + onTagsFilterChange, + isLoading, +}: Props) { + return ( + + + onSearch(value)} + isLoading={isLoading} + /> + + + + + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/status_filter.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/status_filter.tsx new file mode 100644 index 0000000000000..df65845595905 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/status_filter.tsx @@ -0,0 +1,85 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + useGeneratedHtmlId, + EuiFilterButton, + EuiFilterGroup, + EuiPopover, + EuiSelectable, + EuiPopoverTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useState } from 'react'; + +const STATUS_LABEL = i18n.translate('xpack.investigateApp.searchBar.statusFilterButtonLabel', { + defaultMessage: 'Status', +}); + +interface Props { + isLoading: boolean; + onChange: (status: string[]) => void; +} + +export function StatusFilter({ isLoading, onChange }: Props) { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const filterStatusPopoverId = useGeneratedHtmlId({ + prefix: 'filterStatusPopover', + }); + + const [items, setItems] = useState>([ + { label: 'triage' }, + { label: 'active' }, + { label: 'mitigated' }, + { label: 'resolved' }, + { label: 'cancelled' }, + ]); + + const button = ( + setIsPopoverOpen(!isPopoverOpen)} + isSelected={isPopoverOpen} + numFilters={items.length} + hasActiveFilters={!!items.find((item) => item.checked === 'on')} + numActiveFilters={items.filter((item) => item.checked === 'on').length} + > + {STATUS_LABEL} + + ); + return ( + + setIsPopoverOpen(false)} + panelPaddingSize="none" + > + { + setItems(newOptions); + onChange(newOptions.filter((item) => item.checked === 'on').map((item) => item.label)); + }} + isLoading={isLoading} + > + {(list, search) => ( +
+ {search} + {list} +
+ )} +
+
+
+ ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/tags_filter.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/tags_filter.tsx new file mode 100644 index 0000000000000..5a82f84a47fe1 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/search_bar/tags_filter.tsx @@ -0,0 +1,86 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + useGeneratedHtmlId, + EuiFilterButton, + EuiFilterGroup, + EuiPopover, + EuiSelectable, + EuiPopoverTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useEffect, useState } from 'react'; +import { useFetchAllInvestigationTags } from '../../../../hooks/use_fetch_all_investigation_tags'; + +const TAGS_LABEL = i18n.translate('xpack.investigateApp.searchBar.tagsFilterButtonLabel', { + defaultMessage: 'Tags', +}); + +interface Props { + isLoading: boolean; + onChange: (tags: string[]) => void; +} + +export function TagsFilter({ isLoading, onChange }: Props) { + const { isLoading: isTagsLoading, data: tags } = useFetchAllInvestigationTags(); + const [items, setItems] = useState>([]); + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const filterTagsPopoverId = useGeneratedHtmlId({ + prefix: 'filterTagsPopover', + }); + + useEffect(() => { + if (tags) { + setItems(tags.map((tag) => ({ label: tag }))); + } + }, [tags]); + + const button = ( + setIsPopoverOpen(!isPopoverOpen)} + isSelected={isPopoverOpen} + numFilters={items.length} + hasActiveFilters={!!items.find((item) => item.checked === 'on')} + numActiveFilters={items.filter((item) => item.checked === 'on').length} + > + {TAGS_LABEL} + + ); + return ( + + setIsPopoverOpen(false)} + panelPaddingSize="none" + > + { + setItems(newOptions); + onChange(newOptions.filter((item) => item.checked === 'on').map((item) => item.label)); + }} + isLoading={isLoading || isTagsLoading} + > + {(list, search) => ( +
+ {search} + {list} +
+ )} +
+
+
+ ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts index 1755d283b3763..5d62b745e0a73 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts @@ -13,6 +13,7 @@ import { deleteInvestigationNoteParamsSchema, deleteInvestigationParamsSchema, findInvestigationsParamsSchema, + getAllInvestigationTagsParamsSchema, getInvestigationItemsParamsSchema, getInvestigationNotesParamsSchema, getInvestigationParamsSchema, @@ -27,14 +28,15 @@ import { deleteInvestigation } from '../services/delete_investigation'; import { deleteInvestigationItem } from '../services/delete_investigation_item'; import { deleteInvestigationNote } from '../services/delete_investigation_note'; import { findInvestigations } from '../services/find_investigations'; +import { getAllInvestigationTags } from '../services/get_all_investigation_tags'; import { getInvestigation } from '../services/get_investigation'; +import { getInvestigationItems } from '../services/get_investigation_items'; import { getInvestigationNotes } from '../services/get_investigation_notes'; import { investigationRepositoryFactory } from '../services/investigation_repository'; -import { createInvestigateAppServerRoute } from './create_investigate_app_server_route'; -import { getInvestigationItems } from '../services/get_investigation_items'; -import { updateInvestigationNote } from '../services/update_investigation_note'; -import { updateInvestigationItem } from '../services/update_investigation_item'; import { updateInvestigation } from '../services/update_investigation'; +import { updateInvestigationItem } from '../services/update_investigation_item'; +import { updateInvestigationNote } from '../services/update_investigation_note'; +import { createInvestigateAppServerRoute } from './create_investigate_app_server_route'; const createInvestigationRoute = createInvestigateAppServerRoute({ endpoint: 'POST /api/observability/investigations 2023-10-31', @@ -138,6 +140,20 @@ const createInvestigationNoteRoute = createInvestigateAppServerRoute({ }, }); +const getAllInvestigationTagsRoute = createInvestigateAppServerRoute({ + endpoint: 'GET /api/observability/investigations/_tags 2023-10-31', + options: { + tags: [], + }, + params: getAllInvestigationTagsParamsSchema, + handler: async ({ params, context, request, logger }) => { + const soClient = (await context.core).savedObjects.client; + const repository = investigationRepositoryFactory({ soClient, logger }); + + return await getAllInvestigationTags(repository); + }, +}); + const getInvestigationNotesRoute = createInvestigateAppServerRoute({ endpoint: 'GET /api/observability/investigations/{investigationId}/notes 2023-10-31', options: { @@ -296,6 +312,7 @@ export function getGlobalInvestigateAppServerRouteRepository() { ...deleteInvestigationItemRoute, ...updateInvestigationItemRoute, ...getInvestigationItemsRoute, + ...getAllInvestigationTagsRoute, }; } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/saved_objects/investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/saved_objects/investigation.ts index eeb937fb16cfa..20ed328689050 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/saved_objects/investigation.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/saved_objects/investigation.ts @@ -27,6 +27,7 @@ export const investigation: SavedObjectsType = { }, }, status: { type: 'keyword' }, + tags: { type: 'keyword' }, }, }, management: { diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts index 2aed0baed8923..eb8277d7d6f83 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation.ts @@ -18,9 +18,11 @@ export async function createInvestigation( throw new Error(`Investigation [id=${params.id}] already exists`); } + const now = Date.now(); const investigation: Investigation = { ...params, - createdAt: Date.now(), + updatedAt: now, + createdAt: now, createdBy: user.username, status: 'triage', notes: [], diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_item.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_item.ts index 1ed6f1289280b..cf77887aab0a3 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_item.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_item.ts @@ -20,10 +20,12 @@ export async function createInvestigationItem( ): Promise { const investigation = await repository.findById(investigationId); + const now = Date.now(); const investigationItem = { id: v4(), createdBy: user.username, - createdAt: Date.now(), + createdAt: now, + updatedAt: now, ...params, }; investigation.items.push(investigationItem); diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts index 9ce727c0f2e08..2f74123b6f269 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/create_investigation_note.ts @@ -20,11 +20,13 @@ export async function createInvestigationNote( ): Promise { const investigation = await repository.findById(investigationId); + const now = Date.now(); const investigationNote = { id: v4(), content: params.content, createdBy: user.username, - createdAt: Date.now(), + updatedAt: now, + createdAt: now, }; investigation.notes.push(investigationNote); diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts index 7530b3c768610..c3d4606645764 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/find_investigations.ts @@ -10,14 +10,18 @@ import { FindInvestigationsResponse, findInvestigationsResponseSchema, } from '@kbn/investigation-shared'; -import { InvestigationRepository } from './investigation_repository'; +import { InvestigationRepository, Search } from './investigation_repository'; import { InvestigationStatus } from '../models/investigation'; export async function findInvestigations( params: FindInvestigationsParams, repository: InvestigationRepository ): Promise { - const investigations = await repository.search(toFilter(params), toPagination(params)); + const investigations = await repository.search({ + search: toSearch(params), + filter: toFilter(params), + pagination: toPagination(params), + }); return findInvestigationsResponseSchema.parse(investigations); } @@ -26,16 +30,28 @@ function toPagination(params: FindInvestigationsParams) { const DEFAULT_PER_PAGE = 10; const DEFAULT_PAGE = 1; return { - page: params?.page ? parseInt(params.page, 10) : DEFAULT_PAGE, - perPage: params?.perPage ? parseInt(params.perPage, 10) : DEFAULT_PER_PAGE, + page: params?.page && params.page >= 1 ? params.page : DEFAULT_PAGE, + perPage: + params?.perPage && params.perPage > 0 && params.perPage <= 100 + ? params.perPage + : DEFAULT_PER_PAGE, }; } -function toFilter(params: FindInvestigationsParams) { +function toSearch(params: FindInvestigationsParams): Search | undefined { + if (params?.search) { + return { search: params.search }; + } +} + +function toFilter(params: FindInvestigationsParams): string | undefined { if (params?.alertId) { const activeStatus: InvestigationStatus = 'active'; const triageStatus: InvestigationStatus = 'triage'; return `investigation.attributes.origin.id:(${params.alertId}) AND (investigation.attributes.status: ${activeStatus} OR investigation.attributes.status: ${triageStatus})`; } - return ''; + + if (params?.filter) { + return params.filter; + } } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_tags.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_tags.ts new file mode 100644 index 0000000000000..48b1624a434d7 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_tags.ts @@ -0,0 +1,19 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + GetAllInvestigationTagsResponse, + getAllInvestigationTagsResponseSchema, +} from '@kbn/investigation-shared'; +import { InvestigationRepository } from './investigation_repository'; + +export async function getAllInvestigationTags( + repository: InvestigationRepository +): Promise { + const tags = await repository.findAllTags(); + return getAllInvestigationTagsResponseSchema.parse(tags); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts index 73c9136cb3673..b7de0b96949da 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts @@ -11,11 +11,23 @@ import { Investigation, StoredInvestigation } from '../models/investigation'; import { Paginated, Pagination } from '../models/pagination'; import { SO_INVESTIGATION_TYPE } from '../saved_objects/investigation'; +export interface Search { + search: string; +} export interface InvestigationRepository { save(investigation: Investigation): Promise; findById(id: string): Promise; deleteById(id: string): Promise; - search(filter: string, pagination: Pagination): Promise>; + search({ + search, + filter, + pagination, + }: { + search?: Search; + filter?: string; + pagination: Pagination; + }): Promise>; + findAllTags(): Promise; } export function investigationRepositoryFactory({ @@ -89,12 +101,15 @@ export function investigationRepositoryFactory({ await soClient.delete(SO_INVESTIGATION_TYPE, response.saved_objects[0].id); }, - async search(filter: string, pagination: Pagination): Promise> { + async search({ search, filter, pagination }): Promise> { const response = await soClient.find({ type: SO_INVESTIGATION_TYPE, page: pagination.page, perPage: pagination.perPage, - filter, + sortField: 'updated_at', + sortOrder: 'desc', + ...(filter && { filter }), + ...(search && { search: search.search }), }); return { @@ -106,5 +121,25 @@ export function investigationRepositoryFactory({ .filter((investigation) => investigation !== undefined) as Investigation[], }; }, + + async findAllTags(): Promise { + interface AggsTagsTerms { + tags: { buckets: [{ key: string }] }; + } + + const response = await soClient.find({ + type: SO_INVESTIGATION_TYPE, + aggs: { + tags: { + terms: { + field: 'investigation.attributes.tags', + size: 10000, + }, + }, + }, + }); + + return response.aggregations?.tags?.buckets.map((bucket) => bucket.key) ?? []; + }, }; } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation_note.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation_note.ts index dda5ae34f2a71..fc4c5a2c0b1fc 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation_note.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation_note.ts @@ -27,7 +27,7 @@ export async function updateInvestigationNote( investigation.notes = investigation.notes.filter((currNote) => { if (currNote.id === noteId) { - currNote.content = params.content; + currNote = Object.assign(currNote, { content: params.content, updatedAt: Date.now() }); } return currNote; From 1199a5ce66ea04c568fb36dfd88aa5a4090a3974 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 17 Sep 2024 04:21:26 +1000 Subject: [PATCH 037/139] skip failing test suite (#193061) --- .../test_suites/common/alerting/summary_actions.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts b/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts index 2726af585e28f..ec63653bef7c7 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/alerting/summary_actions.ts @@ -39,7 +39,8 @@ export default function ({ getService }: FtrProviderContext) { const alertingApi = getService('alertingApi'); let roleAdmin: RoleCredentials; - describe('Summary actions', function () { + // Failing: See https://github.com/elastic/kibana/issues/193061 + describe.skip('Summary actions', function () { const RULE_TYPE_ID = '.es-query'; const ALERT_ACTION_INDEX = 'alert-action-es-query'; const ALERT_INDEX = '.alerts-stack.alerts-default'; From 8c8696d537b3661c72d98f9ed50d2922d77d5142 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 16 Sep 2024 16:14:29 -0400 Subject: [PATCH 038/139] [Fleet] Fix bulk GET agent policies permissions (#193070) --- .../server/routes/agent_policy/handlers.ts | 5 ++ .../fleet/server/routes/agent_policy/index.ts | 5 +- .../apis/agent_policy/privileges.ts | 62 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts index c24b36c382dc0..a86c627688207 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/handlers.ts @@ -191,6 +191,11 @@ export const bulkGetAgentPoliciesHandler: FleetRequestHandler< const fleetContext = await context.fleet; const soClient = fleetContext.internalSoClient; const { full: withPackagePolicies = false, ignoreMissing = false, ids } = request.body; + if (!fleetContext.authz.fleet.readAgentPolicies && withPackagePolicies) { + throw new FleetUnauthorizedError( + 'full query parameter require agent policies read permissions' + ); + } let items = await agentPolicyService.getByIDs(soClient, ids, { withPackagePolicies, ignoreMissing, diff --git a/x-pack/plugins/fleet/server/routes/agent_policy/index.ts b/x-pack/plugins/fleet/server/routes/agent_policy/index.ts index 66e84cf4a76fe..0ff76addd1b16 100644 --- a/x-pack/plugins/fleet/server/routes/agent_policy/index.ts +++ b/x-pack/plugins/fleet/server/routes/agent_policy/index.ts @@ -61,8 +61,9 @@ export const registerRoutes = (router: FleetAuthzRouter) => { router.versioned .post({ path: AGENT_POLICY_API_ROUTES.BULK_GET_PATTERN, - fleetAuthz: { - fleet: { readAgentPolicies: true }, + fleetAuthz: (authz) => { + // Allow to retrieve agent policies metadata (no full) for user with only read agents permissions + return authz.fleet.readAgentPolicies || authz.fleet.readAgents; }, }) .addVersion( diff --git a/x-pack/test/fleet_api_integration/apis/agent_policy/privileges.ts b/x-pack/test/fleet_api_integration/apis/agent_policy/privileges.ts index d4e9aab9cdbd2..d22fa9380769d 100644 --- a/x-pack/test/fleet_api_integration/apis/agent_policy/privileges.ts +++ b/x-pack/test/fleet_api_integration/apis/agent_policy/privileges.ts @@ -49,6 +49,46 @@ const READ_SCENARIOS = [ }, ]; +const READ_SCENARIOS_FULL_POLICIES = [ + { + user: testUsers.fleet_all_only, + statusCode: 200, + }, + { + user: testUsers.fleet_read_only, + statusCode: 200, + }, + { + user: testUsers.fleet_agent_policies_read_only, + statusCode: 200, + }, + { + user: testUsers.fleet_agent_policies_all_only, + statusCode: 200, + }, + { + // Expect minimal access + user: testUsers.fleet_agents_read_only, + statusCode: 403, + }, + { + user: testUsers.fleet_no_access, + statusCode: 403, + }, + { + user: testUsers.fleet_minimal_all_only, + statusCode: 403, + }, + { + user: testUsers.fleet_minimal_read_only, + statusCode: 403, + }, + { + user: testUsers.fleet_settings_read_only, + statusCode: 403, + }, +]; + const ALL_SCENARIOS = [ { user: testUsers.fleet_all_only, @@ -101,11 +141,33 @@ export default function (providerContext: FtrProviderContext) { path: '/api/fleet/agent_policies', scenarios: READ_SCENARIOS, }, + { + method: 'GET', + path: '/api/fleet/agent_policies?full=true', + scenarios: READ_SCENARIOS_FULL_POLICIES, + }, { method: 'GET', path: '/api/fleet/agent_policies/policy-test-privileges-1', scenarios: READ_SCENARIOS, }, + { + method: 'POST', + path: '/api/fleet/agent_policies/_bulk_get', + scenarios: READ_SCENARIOS, + send: { + ids: ['policy-test-privileges-1'], + }, + }, + { + method: 'POST', + path: '/api/fleet/agent_policies/_bulk_get', + scenarios: READ_SCENARIOS_FULL_POLICIES, + send: { + ids: ['policy-test-privileges-1'], + full: true, + }, + }, { method: 'POST', path: '/api/fleet/agent_policies', From bcab410c5006e49a37f5eddd5230a6b74593c2d7 Mon Sep 17 00:00:00 2001 From: Bena Kansara <69037875+benakansara@users.noreply.github.com> Date: Mon, 16 Sep 2024 22:26:52 +0200 Subject: [PATCH 039/139] [RCA] Remove x-axis and labels from library visualizations (#192994) Removes y-axis label, x-axis and adjusts height of the component for library visualizations --- .../register_embeddable_item.tsx | 7 ++++++- .../items/esql_item/register_esql_item.tsx | 12 ++++++++++-- .../items/lens_item/register_lens_item.tsx | 17 +++++------------ .../utils/get_lens_attrs_for_suggestion.ts | 13 ------------- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx index 3be16c83c8018..8ebf3829b073d 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/embeddable_item/register_embeddable_item.tsx @@ -89,6 +89,11 @@ function LegacyEmbeddable({ type, config, timeRange: { from, to }, savedObjectId from, to, }, + overrides: { + axisX: { hide: true }, + axisLeft: { style: { axisTitle: { visible: false } } }, + settings: { showLegend: false }, + }, }; if (savedObjectId) { @@ -188,7 +193,7 @@ export function registerEmbeddableItem({ grow={true} className={css` > div { - height: 196px; + height: 128px; } `} > diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx index 7e64db5557fc2..54d3698a5148b 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/esql_item/register_esql_item.tsx @@ -132,7 +132,11 @@ export function EsqlWidget({ suggestion, dataView, esqlQuery, dateHistogramResul ); } else { @@ -147,7 +151,11 @@ export function EsqlWidget({ suggestion, dataView, esqlQuery, dateHistogramResul ); diff --git a/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx b/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx index 3f2b1d9f9c1bf..2896719a49e20 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/items/lens_item/register_lens_item.tsx @@ -178,17 +178,6 @@ export function LensWidget({ const attributesLens = new LensAttributesBuilder({ visualization: new XYChart({ - visualOptions: { - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: false, - }, - legend: { - isVisible: false, - position: 'right', - }, - }, layers, formulaAPI: formulaAsync.value.formula, dataView, @@ -227,7 +216,11 @@ export function LensWidget({ query={(searchConfiguration?.query as Query) || defaultQuery} disableTriggers={true} filters={filters} - overrides={{ axisX: { hide: true } }} + overrides={{ + axisX: { hide: true }, + axisLeft: { style: { axisTitle: { visible: false } } }, + settings: { showLegend: false }, + }} />
); diff --git a/x-pack/plugins/observability_solution/investigate_app/public/utils/get_lens_attrs_for_suggestion.ts b/x-pack/plugins/observability_solution/investigate_app/public/utils/get_lens_attrs_for_suggestion.ts index 79693ff2941aa..0483d771954c0 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/utils/get_lens_attrs_for_suggestion.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/utils/get_lens_attrs_for_suggestion.ts @@ -32,19 +32,6 @@ export function getLensAttrsForSuggestion({ dataView, }) as TypedLensByValueInput['attributes']; - attrs.state.visualization = { - ...(attrs.state.visualization as any), - axisTitlesVisibilitySettings: { - x: false, - yLeft: false, - yRight: false, - }, - legend: { - isVisible: false, - position: 'right', - }, - }; - const lensEmbeddableInput: TypedLensByValueInput = { attributes: attrs, id: v4(), From b3baadd14ae0cc07e22d878bdd24861309a26426 Mon Sep 17 00:00:00 2001 From: Maxim Palenov Date: Mon, 16 Sep 2024 23:57:22 +0300 Subject: [PATCH 040/139] [Security Solution] Unskip `install_large_prebuilt_rules_package` (#192563) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Addresses:** https://github.com/elastic/kibana/issues/192479 ## Summary This PR unskips `install_large_prebuilt_rules_package` FTR test. ## Details The flakiness is caused by chunked assets installation inside the Fleet plugin. Used no index refresh strategy leads to reading stale data in `PUT /api/detection_engine/rules/prepackaged` endpoint handler and returning arbitrary data. The problem was fixed by adding `refresh=wait_for` for the last assets chunk installation. ## Flaky test runner - 🟢 (100 runs) https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/6938 --- .../services/epm/kibana/assets/install.ts | 95 +++++++++++++------ .../install_large_prebuilt_rules_package.ts | 21 ++-- 2 files changed, 78 insertions(+), 38 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts b/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts index 8f4397883eb05..276478099daf8 100644 --- a/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts @@ -146,35 +146,12 @@ export async function installKibanaAssets(options: { await makeManagedIndexPatternsGlobal(savedObjectsClient); - let installedAssets: SavedObjectsImportSuccess[] = []; - - if ( - assetsToInstall.length > MAX_ASSETS_TO_INSTALL_IN_PARALLEL && - !hasReferences(assetsToInstall) - ) { - // If the package size is too large, we need to install in chunks to avoid - // memory issues as the SO import creates a lot of objects in memory - - // NOTE: if there are references, we can't chunk the install because - // referenced objects might end up in different chunks leading to import - // errors. - for (const assetChunk of chunk(assetsToInstall, MAX_ASSETS_TO_INSTALL_IN_PARALLEL)) { - const result = await installKibanaSavedObjects({ - logger, - savedObjectsImporter, - kibanaAssets: assetChunk, - }); - installedAssets = installedAssets.concat(result); - } - } else { - installedAssets = await installKibanaSavedObjects({ - logger, - savedObjectsImporter, - kibanaAssets: assetsToInstall, - }); - } - - return installedAssets; + return await installKibanaSavedObjects({ + logger, + savedObjectsImporter, + kibanaAssets: assetsToInstall, + assetsChunkSize: MAX_ASSETS_TO_INSTALL_IN_PARALLEL, + }); } export async function installKibanaAssetsAndReferencesMultispace({ @@ -411,13 +388,71 @@ async function retryImportOnConflictError( // only exported for testing export async function installKibanaSavedObjects({ + savedObjectsImporter, + kibanaAssets, + assetsChunkSize, + logger, +}: { + kibanaAssets: ArchiveAsset[]; + savedObjectsImporter: SavedObjectsImporterContract; + logger: Logger; + assetsChunkSize?: number; +}): Promise { + if (!assetsChunkSize || kibanaAssets.length <= assetsChunkSize || hasReferences(kibanaAssets)) { + return await installKibanaSavedObjectsChunk({ + logger, + savedObjectsImporter, + kibanaAssets, + refresh: 'wait_for', + }); + } + + const installedAssets: SavedObjectsImportSuccess[] = []; + + // If the package size is too large, we need to install in chunks to avoid + // memory issues as the SO import creates a lot of objects in memory + + // NOTE: if there are references, we can't chunk the install because + // referenced objects might end up in different chunks leading to import + // errors. + const assetChunks = chunk(kibanaAssets, assetsChunkSize); + const allAssetChunksButLast = assetChunks.slice(0, -1); + const lastAssetChunk = assetChunks.slice(-1)[0]; + + for (const assetChunk of allAssetChunksButLast) { + const result = await installKibanaSavedObjectsChunk({ + logger, + savedObjectsImporter, + kibanaAssets: assetChunk, + refresh: false, + }); + + installedAssets.push(...result); + } + + const result = await installKibanaSavedObjectsChunk({ + logger, + savedObjectsImporter, + kibanaAssets: lastAssetChunk, + refresh: 'wait_for', + }); + + installedAssets.push(...result); + + return installedAssets; +} + +// only exported for testing +async function installKibanaSavedObjectsChunk({ savedObjectsImporter, kibanaAssets, logger, + refresh, }: { kibanaAssets: ArchiveAsset[]; savedObjectsImporter: SavedObjectsImporterContract; logger: Logger; + refresh?: boolean | 'wait_for'; }) { if (!kibanaAssets.length) { return []; @@ -437,8 +472,8 @@ export async function installKibanaSavedObjects({ overwrite: true, readStream, createNewCopies: false, - refresh: false, managed: true, + refresh, }); }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/install_large_prebuilt_rules_package.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/install_large_prebuilt_rules_package.ts index 10a5adaf83346..29ca3eea30239 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/install_large_prebuilt_rules_package.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/large_prebuilt_rules_package/trial_license_complete_tier/install_large_prebuilt_rules_package.ts @@ -18,8 +18,7 @@ export default ({ getService }: FtrProviderContext): void => { const supertest = getService('supertest'); const log = getService('log'); - // Failing: See https://github.com/elastic/kibana/issues/192479 - describe.skip('@ess @serverless @skipInServerlessMKI install_large_prebuilt_rules_package', () => { + describe('@ess @serverless @skipInServerlessMKI install_large_prebuilt_rules_package', () => { beforeEach(async () => { await deleteAllRules(supertest, log); await deleteAllPrebuiltRuleAssets(es, log); @@ -36,9 +35,12 @@ export default ({ getService }: FtrProviderContext): void => { es, supertest ); - expect(statusBeforePackageInstallation.rules_installed).toBe(0); - expect(statusBeforePackageInstallation.rules_not_installed).toBe(0); - expect(statusBeforePackageInstallation.rules_not_updated).toBe(0); + + expect(statusBeforePackageInstallation).toMatchObject({ + rules_installed: 0, + rules_not_installed: 0, + rules_not_updated: 0, + }); // Install the package with 15000 prebuilt historical version of rules rules and 750 unique rules await installPrebuiltRulesAndTimelines(es, supertest); @@ -48,9 +50,12 @@ export default ({ getService }: FtrProviderContext): void => { es, supertest ); - expect(statusAfterPackageInstallation.rules_installed).toBe(750); - expect(statusAfterPackageInstallation.rules_not_installed).toBe(0); - expect(statusAfterPackageInstallation.rules_not_updated).toBe(0); + + expect(statusAfterPackageInstallation).toMatchObject({ + rules_installed: 750, + rules_not_installed: 0, + rules_not_updated: 0, + }); }); }); }; From bb1898ec8f56fd77cfe0858cce243d714e788194 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Mon, 16 Sep 2024 17:22:03 -0400 Subject: [PATCH 041/139] feat(rca): display investigations stats (#193069) --- .../rest_specs/get_all_investigation_stats.ts | 25 ++++++ .../src/rest_specs/index.ts | 2 + .../src/schema/index.ts | 2 + .../src/schema/investigation.ts | 3 + .../public/hooks/query_key_factory.ts | 1 + .../use_fetch_all_investigation_stats.ts | 73 ++++++++++++++++ .../list/components/investigation_list.tsx | 17 ++-- .../list/components/investigation_stats.tsx | 83 +++++++++++++++++++ ...investigate_app_server_route_repository.ts | 17 ++++ .../services/get_all_investigation_stats.ts | 19 +++++ .../services/investigation_repository.ts | 42 ++++++++++ .../server/services/update_investigation.ts | 10 ++- 12 files changed, 286 insertions(+), 8 deletions(-) create mode 100644 packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_stats.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_stats.tsx create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_stats.ts diff --git a/packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts b/packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts new file mode 100644 index 0000000000000..bee9f15db587d --- /dev/null +++ b/packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts @@ -0,0 +1,25 @@ +/* + * 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 { z } from '@kbn/zod'; +import { statusSchema } from '../schema'; + +const getAllInvestigationStatsParamsSchema = z.object({ + query: z.object({}), +}); + +const getAllInvestigationStatsResponseSchema = z.object({ + count: z.record(statusSchema, z.number()), + total: z.number(), +}); + +type GetAllInvestigationStatsResponse = z.output; + +export { getAllInvestigationStatsParamsSchema, getAllInvestigationStatsResponseSchema }; +export type { GetAllInvestigationStatsResponse }; diff --git a/packages/kbn-investigation-shared/src/rest_specs/index.ts b/packages/kbn-investigation-shared/src/rest_specs/index.ts index 9b81aca896f55..c00ec5035765e 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/index.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/index.ts @@ -17,6 +17,7 @@ export type * from './find'; export type * from './get'; export type * from './get_items'; export type * from './get_notes'; +export type * from './get_all_investigation_stats'; export type * from './get_all_investigation_tags'; export type * from './investigation'; export type * from './investigation_item'; @@ -35,6 +36,7 @@ export * from './find'; export * from './get'; export * from './get_items'; export * from './get_notes'; +export * from './get_all_investigation_stats'; export * from './get_all_investigation_tags'; export * from './investigation'; export * from './investigation_item'; diff --git a/packages/kbn-investigation-shared/src/schema/index.ts b/packages/kbn-investigation-shared/src/schema/index.ts index f48b6a40416d0..7491ecce76cc2 100644 --- a/packages/kbn-investigation-shared/src/schema/index.ts +++ b/packages/kbn-investigation-shared/src/schema/index.ts @@ -11,3 +11,5 @@ export * from './investigation'; export * from './investigation_item'; export * from './investigation_note'; export * from './origin'; + +export type * from './investigation'; diff --git a/packages/kbn-investigation-shared/src/schema/investigation.ts b/packages/kbn-investigation-shared/src/schema/investigation.ts index 47d198665657d..9be39b5b2a7b3 100644 --- a/packages/kbn-investigation-shared/src/schema/investigation.ts +++ b/packages/kbn-investigation-shared/src/schema/investigation.ts @@ -36,4 +36,7 @@ const investigationSchema = z.object({ items: z.array(investigationItemSchema), }); +type Status = z.infer; + +export type { Status }; export { investigationSchema, statusSchema }; diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts index 454c77ddf56e0..85a8c35b63a5e 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/query_key_factory.ts @@ -10,6 +10,7 @@ export const investigationKeys = { all: ['investigations'] as const, tags: () => [...investigationKeys.all, 'tags'] as const, + stats: () => [...investigationKeys.all, 'stats'] as const, lists: () => [...investigationKeys.all, 'list'] as const, list: (params: { page: number; perPage: number; search?: string; filter?: string }) => [...investigationKeys.lists(), params] as const, diff --git a/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_stats.ts b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_stats.ts new file mode 100644 index 0000000000000..2b2c8b92b0d4f --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/hooks/use_fetch_all_investigation_stats.ts @@ -0,0 +1,73 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { GetAllInvestigationStatsResponse, Status } from '@kbn/investigation-shared'; +import { useQuery } from '@tanstack/react-query'; +import { investigationKeys } from './query_key_factory'; +import { useKibana } from './use_kibana'; + +export interface Response { + isInitialLoading: boolean; + isLoading: boolean; + isRefetching: boolean; + isSuccess: boolean; + isError: boolean; + data: { count: Record; total: number } | undefined; +} + +export function useFetchAllInvestigationStats(): Response { + const { + core: { + http, + notifications: { toasts }, + }, + } = useKibana(); + + const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({ + queryKey: investigationKeys.stats(), + queryFn: async ({ signal }) => { + const response = await http.get( + `/api/observability/investigations/_stats`, + { + version: '2023-10-31', + signal, + } + ); + + return { + count: { + triage: response.count.triage ?? 0, + active: response.count.active ?? 0, + mitigated: response.count.mitigated ?? 0, + resolved: response.count.resolved ?? 0, + cancelled: response.count.cancelled ?? 0, + }, + total: response.total ?? 0, + }; + }, + retry: false, + cacheTime: 600 * 1000, // 10 minutes + staleTime: 0, + onError: (error: Error) => { + toasts.addError(error, { + title: i18n.translate('xpack.investigateApp.useFetchAllInvestigationStats.errorTitle', { + defaultMessage: 'Something went wrong while fetching the investigation stats', + }), + }); + }, + }); + + return { + data, + isInitialLoading, + isLoading, + isRefetching, + isSuccess, + isError, + }; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx index 8e1bc793b545e..d75710f817703 100644 --- a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_list.tsx @@ -10,6 +10,7 @@ import { EuiBasicTable, EuiBasicTableColumn, EuiFlexGroup, + EuiFlexItem, EuiLink, EuiLoadingSpinner, EuiText, @@ -23,6 +24,7 @@ import { InvestigationStatusBadge } from '../../../components/investigation_stat import { useFetchInvestigationList } from '../../../hooks/use_fetch_investigation_list'; import { useKibana } from '../../../hooks/use_kibana'; import { InvestigationListActions } from './investigation_list_actions'; +import { InvestigationStats } from './investigation_stats'; import { InvestigationsError } from './investigations_error'; import { SearchBar } from './search_bar/search_bar'; @@ -82,11 +84,15 @@ export function InvestigationList() { defaultMessage: 'Tags', }), render: (value: InvestigationResponse['tags']) => { - return value.map((tag) => ( - - {tag} - - )); + return ( + + {value.map((tag) => ( + + {tag} + + ))} + + ); }, }, { @@ -153,6 +159,7 @@ export function InvestigationList() { return ( + setSearch(value)} diff --git a/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_stats.tsx b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_stats.tsx new file mode 100644 index 0000000000000..7f654dce415c9 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/public/pages/list/components/investigation_stats.tsx @@ -0,0 +1,83 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import numeral from '@elastic/numeral'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiStat } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { useFetchAllInvestigationStats } from '../../../hooks/use_fetch_all_investigation_stats'; +import { useKibana } from '../../../hooks/use_kibana'; + +export function InvestigationStats() { + const { + core: { uiSettings }, + } = useKibana(); + const { data, isLoading: isStatsLoading } = useFetchAllInvestigationStats(); + const numberFormat = uiSettings.get('format:number:defaultPattern'); + + return ( + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts index 5d62b745e0a73..b0ecd89275914 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts @@ -13,6 +13,7 @@ import { deleteInvestigationNoteParamsSchema, deleteInvestigationParamsSchema, findInvestigationsParamsSchema, + getAllInvestigationStatsParamsSchema, getAllInvestigationTagsParamsSchema, getInvestigationItemsParamsSchema, getInvestigationNotesParamsSchema, @@ -37,6 +38,7 @@ import { updateInvestigation } from '../services/update_investigation'; import { updateInvestigationItem } from '../services/update_investigation_item'; import { updateInvestigationNote } from '../services/update_investigation_note'; import { createInvestigateAppServerRoute } from './create_investigate_app_server_route'; +import { getAllInvestigationStats } from '../services/get_all_investigation_stats'; const createInvestigationRoute = createInvestigateAppServerRoute({ endpoint: 'POST /api/observability/investigations 2023-10-31', @@ -154,6 +156,20 @@ const getAllInvestigationTagsRoute = createInvestigateAppServerRoute({ }, }); +const getAllInvestigationStatsRoute = createInvestigateAppServerRoute({ + endpoint: 'GET /api/observability/investigations/_stats 2023-10-31', + options: { + tags: [], + }, + params: getAllInvestigationStatsParamsSchema, + handler: async ({ params, context, request, logger }) => { + const soClient = (await context.core).savedObjects.client; + const repository = investigationRepositoryFactory({ soClient, logger }); + + return await getAllInvestigationStats(repository); + }, +}); + const getInvestigationNotesRoute = createInvestigateAppServerRoute({ endpoint: 'GET /api/observability/investigations/{investigationId}/notes 2023-10-31', options: { @@ -312,6 +328,7 @@ export function getGlobalInvestigateAppServerRouteRepository() { ...deleteInvestigationItemRoute, ...updateInvestigationItemRoute, ...getInvestigationItemsRoute, + ...getAllInvestigationStatsRoute, ...getAllInvestigationTagsRoute, }; } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_stats.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_stats.ts new file mode 100644 index 0000000000000..eb2304b4950c5 --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_all_investigation_stats.ts @@ -0,0 +1,19 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + GetAllInvestigationStatsResponse, + getAllInvestigationStatsResponseSchema, +} from '@kbn/investigation-shared'; +import { InvestigationRepository } from './investigation_repository'; + +export async function getAllInvestigationStats( + repository: InvestigationRepository +): Promise { + const stats = await repository.getStats(); + return getAllInvestigationStatsResponseSchema.parse(stats); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts index b7de0b96949da..ffefe757c7c72 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/investigation_repository.ts @@ -6,6 +6,7 @@ */ import { Logger, SavedObjectsClientContract } from '@kbn/core/server'; +import type { Status } from '@kbn/investigation-shared'; import { investigationSchema } from '@kbn/investigation-shared'; import { Investigation, StoredInvestigation } from '../models/investigation'; import { Paginated, Pagination } from '../models/pagination'; @@ -14,6 +15,11 @@ import { SO_INVESTIGATION_TYPE } from '../saved_objects/investigation'; export interface Search { search: string; } +interface Stats { + count: Record; + total: number; +} + export interface InvestigationRepository { save(investigation: Investigation): Promise; findById(id: string): Promise; @@ -28,6 +34,7 @@ export interface InvestigationRepository { pagination: Pagination; }): Promise>; findAllTags(): Promise; + getStats(): Promise; } export function investigationRepositoryFactory({ @@ -141,5 +148,40 @@ export function investigationRepositoryFactory({ return response.aggregations?.tags?.buckets.map((bucket) => bucket.key) ?? []; }, + + async getStats(): Promise<{ count: Record; total: number }> { + interface AggsStatusTerms { + status: { buckets: [{ key: string; doc_count: number }] }; + } + + const response = await soClient.find({ + type: SO_INVESTIGATION_TYPE, + aggs: { + status: { + terms: { + field: 'investigation.attributes.status', + size: 10, + }, + }, + }, + }); + + const countByStatus: Record = { + active: 0, + triage: 0, + mitigated: 0, + resolved: 0, + cancelled: 0, + }; + + return { + count: + response.aggregations?.status?.buckets.reduce( + (acc, bucket) => ({ ...acc, [bucket.key]: bucket.doc_count }), + countByStatus + ) ?? countByStatus, + total: response.total, + }; + }, }; } diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation.ts index b4e33c4a5f673..ee1289ec4b9fa 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/update_investigation.ts @@ -7,7 +7,7 @@ import type { AuthenticatedUser } from '@kbn/core-security-common'; import { UpdateInvestigationParams, UpdateInvestigationResponse } from '@kbn/investigation-shared'; -import { isEqual } from 'lodash'; +import { isEqual, omit } from 'lodash'; import { InvestigationRepository } from './investigation_repository'; import { Investigation } from '../models/investigation'; @@ -18,9 +18,13 @@ export async function updateInvestigation( ): Promise { const originalInvestigation = await repository.findById(investigationId); - const updatedInvestigation: Investigation = Object.assign({}, originalInvestigation, params); + const updatedInvestigation: Investigation = Object.assign({}, originalInvestigation, params, { + updatedAt: Date.now(), + }); - if (isEqual(originalInvestigation, updatedInvestigation)) { + if ( + isEqual(omit(originalInvestigation, ['updatedAt']), omit(updatedInvestigation, ['updatedAt'])) + ) { return originalInvestigation; } From d776e390b013b57badafa7951c19f279cdf0f59d Mon Sep 17 00:00:00 2001 From: Philippe Oberti Date: Mon, 16 Sep 2024 23:37:36 +0200 Subject: [PATCH 042/139] [kbn-expandable-flyout] - refactor internal redux store (#192644) --- packages/kbn-expandable-flyout/index.ts | 2 +- .../src/components/preview_section.test.tsx | 24 ++- .../src/hooks/use_expandable_flyout_api.ts | 4 +- .../src/hooks/use_expandable_flyout_state.ts | 2 +- .../src/index.stories.tsx | 140 ++++++++------ .../kbn-expandable-flyout/src/index.test.tsx | 82 ++++---- .../src/provider.test.tsx | 38 ++-- .../kbn-expandable-flyout/src/provider.tsx | 10 +- .../src/{ => store}/actions.ts | 2 +- .../reducers.test.ts} | 182 ++++++++++-------- .../src/{reducer.ts => store/reducers.ts} | 6 +- .../src/{ => store}/redux.ts | 13 +- .../src/{ => store}/state.ts | 21 +- .../src/test/provider.tsx | 10 +- 14 files changed, 308 insertions(+), 228 deletions(-) rename packages/kbn-expandable-flyout/src/{ => store}/actions.ts (98%) rename packages/kbn-expandable-flyout/src/{reducer.test.ts => store/reducers.test.ts} (78%) rename packages/kbn-expandable-flyout/src/{reducer.ts => store/reducers.ts} (96%) rename packages/kbn-expandable-flyout/src/{ => store}/redux.ts (77%) rename packages/kbn-expandable-flyout/src/{ => store}/state.ts (79%) diff --git a/packages/kbn-expandable-flyout/index.ts b/packages/kbn-expandable-flyout/index.ts index d2d304bd6aa2c..f06be45a68914 100644 --- a/packages/kbn-expandable-flyout/index.ts +++ b/packages/kbn-expandable-flyout/index.ts @@ -12,7 +12,7 @@ export { ExpandableFlyout } from './src'; export { useExpandableFlyoutApi } from './src/hooks/use_expandable_flyout_api'; export { useExpandableFlyoutState } from './src/hooks/use_expandable_flyout_state'; -export { type FlyoutState as ExpandableFlyoutState } from './src/state'; +export { type FlyoutPanels as ExpandableFlyoutState } from './src/store/state'; export { ExpandableFlyoutProvider } from './src/provider'; export { withExpandableFlyoutProvider } from './src/with_provider'; diff --git a/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx b/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx index 831e916f84f05..ba2b8987cc0a8 100644 --- a/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx +++ b/packages/kbn-expandable-flyout/src/components/preview_section.test.tsx @@ -16,18 +16,24 @@ import { PREVIEW_SECTION_TEST_ID, } from './test_ids'; import { TestProvider } from '../test/provider'; -import { State } from '../state'; +import { State } from '../store/state'; describe('PreviewSection', () => { - const context = { - right: {}, - left: {}, - preview: [ - { - id: 'key', + const context: State = { + panels: { + byId: { + flyout: { + right: undefined, + left: undefined, + preview: [ + { + id: 'key', + }, + ], + }, }, - ], - } as unknown as State; + }, + }; const component =
{'component'}
; const left = 500; diff --git a/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts b/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts index 5ae8a4e474887..e1fe482f448f9 100644 --- a/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts +++ b/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_api.ts @@ -21,8 +21,8 @@ import { openPreviewPanelAction, openRightPanelAction, previousPreviewPanelAction, -} from '../actions'; -import { useDispatch } from '../redux'; +} from '../store/actions'; +import { useDispatch } from '../store/redux'; import { FlyoutPanelProps, type ExpandableFlyoutApi } from '../types'; export type { ExpandableFlyoutApi }; diff --git a/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_state.ts b/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_state.ts index f4fbb0f1f2a3f..49cac7d97a895 100644 --- a/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_state.ts +++ b/packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_state.ts @@ -9,7 +9,7 @@ import { REDUX_ID_FOR_MEMORY_STORAGE } from '../constants'; import { useExpandableFlyoutContext } from '../context'; -import { selectPanelsById, useSelector } from '../redux'; +import { selectPanelsById, useSelector } from '../store/redux'; /** * This hook allows you to access the flyout state, read open right, left and preview panels. diff --git a/packages/kbn-expandable-flyout/src/index.stories.tsx b/packages/kbn-expandable-flyout/src/index.stories.tsx index dab81e62f9a0e..a7b1e95e43805 100644 --- a/packages/kbn-expandable-flyout/src/index.stories.tsx +++ b/packages/kbn-expandable-flyout/src/index.stories.tsx @@ -21,7 +21,7 @@ import { } from '@elastic/eui'; import { ExpandableFlyout } from '.'; import { TestProvider } from './test/provider'; -import { State } from './state'; +import { State } from './store/state'; export default { component: ExpandableFlyout, @@ -103,13 +103,15 @@ const registeredPanels = [ export const Right: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', + panels: { + byId: { + memory: { + right: { + id: 'right', + }, + left: undefined, + preview: undefined, }, - left: undefined, - preview: undefined, }, }, }; @@ -126,15 +128,17 @@ export const Right: Story = () => { export const Left: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', - }, - left: { - id: 'left', + panels: { + byId: { + memory: { + right: { + id: 'right', + }, + left: { + id: 'left', + }, + preview: undefined, }, - preview: undefined, }, }, }; @@ -151,19 +155,21 @@ export const Left: Story = () => { export const Preview: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', - }, - left: { - id: 'left', - }, - preview: [ - { - id: 'preview1', + panels: { + byId: { + memory: { + right: { + id: 'right', + }, + left: { + id: 'left', }, - ], + preview: [ + { + id: 'preview1', + }, + ], + }, }, }, }; @@ -180,22 +186,24 @@ export const Preview: Story = () => { export const MultiplePreviews: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', - }, - left: { - id: 'left', - }, - preview: [ - { - id: 'preview1', + panels: { + byId: { + memory: { + right: { + id: 'right', }, - { - id: 'preview2', + left: { + id: 'left', }, - ], + preview: [ + { + id: 'preview1', + }, + { + id: 'preview2', + }, + ], + }, }, }, }; @@ -212,13 +220,15 @@ export const MultiplePreviews: Story = () => { export const CollapsedPushVsOverlay: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', + panels: { + byId: { + memory: { + right: { + id: 'right', + }, + left: undefined, + preview: undefined, }, - left: undefined, - preview: undefined, }, }, }; @@ -232,15 +242,17 @@ export const CollapsedPushVsOverlay: Story = () => { export const ExpandedPushVsOverlay: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', - }, - left: { - id: 'left', + panels: { + byId: { + memory: { + right: { + id: 'right', + }, + left: { + id: 'left', + }, + preview: undefined, }, - preview: undefined, }, }, }; @@ -254,15 +266,17 @@ export const ExpandedPushVsOverlay: Story = () => { export const DisableTypeSelection: Story = () => { const state: State = { - byId: { - memory: { - right: { - id: 'right', - }, - left: { - id: 'left', + panels: { + byId: { + memory: { + right: { + id: 'right', + }, + left: { + id: 'left', + }, + preview: undefined, }, - preview: undefined, }, }, }; diff --git a/packages/kbn-expandable-flyout/src/index.test.tsx b/packages/kbn-expandable-flyout/src/index.test.tsx index 1ec37bcd547c0..14146e2da4541 100644 --- a/packages/kbn-expandable-flyout/src/index.test.tsx +++ b/packages/kbn-expandable-flyout/src/index.test.tsx @@ -18,7 +18,7 @@ import { SETTINGS_MENU_BUTTON_TEST_ID, RIGHT_SECTION_TEST_ID, } from './components/test_ids'; -import { type State } from './state'; +import { type State } from './store/state'; import { TestProvider } from './test/provider'; import { REDUX_ID_FOR_MEMORY_STORAGE } from './constants'; @@ -33,7 +33,9 @@ const registeredPanels: Panel[] = [ describe('ExpandableFlyout', () => { it(`shouldn't render flyout if no panels`, () => { const state: State = { - byId: {}, + panels: { + byId: {}, + }, }; const result = render( @@ -47,13 +49,15 @@ describe('ExpandableFlyout', () => { it('should render right section', () => { const state = { - byId: { - [id]: { - right: { - id: 'key', + panels: { + byId: { + [id]: { + right: { + id: 'key', + }, + left: undefined, + preview: undefined, }, - left: undefined, - preview: undefined, }, }, }; @@ -69,13 +73,15 @@ describe('ExpandableFlyout', () => { it('should render left section', () => { const state = { - byId: { - [id]: { - right: undefined, - left: { - id: 'key', + panels: { + byId: { + [id]: { + right: undefined, + left: { + id: 'key', + }, + preview: undefined, }, - preview: undefined, }, }, }; @@ -91,15 +97,17 @@ describe('ExpandableFlyout', () => { it('should render preview section', () => { const state = { - byId: { - [id]: { - right: undefined, - left: undefined, - preview: [ - { - id: 'key', - }, - ], + panels: { + byId: { + [id]: { + right: undefined, + left: undefined, + preview: [ + { + id: 'key', + }, + ], + }, }, }, }; @@ -115,13 +123,15 @@ describe('ExpandableFlyout', () => { it('should not render flyout when right has value but does not matches registered panels', () => { const state = { - byId: { - [id]: { - right: { - id: 'key1', + panels: { + byId: { + [id]: { + right: { + id: 'key1', + }, + left: undefined, + preview: undefined, }, - left: undefined, - preview: undefined, }, }, }; @@ -138,13 +148,15 @@ describe('ExpandableFlyout', () => { it('should render the menu to change display options', () => { const state = { - byId: { - [id]: { - right: { - id: 'key', + panels: { + byId: { + [id]: { + right: { + id: 'key', + }, + left: undefined, + preview: undefined, }, - left: undefined, - preview: undefined, }, }, }; diff --git a/packages/kbn-expandable-flyout/src/provider.test.tsx b/packages/kbn-expandable-flyout/src/provider.test.tsx index 5bf71f31653e9..5aa386090aa30 100644 --- a/packages/kbn-expandable-flyout/src/provider.test.tsx +++ b/packages/kbn-expandable-flyout/src/provider.test.tsx @@ -11,8 +11,8 @@ import React from 'react'; import { render } from '@testing-library/react'; import { TestProvider } from './test/provider'; import { UrlSynchronizer } from './provider'; -import * as actions from './actions'; -import { State } from './state'; +import * as actions from './store/actions'; +import { State } from './store/state'; import { of } from 'rxjs'; const mockGet = jest.fn(); @@ -28,14 +28,16 @@ describe('UrlSynchronizer', () => { const urlChangedAction = jest.spyOn(actions, 'urlChangedAction'); const initialState: State = { - byId: { - [urlKey]: { - right: { id: 'key1' }, - left: { id: 'key11' }, - preview: undefined, + panels: { + byId: { + [urlKey]: { + right: { id: 'key1' }, + left: { id: 'key11' }, + preview: undefined, + }, }, + needsSync: true, }, - needsSync: true, }; render( @@ -55,8 +57,10 @@ describe('UrlSynchronizer', () => { change$: mockChange$, }); const initialState: State = { - byId: {}, - needsSync: true, + panels: { + byId: {}, + needsSync: true, + }, }; render( @@ -81,14 +85,16 @@ describe('UrlSynchronizer', () => { change$: mockChange$, }); const initialState: State = { - byId: { - [urlKey]: { - right: { id: 'key1' }, - left: { id: 'key2' }, - preview: undefined, + panels: { + byId: { + [urlKey]: { + right: { id: 'key1' }, + left: { id: 'key2' }, + preview: undefined, + }, }, + needsSync: true, }, - needsSync: true, }; render( diff --git a/packages/kbn-expandable-flyout/src/provider.tsx b/packages/kbn-expandable-flyout/src/provider.tsx index 15bcabc11fc10..cad83bb0ee808 100644 --- a/packages/kbn-expandable-flyout/src/provider.tsx +++ b/packages/kbn-expandable-flyout/src/provider.tsx @@ -12,10 +12,10 @@ import React, { FC, PropsWithChildren, useEffect, useMemo } from 'react'; import { Provider as ReduxProvider } from 'react-redux'; import { useHistory } from 'react-router-dom'; import { ExpandableFlyoutContextProvider, useExpandableFlyoutContext } from './context'; -import { FlyoutState } from './state'; +import { FlyoutPanels } from './store/state'; import { useExpandableFlyoutState } from './hooks/use_expandable_flyout_state'; -import { Context, selectNeedsSync, store, useDispatch, useSelector } from './redux'; -import { urlChangedAction } from './actions'; +import { Context, selectNeedsSync, store, useDispatch, useSelector } from './store/redux'; +import { urlChangedAction } from './store/actions'; /** * Dispatches actions when url state changes and initializes the state when the app is loaded with flyout url parameters @@ -43,7 +43,7 @@ export const UrlSynchronizer = () => { return; } - const currentValue = urlStorage.get(urlKey); + const currentValue = urlStorage.get(urlKey); // Dispatch current value to redux store as it does not happen automatically if (currentValue) { @@ -56,7 +56,7 @@ export const UrlSynchronizer = () => { ); } - const subscription = urlStorage.change$(urlKey).subscribe((value) => { + const subscription = urlStorage.change$(urlKey).subscribe((value) => { dispatch(urlChangedAction({ ...value, preview: value?.preview?.at(-1), id: urlKey })); }); diff --git a/packages/kbn-expandable-flyout/src/actions.ts b/packages/kbn-expandable-flyout/src/store/actions.ts similarity index 98% rename from packages/kbn-expandable-flyout/src/actions.ts rename to packages/kbn-expandable-flyout/src/store/actions.ts index 6b127da797271..237a3d0226b05 100644 --- a/packages/kbn-expandable-flyout/src/actions.ts +++ b/packages/kbn-expandable-flyout/src/store/actions.ts @@ -8,7 +8,7 @@ */ import { createAction } from '@reduxjs/toolkit'; -import { FlyoutPanelProps } from './types'; +import { FlyoutPanelProps } from '../types'; export enum ActionType { openFlyout = 'open_flyout', diff --git a/packages/kbn-expandable-flyout/src/reducer.test.ts b/packages/kbn-expandable-flyout/src/store/reducers.test.ts similarity index 78% rename from packages/kbn-expandable-flyout/src/reducer.test.ts rename to packages/kbn-expandable-flyout/src/store/reducers.test.ts index 6cb56f86c6794..aafd72196d0f5 100644 --- a/packages/kbn-expandable-flyout/src/reducer.test.ts +++ b/packages/kbn-expandable-flyout/src/store/reducers.test.ts @@ -7,9 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { FlyoutPanelProps } from './types'; -import { reducer } from './reducer'; -import { initialState, State } from './state'; +import { FlyoutPanelProps } from '../types'; +import { panelsReducer } from './reducers'; +import { initialPanelsState, PanelsState } from './state'; import { closeLeftPanelAction, closePanelsAction, @@ -49,17 +49,18 @@ const previewPanel2: FlyoutPanelProps = { id: 'preview2', state: { id: 'state' }, }; -describe('reducer', () => { + +describe('panelsReducer', () => { describe('should handle openFlyout action', () => { it('should add panels to empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = openPanelsAction({ right: rightPanel1, left: leftPanel1, preview: previewPanel1, id: id1, }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -74,7 +75,7 @@ describe('reducer', () => { }); it('should override all panels in the state', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -89,7 +90,7 @@ describe('reducer', () => { preview: previewPanel2, id: id1, }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -104,7 +105,7 @@ describe('reducer', () => { }); it('should remove all panels despite only passing a single section ', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -117,7 +118,7 @@ describe('reducer', () => { right: rightPanel2, id: id1, }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -132,7 +133,7 @@ describe('reducer', () => { }); it('should add panels to a new key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -145,7 +146,7 @@ describe('reducer', () => { right: rightPanel2, id: id2, }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -167,9 +168,9 @@ describe('reducer', () => { describe('should handle openRightPanel action', () => { it('should add right panel to empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = openRightPanelAction({ right: rightPanel1, id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -184,7 +185,7 @@ describe('reducer', () => { }); it('should replace right panel', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -194,7 +195,7 @@ describe('reducer', () => { }, }; const action = openRightPanelAction({ right: rightPanel2, id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -209,7 +210,7 @@ describe('reducer', () => { }); it('should add right panel to a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -219,7 +220,7 @@ describe('reducer', () => { }, }; const action = openRightPanelAction({ right: rightPanel2, id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -241,9 +242,9 @@ describe('reducer', () => { describe('should handle openLeftPanel action', () => { it('should add left panel to empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = openLeftPanelAction({ left: leftPanel1, id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -258,7 +259,7 @@ describe('reducer', () => { }); it('should replace only left panel', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -268,7 +269,7 @@ describe('reducer', () => { }, }; const action = openLeftPanelAction({ left: leftPanel2, id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -283,7 +284,7 @@ describe('reducer', () => { }); it('should add left panel to a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -293,7 +294,7 @@ describe('reducer', () => { }, }; const action = openLeftPanelAction({ left: leftPanel2, id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -315,9 +316,9 @@ describe('reducer', () => { describe('should handle openPreviewPanel action', () => { it('should add preview panel to empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = openPreviewPanelAction({ preview: previewPanel1, id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -332,7 +333,7 @@ describe('reducer', () => { }); it('should add preview panel to the list of preview panels', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -342,7 +343,7 @@ describe('reducer', () => { }, }; const action = openPreviewPanelAction({ preview: previewPanel2, id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -357,7 +358,7 @@ describe('reducer', () => { }); it('should add preview panel to a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -367,7 +368,7 @@ describe('reducer', () => { }, }; const action = openPreviewPanelAction({ preview: previewPanel2, id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -389,15 +390,18 @@ describe('reducer', () => { describe('should handle closeRightPanel action', () => { it('should return empty state when removing right panel from empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = closeRightPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ + ...state, + needsSync: true, + }); }); it(`should return unmodified state when removing right panel when no right panel exist`, () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -407,13 +411,16 @@ describe('reducer', () => { }, }; const action = closeRightPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ + ...state, + needsSync: true, + }); }); it('should remove right panel', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -424,7 +431,7 @@ describe('reducer', () => { }; const action = closeRightPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -439,7 +446,7 @@ describe('reducer', () => { }); it('should not remove right panel for a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -450,7 +457,7 @@ describe('reducer', () => { }; const action = closeRightPanelAction({ id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -467,15 +474,18 @@ describe('reducer', () => { describe('should handle closeLeftPanel action', () => { it('should return empty state when removing left panel on empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = closeLeftPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ + ...state, + needsSync: true, + }); }); it(`should return unmodified state when removing left panel when no left panel exist`, () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: undefined, @@ -485,13 +495,16 @@ describe('reducer', () => { }, }; const action = closeLeftPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ + ...state, + needsSync: true, + }); }); it('should remove left panel', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -501,7 +514,7 @@ describe('reducer', () => { }, }; const action = closeLeftPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -516,7 +529,7 @@ describe('reducer', () => { }); it('should not remove left panel for a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -526,7 +539,7 @@ describe('reducer', () => { }, }; const action = closeLeftPanelAction({ id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -543,15 +556,18 @@ describe('reducer', () => { describe('should handle closePreviewPanel action', () => { it('should return empty state when removing preview panel on empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = closePreviewPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ + ...state, + needsSync: true, + }); }); it(`should return unmodified state when removing preview panel when no preview panel exist`, () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -561,13 +577,16 @@ describe('reducer', () => { }, }; const action = closePreviewPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: true }); + expect(newState).toEqual({ + ...state, + needsSync: true, + }); }); it('should remove all preview panels', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: rightPanel1, @@ -577,7 +596,7 @@ describe('reducer', () => { }, }; const action = closePreviewPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -592,7 +611,7 @@ describe('reducer', () => { }); it('should not remove preview panels for a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -602,7 +621,7 @@ describe('reducer', () => { }, }; const action = closePreviewPanelAction({ id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -619,15 +638,18 @@ describe('reducer', () => { describe('should handle previousPreviewPanel action', () => { it('should return empty state when previous preview panel on an empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = previousPreviewPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...initialState, needsSync: false }); + expect(newState).toEqual({ + ...initialPanelsState, + needsSync: false, + }); }); it(`should return unmodified state when previous preview panel when no preview panel exist`, () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -637,13 +659,16 @@ describe('reducer', () => { }, }; const action = previousPreviewPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...state, needsSync: false }); + expect(newState).toEqual({ + ...state, + needsSync: false, + }); }); it('should remove only last preview panel', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: rightPanel1, @@ -653,7 +678,7 @@ describe('reducer', () => { }, }; const action = previousPreviewPanelAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -668,7 +693,7 @@ describe('reducer', () => { }); it('should not remove the last preview panel for a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -678,7 +703,7 @@ describe('reducer', () => { }, }; const action = previousPreviewPanelAction({ id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -695,15 +720,18 @@ describe('reducer', () => { describe('should handle closeFlyout action', () => { it('should return empty state when closing flyout on an empty state', () => { - const state: State = initialState; + const state: PanelsState = initialPanelsState; const action = closePanelsAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); - expect(newState).toEqual({ ...initialState, needsSync: true }); + expect(newState).toEqual({ + ...initialPanelsState, + needsSync: true, + }); }); it('should remove all panels', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -713,7 +741,7 @@ describe('reducer', () => { }, }; const action = closePanelsAction({ id: id1 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { @@ -728,7 +756,7 @@ describe('reducer', () => { }); it('should not remove panels for a different key', () => { - const state: State = { + const state: PanelsState = { byId: { [id1]: { left: leftPanel1, @@ -738,7 +766,7 @@ describe('reducer', () => { }, }; const action = closePanelsAction({ id: id2 }); - const newState: State = reducer(state, action); + const newState: PanelsState = panelsReducer(state, action); expect(newState).toEqual({ byId: { diff --git a/packages/kbn-expandable-flyout/src/reducer.ts b/packages/kbn-expandable-flyout/src/store/reducers.ts similarity index 96% rename from packages/kbn-expandable-flyout/src/reducer.ts rename to packages/kbn-expandable-flyout/src/store/reducers.ts index 49c4c4b9774b1..8971fd55f7571 100644 --- a/packages/kbn-expandable-flyout/src/reducer.ts +++ b/packages/kbn-expandable-flyout/src/store/reducers.ts @@ -21,9 +21,9 @@ import { openPreviewPanelAction, urlChangedAction, } from './actions'; -import { initialState } from './state'; +import { initialPanelsState } from './state'; -export const reducer = createReducer(initialState, (builder) => { +export const panelsReducer = createReducer(initialPanelsState, (builder) => { builder.addCase(openPanelsAction, (state, { payload: { preview, left, right, id } }) => { if (id in state.byId) { state.byId[id].right = right; @@ -72,7 +72,7 @@ export const reducer = createReducer(initialState, (builder) => { if (id in state.byId) { if (state.byId[id].preview) { const previewIdenticalToLastOne = deepEqual(preview, state.byId[id].preview?.at(-1)); - // Only append preview when it does not match the last item in state.byId[id].preview + // Only append preview when it does not match the last item in state.data.byId[id].preview if (!previewIdenticalToLastOne) { state.byId[id].preview?.push(preview); } diff --git a/packages/kbn-expandable-flyout/src/redux.ts b/packages/kbn-expandable-flyout/src/store/redux.ts similarity index 77% rename from packages/kbn-expandable-flyout/src/redux.ts rename to packages/kbn-expandable-flyout/src/store/redux.ts index 5cc80517c5c9f..0e81ba74de2de 100644 --- a/packages/kbn-expandable-flyout/src/redux.ts +++ b/packages/kbn-expandable-flyout/src/store/redux.ts @@ -11,13 +11,14 @@ import { createContext } from 'react'; import { createDispatchHook, createSelectorHook, ReactReduxContextValue } from 'react-redux'; import { configureStore } from '@reduxjs/toolkit'; import { createSelector } from 'reselect'; -import { reducer } from './reducer'; +import { panelsReducer } from './reducers'; import { initialState, State } from './state'; export const store = configureStore({ - reducer, + reducer: { + panels: panelsReducer, + }, devTools: process.env.NODE_ENV !== 'production', - enhancers: [], }); export const Context = createContext>({ @@ -30,7 +31,7 @@ export const useSelector = createSelectorHook(Context); const stateSelector = (state: State) => state; +const panelsSelector = createSelector(stateSelector, (state) => state.panels); export const selectPanelsById = (id: string) => - createSelector(stateSelector, (state) => state.byId[id] || {}); - -export const selectNeedsSync = () => createSelector(stateSelector, (state) => state.needsSync); + createSelector(panelsSelector, (state) => state.byId[id] || {}); +export const selectNeedsSync = () => createSelector(panelsSelector, (state) => state.needsSync); diff --git a/packages/kbn-expandable-flyout/src/state.ts b/packages/kbn-expandable-flyout/src/store/state.ts similarity index 79% rename from packages/kbn-expandable-flyout/src/state.ts rename to packages/kbn-expandable-flyout/src/store/state.ts index 40cf03f43d868..12f1b0135460b 100644 --- a/packages/kbn-expandable-flyout/src/state.ts +++ b/packages/kbn-expandable-flyout/src/store/state.ts @@ -7,9 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { FlyoutPanelProps } from './types'; +import { FlyoutPanelProps } from '../..'; -export interface FlyoutState { +export interface FlyoutPanels { /** * Panel to render in the left section */ @@ -24,12 +24,12 @@ export interface FlyoutState { preview: FlyoutPanelProps[] | undefined; } -export interface State { +export interface PanelsState { /** * Store the panels for multiple flyouts */ byId: { - [id: string]: FlyoutState; + [id: string]: FlyoutPanels; }; /** * Is the flyout in sync with external storage (eg. url)? @@ -39,7 +39,18 @@ export interface State { needsSync?: boolean; } -export const initialState: State = { +export const initialPanelsState: PanelsState = { byId: {}, needsSync: false, }; + +export interface State { + /** + * All panels related information + */ + panels: PanelsState; +} + +export const initialState: State = { + panels: initialPanelsState, +}; diff --git a/packages/kbn-expandable-flyout/src/test/provider.tsx b/packages/kbn-expandable-flyout/src/test/provider.tsx index bf0ca914927b2..b6914099e2e42 100644 --- a/packages/kbn-expandable-flyout/src/test/provider.tsx +++ b/packages/kbn-expandable-flyout/src/test/provider.tsx @@ -12,9 +12,9 @@ import { configureStore } from '@reduxjs/toolkit'; import React, { FC, PropsWithChildren } from 'react'; import { I18nProvider } from '@kbn/i18n-react'; import { ExpandableFlyoutContextProvider } from '../context'; -import { reducer } from '../reducer'; -import { Context } from '../redux'; -import { initialState, State } from '../state'; +import { panelsReducer } from '../store/reducers'; +import { Context } from '../store/redux'; +import { initialState, State } from '../store/state'; interface TestProviderProps { state?: State; @@ -27,7 +27,9 @@ export const TestProvider: FC> = ({ urlKey, }) => { const store = configureStore({ - reducer, + reducer: { + panels: panelsReducer, + }, devTools: false, preloadedState: state, enhancers: [], From d6fdc825b4dd7c5878d32a01c4bd8ff9d5eec91e Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Mon, 16 Sep 2024 17:02:49 -0500 Subject: [PATCH 043/139] [Search][Onboarding] Use new index details page (#193058) ## Summary - Updated the empty state redirect to use the new index details page - Updated the empty state to only show "Run in Console" when cURL is the selected coding language. --- .../components/start/create_index_code.tsx | 20 ++++++++++--------- .../public/components/start/hooks/utils.ts | 5 ++--- .../svl_search_elasticsearch_start_page.ts | 4 +--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx index 4901847eeed22..b78137e7a3fdd 100644 --- a/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx +++ b/x-pack/plugins/search_indices/public/components/start/create_index_code.tsx @@ -45,21 +45,23 @@ export const CreateIndexCodeView = ({ createIndexForm }: CreateIndexCodeViewProp return ( - + setSelectedLanguage(value)} /> - - - + {selectedLanguage === 'curl' && ( + + + + )} {selectedCodeExample.installCommand && ( { - expect(await browser.getCurrentUrl()).contain( - '/app/management/data/index_management/indices/index_details' - ); + expect(await browser.getCurrentUrl()).contain('/app/elasticsearch/indices/index_details'); }); }, async expectToBeOnIndexListPage() { From 42fef0b84bda007bb24f149512cbe7de8354f339 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Mon, 16 Sep 2024 17:04:40 -0500 Subject: [PATCH 044/139] skip failing test suite (#189719) --- .../public/components/case_form_fields/assignees.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/case_form_fields/assignees.test.tsx b/x-pack/plugins/cases/public/components/case_form_fields/assignees.test.tsx index 77a781535eb91..fd0a75f6d7a28 100644 --- a/x-pack/plugins/cases/public/components/case_form_fields/assignees.test.tsx +++ b/x-pack/plugins/cases/public/components/case_form_fields/assignees.test.tsx @@ -23,7 +23,8 @@ jest.mock('../../containers/user_profiles/api'); const currentUserProfile = userProfiles[0]; -describe('Assignees', () => { +// Failing: See https://github.com/elastic/kibana/issues/189719 +describe.skip('Assignees', () => { let globalForm: FormHook; let appMockRender: AppMockRenderer; From e7c8cba25cf693bd40a2d9d4f041cfd99273ac31 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Mon, 16 Sep 2024 17:06:41 -0500 Subject: [PATCH 045/139] skip failing test suite (#192944) --- .../cases/public/components/files/file_name_link.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/files/file_name_link.test.tsx b/x-pack/plugins/cases/public/components/files/file_name_link.test.tsx index 0fa3324d295f3..efededf3fba89 100644 --- a/x-pack/plugins/cases/public/components/files/file_name_link.test.tsx +++ b/x-pack/plugins/cases/public/components/files/file_name_link.test.tsx @@ -15,7 +15,8 @@ import { createAppMockRenderer } from '../../common/mock'; import { basicFileMock } from '../../containers/mock'; import { FileNameLink } from './file_name_link'; -describe('FileNameLink', () => { +// Failing: See https://github.com/elastic/kibana/issues/192944 +describe.skip('FileNameLink', () => { let appMockRender: AppMockRenderer; const defaultProps = { From 760379ebf344f428551dfa63d046a043e61a7740 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 17 Sep 2024 08:10:21 +1000 Subject: [PATCH 046/139] skip failing test suite (#191808) --- test/functional/apps/console/monaco/_autocomplete.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/console/monaco/_autocomplete.ts b/test/functional/apps/console/monaco/_autocomplete.ts index 36d96443a5a69..6e0d83ffcd56e 100644 --- a/test/functional/apps/console/monaco/_autocomplete.ts +++ b/test/functional/apps/console/monaco/_autocomplete.ts @@ -34,7 +34,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); } - describe('console autocomplete feature', function describeIndexTests() { + // Failing: See https://github.com/elastic/kibana/issues/191808 + describe.skip('console autocomplete feature', function describeIndexTests() { this.tags('includeFirefox'); before(async () => { log.debug('navigateTo console'); From f6510f67f73804e01a783ed9a57ef72f84bbe9bd Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Mon, 16 Sep 2024 17:10:56 -0500 Subject: [PATCH 047/139] skip failing test suite (#192999) --- .../integrations/sections/epm/screens/detail/index.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx index 4617cc9bd8b1f..58c512a26c294 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.test.tsx @@ -39,7 +39,8 @@ import { Detail } from '.'; // @ts-ignore this saves us having to define all experimental features ExperimentalFeaturesService.init({}); -describe('when on integration detail', () => { +// Failing: See https://github.com/elastic/kibana/issues/192999 +describe.skip('when on integration detail', () => { const pkgkey = 'nginx-0.3.7'; const detailPageUrlPath = pagePathGetters.integration_details_overview({ pkgkey })[1]; let testRenderer: TestRenderer; From 4405f94cad29adf5adf2424e69cbc030e11883f7 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 16 Sep 2024 18:47:45 -0400 Subject: [PATCH 048/139] [Fleet] Add new space aware saved object type to Fleet saved object permissions (#193025) --- x-pack/plugins/fleet/server/plugin.ts | 11 ++- .../apis/space_awareness/agent_policies.ts | 9 ++- .../apis/space_awareness/api_helper.ts | 4 ++ .../platform_security/authorization.ts | 68 +++++++++++++++++++ 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index 3967c3b6abc7c..21c3f1bf97f12 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -66,7 +66,12 @@ import { } from '../common'; import type { ExperimentalFeatures } from '../common/experimental_features'; import { parseExperimentalConfigValue } from '../common/experimental_features'; - +import { + LEGACY_PACKAGE_POLICY_SAVED_OBJECT_TYPE, + PACKAGE_POLICY_SAVED_OBJECT_TYPE, + AGENT_POLICY_SAVED_OBJECT_TYPE, + LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE, +} from '../common/constants'; import { getFilesClientFactory } from './services/files/get_files_client_factory'; import type { MessageSigningServiceInterface } from './services/security'; @@ -79,12 +84,10 @@ import { } from './services/security'; import { - LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE, ASSETS_SAVED_OBJECT_TYPE, DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, FLEET_SERVER_HOST_SAVED_OBJECT_TYPE, OUTPUT_SAVED_OBJECT_TYPE, - PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGES_SAVED_OBJECT_TYPE, PLUGIN_ID, PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, @@ -191,6 +194,8 @@ export type FleetSetupContract = void; const allSavedObjectTypes = [ OUTPUT_SAVED_OBJECT_TYPE, LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE, + AGENT_POLICY_SAVED_OBJECT_TYPE, + LEGACY_PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGE_POLICY_SAVED_OBJECT_TYPE, PACKAGES_SAVED_OBJECT_TYPE, ASSETS_SAVED_OBJECT_TYPE, diff --git a/x-pack/test/fleet_api_integration/apis/space_awareness/agent_policies.ts b/x-pack/test/fleet_api_integration/apis/space_awareness/agent_policies.ts index 40e163dfabf47..037ba332cfefb 100644 --- a/x-pack/test/fleet_api_integration/apis/space_awareness/agent_policies.ts +++ b/x-pack/test/fleet_api_integration/apis/space_awareness/agent_policies.ts @@ -11,10 +11,11 @@ import { FtrProviderContext } from '../../../api_integration/ftr_provider_contex import { skipIfNoDockerRegistry } from '../../helpers'; import { SpaceTestApiClient } from './api_helper'; import { cleanFleetIndices, expectToRejectWithNotFound } from './helpers'; +import { setupTestUsers, testUsers } from '../test_users'; export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; - const supertest = getService('supertest'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); const esClient = getService('es'); const kibanaServer = getService('kibanaServer'); const spaces = getService('spaces'); @@ -22,13 +23,17 @@ export default function (providerContext: FtrProviderContext) { describe('agent policies', function () { skipIfNoDockerRegistry(providerContext); - const apiClient = new SpaceTestApiClient(supertest); + const apiClient = new SpaceTestApiClient(supertestWithoutAuth, { + username: testUsers.fleet_all_int_all.username, + password: testUsers.fleet_all_int_all.password, + }); let defaultSpacePolicy1: CreateAgentPolicyResponse; let spaceTest1Policy1: CreateAgentPolicyResponse; let spaceTest1Policy2: CreateAgentPolicyResponse; before(async () => { + await setupTestUsers(getService('security')); TEST_SPACE_1 = spaces.getDefaultTestSpace(); await kibanaServer.savedObjects.cleanStandardList(); await kibanaServer.savedObjects.cleanStandardList({ diff --git a/x-pack/test/fleet_api_integration/apis/space_awareness/api_helper.ts b/x-pack/test/fleet_api_integration/apis/space_awareness/api_helper.ts index 9009e2b81a73b..1de90ae3dcfaa 100644 --- a/x-pack/test/fleet_api_integration/apis/space_awareness/api_helper.ts +++ b/x-pack/test/fleet_api_integration/apis/space_awareness/api_helper.ts @@ -133,6 +133,7 @@ export class SpaceTestApiClient { async deleteAgentPolicy(agentPolicyId: string, spaceId?: string) { await this.supertest .post(`${this.getBaseUrl(spaceId)}/api/fleet/agent_policies/delete`) + .auth(this.auth.username, this.auth.password) .send({ agentPolicyId, }) @@ -142,6 +143,7 @@ export class SpaceTestApiClient { async getAgentPolicy(policyId: string, spaceId?: string): Promise { const { body: res } = await this.supertest .get(`${this.getBaseUrl(spaceId)}/api/fleet/agent_policies/${policyId}`) + .auth(this.auth.username, this.auth.password) .expect(200); return res; @@ -172,6 +174,7 @@ export class SpaceTestApiClient { async getAgentPolicies(spaceId?: string): Promise { const { body: res } = await this.supertest .get(`${this.getBaseUrl(spaceId)}/api/fleet/agent_policies`) + .auth(this.auth.username, this.auth.password) .expect(200); return res; @@ -482,6 +485,7 @@ export class SpaceTestApiClient { async postEnableSpaceAwareness(spaceId?: string): Promise { const { body: res } = await this.supertest .post(`${this.getBaseUrl(spaceId)}/internal/fleet/enable_space_awareness`) + .auth(this.auth.username, this.auth.password) .set('kbn-xsrf', 'xxxx') .set('elastic-api-version', '1'); diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts index 329b9be0de561..2e41125e8265b 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/platform_security/authorization.ts @@ -3666,6 +3666,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:ingest-agent-policies/delete", "saved_object:ingest-agent-policies/bulk_delete", "saved_object:ingest-agent-policies/share_to_space", + "saved_object:fleet-agent-policies/bulk_get", + "saved_object:fleet-agent-policies/get", + "saved_object:fleet-agent-policies/find", + "saved_object:fleet-agent-policies/open_point_in_time", + "saved_object:fleet-agent-policies/close_point_in_time", + "saved_object:fleet-agent-policies/create", + "saved_object:fleet-agent-policies/bulk_create", + "saved_object:fleet-agent-policies/update", + "saved_object:fleet-agent-policies/bulk_update", + "saved_object:fleet-agent-policies/delete", + "saved_object:fleet-agent-policies/bulk_delete", + "saved_object:fleet-agent-policies/share_to_space", "saved_object:ingest-package-policies/bulk_get", "saved_object:ingest-package-policies/get", "saved_object:ingest-package-policies/find", @@ -3678,6 +3690,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:ingest-package-policies/delete", "saved_object:ingest-package-policies/bulk_delete", "saved_object:ingest-package-policies/share_to_space", + "saved_object:fleet-package-policies/bulk_get", + "saved_object:fleet-package-policies/get", + "saved_object:fleet-package-policies/find", + "saved_object:fleet-package-policies/open_point_in_time", + "saved_object:fleet-package-policies/close_point_in_time", + "saved_object:fleet-package-policies/create", + "saved_object:fleet-package-policies/bulk_create", + "saved_object:fleet-package-policies/update", + "saved_object:fleet-package-policies/bulk_update", + "saved_object:fleet-package-policies/delete", + "saved_object:fleet-package-policies/bulk_delete", + "saved_object:fleet-package-policies/share_to_space", "saved_object:epm-packages/bulk_get", "saved_object:epm-packages/get", "saved_object:epm-packages/find", @@ -3993,6 +4017,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:ingest-agent-policies/delete", "saved_object:ingest-agent-policies/bulk_delete", "saved_object:ingest-agent-policies/share_to_space", + "saved_object:fleet-agent-policies/bulk_get", + "saved_object:fleet-agent-policies/get", + "saved_object:fleet-agent-policies/find", + "saved_object:fleet-agent-policies/open_point_in_time", + "saved_object:fleet-agent-policies/close_point_in_time", + "saved_object:fleet-agent-policies/create", + "saved_object:fleet-agent-policies/bulk_create", + "saved_object:fleet-agent-policies/update", + "saved_object:fleet-agent-policies/bulk_update", + "saved_object:fleet-agent-policies/delete", + "saved_object:fleet-agent-policies/bulk_delete", + "saved_object:fleet-agent-policies/share_to_space", "saved_object:ingest-package-policies/bulk_get", "saved_object:ingest-package-policies/get", "saved_object:ingest-package-policies/find", @@ -4005,6 +4041,18 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:ingest-package-policies/delete", "saved_object:ingest-package-policies/bulk_delete", "saved_object:ingest-package-policies/share_to_space", + "saved_object:fleet-package-policies/bulk_get", + "saved_object:fleet-package-policies/get", + "saved_object:fleet-package-policies/find", + "saved_object:fleet-package-policies/open_point_in_time", + "saved_object:fleet-package-policies/close_point_in_time", + "saved_object:fleet-package-policies/create", + "saved_object:fleet-package-policies/bulk_create", + "saved_object:fleet-package-policies/update", + "saved_object:fleet-package-policies/bulk_update", + "saved_object:fleet-package-policies/delete", + "saved_object:fleet-package-policies/bulk_delete", + "saved_object:fleet-package-policies/share_to_space", "saved_object:epm-packages/bulk_get", "saved_object:epm-packages/get", "saved_object:epm-packages/find", @@ -4305,11 +4353,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:ingest-agent-policies/find", "saved_object:ingest-agent-policies/open_point_in_time", "saved_object:ingest-agent-policies/close_point_in_time", + "saved_object:fleet-agent-policies/bulk_get", + "saved_object:fleet-agent-policies/get", + "saved_object:fleet-agent-policies/find", + "saved_object:fleet-agent-policies/open_point_in_time", + "saved_object:fleet-agent-policies/close_point_in_time", "saved_object:ingest-package-policies/bulk_get", "saved_object:ingest-package-policies/get", "saved_object:ingest-package-policies/find", "saved_object:ingest-package-policies/open_point_in_time", "saved_object:ingest-package-policies/close_point_in_time", + "saved_object:fleet-package-policies/bulk_get", + "saved_object:fleet-package-policies/get", + "saved_object:fleet-package-policies/find", + "saved_object:fleet-package-policies/open_point_in_time", + "saved_object:fleet-package-policies/close_point_in_time", "saved_object:epm-packages/bulk_get", "saved_object:epm-packages/get", "saved_object:epm-packages/find", @@ -4457,11 +4515,21 @@ export default function ({ getService }: FtrProviderContext) { "saved_object:ingest-agent-policies/find", "saved_object:ingest-agent-policies/open_point_in_time", "saved_object:ingest-agent-policies/close_point_in_time", + "saved_object:fleet-agent-policies/bulk_get", + "saved_object:fleet-agent-policies/get", + "saved_object:fleet-agent-policies/find", + "saved_object:fleet-agent-policies/open_point_in_time", + "saved_object:fleet-agent-policies/close_point_in_time", "saved_object:ingest-package-policies/bulk_get", "saved_object:ingest-package-policies/get", "saved_object:ingest-package-policies/find", "saved_object:ingest-package-policies/open_point_in_time", "saved_object:ingest-package-policies/close_point_in_time", + "saved_object:fleet-package-policies/bulk_get", + "saved_object:fleet-package-policies/get", + "saved_object:fleet-package-policies/find", + "saved_object:fleet-package-policies/open_point_in_time", + "saved_object:fleet-package-policies/close_point_in_time", "saved_object:epm-packages/bulk_get", "saved_object:epm-packages/get", "saved_object:epm-packages/find", From ac3a6da5ef23f0bb4f608ab0722441e95acc514d Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Mon, 16 Sep 2024 18:06:33 -0500 Subject: [PATCH 049/139] skip failing test suite (#192674) --- .../public/components/all_cases/assignees_column.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/all_cases/assignees_column.test.tsx b/x-pack/plugins/cases/public/components/all_cases/assignees_column.test.tsx index 615537fd7d143..0ca3f4314bd96 100644 --- a/x-pack/plugins/cases/public/components/all_cases/assignees_column.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/assignees_column.test.tsx @@ -14,7 +14,8 @@ import { userProfiles, userProfilesMap } from '../../containers/user_profiles/ap import type { AssigneesColumnProps } from './assignees_column'; import { AssigneesColumn } from './assignees_column'; -describe('AssigneesColumn', () => { +// Failing: See https://github.com/elastic/kibana/issues/192674 +describe.skip('AssigneesColumn', () => { const defaultProps: AssigneesColumnProps = { assignees: userProfiles, userProfiles: userProfilesMap, From a751a7fa604c6ae1a99a281c91b7070d74857719 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:09:35 +1000 Subject: [PATCH 050/139] skip failing test suite (#193072) --- .../spaces_only/tests/alerting/group2/monitoring.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/monitoring.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/monitoring.ts index 95d2a08a57d33..a86db4a8c27e4 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/monitoring.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group2/monitoring.ts @@ -14,7 +14,8 @@ import { FtrProviderContext } from '../../../../common/ftr_provider_context'; export default function monitoringAlertTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - describe('monitoring', () => { + // Failing: See https://github.com/elastic/kibana/issues/193072 + describe.skip('monitoring', () => { const objectRemover = new ObjectRemover(supertest); after(async () => await objectRemover.removeAll()); From c5c79a954c262d58905f27bfcee90633084a03a6 Mon Sep 17 00:00:00 2001 From: Jon Date: Mon, 16 Sep 2024 18:14:12 -0500 Subject: [PATCH 051/139] [ci/cloud deploy] Remove enterprise search (#193101) --- .buildkite/scripts/steps/cloud/deploy.json | 27 ---------------------- 1 file changed, 27 deletions(-) diff --git a/.buildkite/scripts/steps/cloud/deploy.json b/.buildkite/scripts/steps/cloud/deploy.json index d139af131f0a9..3080f083aadfd 100644 --- a/.buildkite/scripts/steps/cloud/deploy.json +++ b/.buildkite/scripts/steps/cloud/deploy.json @@ -161,33 +161,6 @@ "ref_id": "main-elasticsearch" } ], - "enterprise_search": [ - { - "elasticsearch_cluster_ref_id": "main-elasticsearch", - "region": "gcp-us-west2", - "plan": { - "cluster_topology": [ - { - "node_type": { - "connector": true, - "appserver": true, - "worker": true - }, - "instance_configuration_id": "gcp.enterprisesearch.1", - "zone_count": 1, - "size": { - "resource": "memory", - "value": 2048 - } - } - ], - "enterprise_search": { - "version": null - } - }, - "ref_id": "main-enterprise_search" - } - ], "kibana": [ { "elasticsearch_cluster_ref_id": "main-elasticsearch", From 134b81572c4234e9c813aa5ed5dda286a99ffc32 Mon Sep 17 00:00:00 2001 From: Jiawei Wu <74562234+JiaweiWu@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:52:00 -0700 Subject: [PATCH 052/139] [Response Ops] Fix maintenance window custom schedule create and update error (#192649) ## Summary Fixes a bug where the backend would throw an error if we tried to create or update a maintenance window with a custom schedule. This was due to the `form-lib` converting everything `frequency`, `interval`, and `customFrequency` field to a string and our logic assumed it was a number so the `===` comparisons were failing. ### How to test: 1. Navigate to the create maintenance window form 2. Attempt to create a maintenance window with a custom schedule 3. Assert the maintenance window was created successfully 4. Attempt to edit the maintenance window with a different custom schedule 5. Assert the maintenance window was edited successfully Fixes: https://github.com/elastic/kibana/issues/192601 --------- Co-authored-by: Elastic Machine --- .../routes/r_rule/request/schemas/v1.ts | 10 +- .../create_maintenance_windows_form.test.tsx | 16 ++- .../create_maintenance_windows_form.tsx | 6 +- .../components/empty_prompt.tsx | 7 +- .../custom_recurring_schedule.test.tsx | 38 ++++-- .../custom_recurring_schedule.tsx | 20 ++- .../recurring_schedule.test.tsx | 20 ++- .../recurring_schedule.tsx | 24 +++- .../pages/maintenance_windows/constants.ts | 23 +++- .../helpers/convert_to_rrule.ts | 13 +- .../helpers/parse_schedule.ts | 45 +++++++ .../helpers/recurring_summary.ts | 122 +++++++++--------- .../r_rule/schemas/r_rule_request_schema.ts | 10 +- .../server/routes/lib/rrule_schema.ts | 16 ++- .../maintenance_windows/index.ts | 2 + .../maintenance_window_create_form.ts | 96 ++++++++++++++ .../maintenance_window_update_form.ts | 79 ++++++++++++ .../maintenance_windows_table.ts | 10 +- .../maintenance_windows/utils.ts | 15 +-- 19 files changed, 435 insertions(+), 137 deletions(-) create mode 100644 x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/parse_schedule.ts create mode 100644 x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_create_form.ts create mode 100644 x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_update_form.ts diff --git a/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts index 43528f7c0f722..78f8f24221a59 100644 --- a/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/r_rule/request/schemas/v1.ts @@ -21,16 +21,22 @@ export const rRuleRequestSchema = schema.object({ interval: schema.maybe( schema.number({ validate: (interval: number) => { - if (interval < 1) return 'rRule interval must be > 0'; + if (!Number.isInteger(interval)) { + return 'rRule interval must be an integer greater than 0'; + } }, + min: 1, }) ), until: schema.maybe(schema.string({ validate: validateEndDateV1 })), count: schema.maybe( schema.number({ validate: (count: number) => { - if (count < 1) return 'rRule count must be > 0'; + if (!Number.isInteger(count)) { + return 'rRule count must be an integer greater than 0'; + } }, + min: 1, }) ), byweekday: schema.maybe( diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.test.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.test.tsx index acf926ac7ff2d..070e88f8b3e73 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.test.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.test.tsx @@ -96,12 +96,16 @@ describe('CreateMaintenanceWindowForm', () => { it('should initialize the form when no initialValue provided', () => { const result = appMockRenderer.render(); - const titleInput = within(result.getByTestId('title-field')).getByTestId('input'); + const titleInput = within(result.getByTestId('title-field')).getByTestId( + 'createMaintenanceWindowFormNameInput' + ); const dateInputs = within(result.getByTestId('date-field')).getAllByLabelText( // using the aria-label to query for the date-picker input 'Press the down key to open a popover containing a calendar.' ); - const recurringInput = within(result.getByTestId('recurring-field')).getByTestId('input'); + const recurringInput = within(result.getByTestId('recurring-field')).getByTestId( + 'createMaintenanceWindowRepeatSwitch' + ); expect(titleInput).toHaveValue(''); // except for the date field @@ -125,12 +129,16 @@ describe('CreateMaintenanceWindowForm', () => { /> ); - const titleInput = within(result.getByTestId('title-field')).getByTestId('input'); + const titleInput = within(result.getByTestId('title-field')).getByTestId( + 'createMaintenanceWindowFormNameInput' + ); const dateInputs = within(result.getByTestId('date-field')).getAllByLabelText( // using the aria-label to query for the date-picker input 'Press the down key to open a popover containing a calendar.' ); - const recurringInput = within(result.getByTestId('recurring-field')).getByTestId('input'); + const recurringInput = within(result.getByTestId('recurring-field')).getByTestId( + 'createMaintenanceWindowRepeatSwitch' + ); const timezoneInput = within(result.getByTestId('timezone-field')).getByTestId( 'comboBoxSearchInput' ); diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx index 6b8de98369b14..6783289963f6c 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx @@ -329,7 +329,7 @@ export const CreateMaintenanceWindowForm = React.memo +
diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/empty_prompt.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/empty_prompt.tsx index 3fd5bb04ce496..d6b7055f48fcd 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/empty_prompt.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/empty_prompt.tsx @@ -24,7 +24,12 @@ export const EmptyPrompt = React.memo( const renderActions = useMemo(() => { if (showCreateButton) { return [ - + {i18n.EMPTY_PROMPT_BUTTON} , { ); - fireEvent.change(within(result.getByTestId('custom-frequency-field')).getByTestId('select'), { - target: { value: Frequency.WEEKLY }, - }); + fireEvent.change( + within(result.getByTestId('custom-frequency-field')).getByTestId( + 'customRecurringScheduleFrequencySelect' + ), + { + target: { value: Frequency.WEEKLY }, + } + ); await waitFor(() => expect(result.getByTestId('byweekday-field')).toBeInTheDocument()); }); @@ -97,9 +102,14 @@ describe('CustomRecurringSchedule', () => { ); - fireEvent.change(within(result.getByTestId('custom-frequency-field')).getByTestId('select'), { - target: { value: Frequency.MONTHLY }, - }); + fireEvent.change( + within(result.getByTestId('custom-frequency-field')).getByTestId( + 'customRecurringScheduleFrequencySelect' + ), + { + target: { value: Frequency.MONTHLY }, + } + ); await waitFor(() => expect(result.getByTestId('bymonth-field')).toBeInTheDocument()); }); @@ -111,9 +121,11 @@ describe('CustomRecurringSchedule', () => { ); const frequencyInput = within(result.getByTestId('custom-frequency-field')).getByTestId( - 'select' + 'customRecurringScheduleFrequencySelect' + ); + const intervalInput = within(result.getByTestId('interval-field')).getByTestId( + 'customRecurringScheduleIntervalInput' ); - const intervalInput = within(result.getByTestId('interval-field')).getByTestId('input'); expect(frequencyInput).toHaveValue('2'); expect(intervalInput).toHaveValue(1); @@ -137,14 +149,16 @@ describe('CustomRecurringSchedule', () => { ); const frequencyInput = within(result.getByTestId('custom-frequency-field')).getByTestId( - 'select' + 'customRecurringScheduleFrequencySelect' + ); + const intervalInput = within(result.getByTestId('interval-field')).getByTestId( + 'customRecurringScheduleIntervalInput' ); - const intervalInput = within(result.getByTestId('interval-field')).getByTestId('input'); const input3 = within(result.getByTestId('byweekday-field')) - .getByTestId('3') + .getByTestId('isoWeekdays3') .getAttribute('aria-pressed'); const input4 = within(result.getByTestId('byweekday-field')) - .getByTestId('4') + .getByTestId('isoWeekdays4') .getAttribute('aria-pressed'); expect(frequencyInput).toHaveValue('2'); expect(intervalInput).toHaveValue(3); diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx index 749b5b8b5be30..cc8b42b2f6339 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/custom_recurring_schedule.tsx @@ -23,6 +23,7 @@ import * as i18n from '../../translations'; import { getInitialByWeekday } from '../../helpers/get_initial_by_weekday'; import { getWeekdayInfo } from '../../helpers/get_weekday_info'; import { FormProps } from '../schema'; +import { parseSchedule } from '../../helpers/parse_schedule'; const UseField = getUseField({ component: Field }); @@ -44,9 +45,13 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { ], }); + const parsedSchedule = useMemo(() => { + return parseSchedule(recurringSchedule); + }, [recurringSchedule]); + const frequencyOptions = useMemo( - () => CREATE_FORM_CUSTOM_FREQUENCY(recurringSchedule?.interval), - [recurringSchedule?.interval] + () => CREATE_FORM_CUSTOM_FREQUENCY(parsedSchedule?.interval), + [parsedSchedule?.interval] ); const bymonthOptions = useMemo(() => { @@ -69,7 +74,7 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { return ( <> - {recurringSchedule?.frequency !== Frequency.DAILY ? ( + {parsedSchedule?.frequency !== Frequency.DAILY ? ( <> @@ -81,6 +86,7 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { 'data-test-subj': 'interval-field', id: 'interval', euiFieldProps: { + 'data-test-subj': 'customRecurringScheduleIntervalInput', min: 1, prepend: ( @@ -97,6 +103,7 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { componentProps={{ 'data-test-subj': 'custom-frequency-field', euiFieldProps: { + 'data-test-subj': 'customRecurringScheduleFrequencySelect', options: frequencyOptions, }, }} @@ -106,8 +113,8 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { ) : null} - {Number(recurringSchedule?.customFrequency) === Frequency.WEEKLY || - recurringSchedule?.frequency === Frequency.DAILY ? ( + {Number(parsedSchedule?.customFrequency) === Frequency.WEEKLY || + parsedSchedule?.frequency === Frequency.DAILY ? ( { componentProps={{ 'data-test-subj': 'byweekday-field', euiFieldProps: { + 'data-test-subj': 'customRecurringScheduleByWeekdayButtonGroup', legend: 'Repeat on weekday', options: WEEKDAY_OPTIONS, }, @@ -138,7 +146,7 @@ export const CustomRecurringSchedule: React.FC = React.memo(() => { /> ) : null} - {Number(recurringSchedule?.customFrequency) === Frequency.MONTHLY ? ( + {Number(parsedSchedule?.customFrequency) === Frequency.MONTHLY ? ( { ); - const btn = within(result.getByTestId('ends-field')).getByTestId('ondate'); + const btn = within(result.getByTestId('ends-field')).getByTestId('recurrenceEndOptionOnDate'); fireEvent.click(btn); expect(result.getByTestId('until-field')).toBeInTheDocument(); @@ -77,7 +77,7 @@ describe('RecurringSchedule', () => { ); - const btn = within(result.getByTestId('ends-field')).getByTestId('afterx'); + const btn = within(result.getByTestId('ends-field')).getByTestId('recurrenceEndOptionAfterX'); fireEvent.click(btn); expect(result.getByTestId('count-field')).toBeInTheDocument(); @@ -90,8 +90,12 @@ describe('RecurringSchedule', () => { ); - const frequencyInput = within(result.getByTestId('frequency-field')).getByTestId('select'); - const endsInput = within(result.getByTestId('ends-field')).getByTestId('never'); + const frequencyInput = within(result.getByTestId('frequency-field')).getByTestId( + 'recurringScheduleRepeatSelect' + ); + const endsInput = within(result.getByTestId('ends-field')).getByTestId( + 'recurrenceEndOptionNever' + ); expect(frequencyInput).toHaveValue('3'); expect(endsInput).toHaveAttribute('aria-pressed', 'true'); @@ -112,8 +116,12 @@ describe('RecurringSchedule', () => { ); - const frequencyInput = within(result.getByTestId('frequency-field')).getByTestId('select'); - const endsInput = within(result.getByTestId('ends-field')).getByTestId('ondate'); + const frequencyInput = within(result.getByTestId('frequency-field')).getByTestId( + 'recurringScheduleRepeatSelect' + ); + const endsInput = within(result.getByTestId('ends-field')).getByTestId( + 'recurrenceEndOptionOnDate' + ); const untilInput = within(result.getByTestId('until-field')).getByLabelText( // using the aria-label to query for the date-picker input 'Press the down key to open a popover containing a calendar.' diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.tsx b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.tsx index ac4db2ba20cc2..444012ba456a8 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.tsx +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/components/recurring_schedule_form/recurring_schedule.tsx @@ -34,6 +34,7 @@ import { CustomRecurringSchedule } from './custom_recurring_schedule'; import { recurringSummary } from '../../helpers/recurring_summary'; import { getPresets } from '../../helpers/get_presets'; import { FormProps } from '../schema'; +import { parseSchedule } from '../../helpers/parse_schedule'; const UseField = getUseField({ component: Field }); @@ -70,30 +71,39 @@ export const RecurringSchedule: React.FC = React.memo(() => { { text: i18n.CREATE_FORM_FREQUENCY_DAILY, value: Frequency.DAILY, + 'data-test-subj': 'recurringScheduleOptionDaily', }, { text: i18n.CREATE_FORM_FREQUENCY_WEEKLY_ON(dayOfWeek), value: Frequency.WEEKLY, + 'data-test-subj': 'recurringScheduleOptionWeekly', }, { text: i18n.CREATE_FORM_FREQUENCY_NTH_WEEKDAY(dayOfWeek)[ isLastOfMonth ? 0 : nthWeekdayOfMonth ], value: Frequency.MONTHLY, + 'data-test-subj': 'recurringScheduleOptionMonthly', }, { text: i18n.CREATE_FORM_FREQUENCY_YEARLY_ON(date), value: Frequency.YEARLY, + 'data-test-subj': 'recurringScheduleOptionYearly', }, { text: i18n.CREATE_FORM_FREQUENCY_CUSTOM, value: 'CUSTOM', + 'data-test-subj': 'recurringScheduleOptionCustom', }, ], presets: getPresets(date), }; }, [startDate]); + const parsedSchedule = useMemo(() => { + return parseSchedule(recurringSchedule); + }, [recurringSchedule]); + return ( @@ -102,14 +112,15 @@ export const RecurringSchedule: React.FC = React.memo(() => { componentProps={{ 'data-test-subj': 'frequency-field', euiFieldProps: { + 'data-test-subj': 'recurringScheduleRepeatSelect', options, }, }} /> - {recurringSchedule?.frequency === Frequency.DAILY || - recurringSchedule?.frequency === 'CUSTOM' ? ( + {(parsedSchedule?.frequency === Frequency.DAILY || + parsedSchedule?.frequency === 'CUSTOM') && ( - ) : null} + )} { }, }} /> - {recurringSchedule?.ends === EndsOptions.ON_DATE ? ( + {parsedSchedule?.ends === EndsOptions.ON_DATE ? ( <> @@ -164,13 +175,14 @@ export const RecurringSchedule: React.FC = React.memo(() => { ) : null} - {recurringSchedule?.ends === EndsOptions.AFTER_X ? ( + {parsedSchedule?.ends === EndsOptions.AFTER_X ? ( { {i18n.CREATE_FORM_RECURRING_SUMMARY_PREFIX( - recurringSummary(moment(startDate), recurringSchedule, presets) + recurringSummary(moment(startDate), parsedSchedule, presets) )} diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts index 22b992e3e6382..05e19f0ede52c 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/constants.ts @@ -60,33 +60,50 @@ export enum EndsOptions { } export const RECURRENCE_END_OPTIONS = [ - { id: 'never', label: i18n.CREATE_FORM_ENDS_NEVER }, - { id: 'ondate', label: i18n.CREATE_FORM_ENDS_ON_DATE }, - { id: 'afterx', label: i18n.CREATE_FORM_ENDS_AFTER_X }, + { + id: 'never', + label: i18n.CREATE_FORM_ENDS_NEVER, + 'data-test-subj': 'recurrenceEndOptionNever', + }, + { + id: 'ondate', + label: i18n.CREATE_FORM_ENDS_ON_DATE, + 'data-test-subj': 'recurrenceEndOptionOnDate', + }, + { + id: 'afterx', + label: i18n.CREATE_FORM_ENDS_AFTER_X, + 'data-test-subj': 'recurrenceEndOptionAfterX', + }, ]; export const CREATE_FORM_CUSTOM_FREQUENCY = (interval: number = 1) => [ { text: i18n.CREATE_FORM_CUSTOM_FREQUENCY_DAILY(interval), value: Frequency.DAILY, + 'data-test-subj': 'customFrequencyDaily', }, { text: i18n.CREATE_FORM_CUSTOM_FREQUENCY_WEEKLY(interval), value: Frequency.WEEKLY, + 'data-test-subj': 'customFrequencyWeekly', }, { text: i18n.CREATE_FORM_CUSTOM_FREQUENCY_MONTHLY(interval), value: Frequency.MONTHLY, + 'data-test-subj': 'customFrequencyMonthly', }, { text: i18n.CREATE_FORM_CUSTOM_FREQUENCY_YEARLY(interval), value: Frequency.YEARLY, + 'data-test-subj': 'customFrequencyYearly', }, ]; export const WEEKDAY_OPTIONS = ISO_WEEKDAYS.map((n) => ({ id: String(n), label: moment().isoWeekday(n).format('ddd'), + 'data-test-subj': `isoWeekdays${n}`, })); export const ISO_WEEKDAYS_TO_RRULE: Record = { diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts index c3861a2a187ea..67e95ce3d3dbd 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/convert_to_rrule.ts @@ -12,20 +12,23 @@ import { getNthByWeekday } from './get_nth_by_weekday'; import { RecurringScheduleFormProps } from '../components/schema'; import { getPresets } from './get_presets'; import { RRuleParams } from '../../../../common'; +import { parseSchedule } from './parse_schedule'; export const convertToRRule = ( startDate: Moment, timezone: string, - recurringForm?: RecurringScheduleFormProps + recurringSchedule?: RecurringScheduleFormProps ): RRuleParams => { const presets = getPresets(startDate); + const parsedSchedule = parseSchedule(recurringSchedule); + const rRule: RRuleParams = { dtstart: startDate.toISOString(), tzid: timezone, }; - if (!recurringForm) + if (!parsedSchedule) return { ...rRule, // default to yearly and a count of 1 @@ -34,9 +37,9 @@ export const convertToRRule = ( count: 1, }; - let form = recurringForm; - if (recurringForm.frequency !== 'CUSTOM') { - form = { ...recurringForm, ...presets[recurringForm.frequency] }; + let form = parsedSchedule; + if (parsedSchedule.frequency !== 'CUSTOM') { + form = { ...parsedSchedule, ...presets[parsedSchedule.frequency] }; } const frequency = form.customFrequency ?? (form.frequency as Frequency); diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/parse_schedule.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/parse_schedule.ts new file mode 100644 index 0000000000000..6968db721d1fb --- /dev/null +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/parse_schedule.ts @@ -0,0 +1,45 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RecurringScheduleFormProps } from '../components/schema'; + +export const parseSchedule = ( + schedule: RecurringScheduleFormProps | undefined +): RecurringScheduleFormProps | undefined => { + if (!schedule) { + return schedule; + } + + const { frequency, customFrequency, interval, count } = schedule; + + // We must case them to unknown because form-lib is already turning them into strings + // despite what our types suggests + const parsedFrequency = parseInt(frequency as string, 10); + const parsedCustomFrequency = parseInt(customFrequency as unknown as string, 10); + const parsedInterval = parseInt(interval as unknown as string, 10); + const parsedCount = parseInt(count as unknown as string, 10); + + const shallowCopy = { ...schedule }; + + if (!isNaN(parsedFrequency)) { + shallowCopy.frequency = parsedFrequency; + } + + if (!isNaN(parsedCustomFrequency)) { + shallowCopy.customFrequency = parsedCustomFrequency; + } + + if (!isNaN(parsedInterval)) { + shallowCopy.interval = parsedInterval; + } + + if (!isNaN(parsedCount)) { + shallowCopy.count = parsedCount; + } + + return shallowCopy; +}; diff --git a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts index 5e3be96c04147..34054bbb736ac 100644 --- a/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts +++ b/x-pack/plugins/alerting/public/pages/maintenance_windows/helpers/recurring_summary.ts @@ -24,80 +24,76 @@ export const recurringSummary = ( ) => { if (!recurringSchedule) return ''; - if (recurringSchedule) { - let schedule = recurringSchedule; - if (recurringSchedule.frequency !== 'CUSTOM') { - schedule = { ...recurringSchedule, ...presets[recurringSchedule.frequency] }; - } + let schedule = recurringSchedule; + if (recurringSchedule.frequency !== 'CUSTOM') { + schedule = { ...recurringSchedule, ...presets[recurringSchedule.frequency] }; + } - const frequency = - schedule.customFrequency ?? (schedule.frequency as MaintenanceWindowFrequency); - const interval = schedule.interval || 1; - const frequencySummary = i18n.CREATE_FORM_FREQUENCY_SUMMARY(interval)[frequency]; + const frequency = schedule.customFrequency ?? (schedule.frequency as MaintenanceWindowFrequency); + const interval = schedule.interval || 1; + const frequencySummary = i18n.CREATE_FORM_FREQUENCY_SUMMARY(interval)[frequency]; - // daily and weekly - let weeklySummary = null; - let dailyWeekdaySummary = null; - let dailyWithWeekdays = false; - const byweekday = schedule.byweekday; - if (byweekday) { - const weekdays = Object.keys(byweekday) - .filter((k) => byweekday[k] === true) - .map((n) => ISO_WEEKDAYS_TO_RRULE[Number(n)]); - const formattedWeekdays = weekdays.map((weekday) => toWeekdayName(weekday)).join(', '); + // daily and weekly + let weeklySummary = null; + let dailyWeekdaySummary = null; + let dailyWithWeekdays = false; + const byweekday = schedule.byweekday; + if (byweekday) { + const weekdays = Object.keys(byweekday) + .filter((k) => byweekday[k] === true) + .map((n) => ISO_WEEKDAYS_TO_RRULE[Number(n)]); + const formattedWeekdays = weekdays.map((weekday) => toWeekdayName(weekday)).join(', '); - weeklySummary = i18n.CREATE_FORM_WEEKLY_SUMMARY(formattedWeekdays); - dailyWeekdaySummary = formattedWeekdays; + weeklySummary = i18n.CREATE_FORM_WEEKLY_SUMMARY(formattedWeekdays); + dailyWeekdaySummary = formattedWeekdays; - dailyWithWeekdays = frequency === Frequency.DAILY; - } + dailyWithWeekdays = frequency === Frequency.DAILY; + } - // monthly - let monthlySummary = null; - const bymonth = schedule.bymonth; - if (bymonth) { - if (bymonth === 'weekday') { - const nthWeekday = getNthByWeekday(startDate); - const nth = nthWeekday.startsWith('-1') ? 0 : Number(nthWeekday[1]); - monthlySummary = i18n.CREATE_FORM_WEEKDAY_SHORT(toWeekdayName(nthWeekday))[nth]; - monthlySummary = monthlySummary[0].toLocaleLowerCase() + monthlySummary.slice(1); - } else if (bymonth === 'day') { - monthlySummary = i18n.CREATE_FORM_MONTHLY_BY_DAY_SUMMARY(startDate.date()); - } + // monthly + let monthlySummary = null; + const bymonth = schedule.bymonth; + if (bymonth) { + if (bymonth === 'weekday') { + const nthWeekday = getNthByWeekday(startDate); + const nth = nthWeekday.startsWith('-1') ? 0 : Number(nthWeekday[1]); + monthlySummary = i18n.CREATE_FORM_WEEKDAY_SHORT(toWeekdayName(nthWeekday))[nth]; + monthlySummary = monthlySummary[0].toLocaleLowerCase() + monthlySummary.slice(1); + } else if (bymonth === 'day') { + monthlySummary = i18n.CREATE_FORM_MONTHLY_BY_DAY_SUMMARY(startDate.date()); } + } - // yearly - const yearlyByMonthSummary = i18n.CREATE_FORM_YEARLY_BY_MONTH_SUMMARY( - monthDayDate(moment().month(startDate.month()).date(startDate.date())) - ); + // yearly + const yearlyByMonthSummary = i18n.CREATE_FORM_YEARLY_BY_MONTH_SUMMARY( + monthDayDate(moment().month(startDate.month()).date(startDate.date())) + ); - const onSummary = dailyWithWeekdays - ? dailyWeekdaySummary - : frequency === Frequency.WEEKLY - ? weeklySummary - : frequency === Frequency.MONTHLY - ? monthlySummary - : frequency === Frequency.YEARLY - ? yearlyByMonthSummary - : null; + const onSummary = dailyWithWeekdays + ? dailyWeekdaySummary + : frequency === Frequency.WEEKLY + ? weeklySummary + : frequency === Frequency.MONTHLY + ? monthlySummary + : frequency === Frequency.YEARLY + ? yearlyByMonthSummary + : null; - const untilSummary = schedule.until - ? i18n.CREATE_FORM_UNTIL_DATE_SUMMARY(moment(schedule.until).format('LL')) - : schedule.count - ? i18n.CREATE_FORM_OCURRENCES_SUMMARY(schedule.count) - : null; + const untilSummary = schedule.until + ? i18n.CREATE_FORM_UNTIL_DATE_SUMMARY(moment(schedule.until).format('LL')) + : schedule.count + ? i18n.CREATE_FORM_OCURRENCES_SUMMARY(schedule.count) + : null; - const every = i18n - .CREATE_FORM_RECURRING_SUMMARY( - !dailyWithWeekdays ? frequencySummary : null, - onSummary, - untilSummary - ) - .trim(); + const every = i18n + .CREATE_FORM_RECURRING_SUMMARY( + !dailyWithWeekdays ? frequencySummary : null, + onSummary, + untilSummary + ) + .trim(); - return every; - } - return ''; + return every; }; export const toWeekdayName = (weekday: string) => diff --git a/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.ts b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.ts index 0c83d16dee024..1868abc1703af 100644 --- a/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.ts +++ b/x-pack/plugins/alerting/server/application/r_rule/schemas/r_rule_request_schema.ts @@ -16,16 +16,22 @@ export const rRuleRequestSchema = schema.object({ interval: schema.maybe( schema.number({ validate: (interval: number) => { - if (interval < 1) return 'rRule interval must be > 0'; + if (!Number.isInteger(interval)) { + return 'rRule interval must be an integer greater than 0'; + } }, + min: 1, }) ), until: schema.maybe(schema.string({ validate: validateEndDate })), count: schema.maybe( schema.number({ validate: (count: number) => { - if (count < 1) return 'rRule count must be > 0'; + if (!Number.isInteger(count)) { + return 'rRule count must be an integer greater than 0'; + } }, + min: 1, }) ), byweekday: schema.maybe( diff --git a/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts b/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts index 4f714ef8d9fbe..a73854c7f4635 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rrule_schema.ts @@ -13,25 +13,27 @@ export const rRuleSchema = schema.object({ dtstart: schema.string({ validate: validateSnoozeStartDate }), tzid: schema.string(), freq: schema.maybe( - schema.number({ - validate: (freq: number) => { - if (freq < 0 || freq > 3) return 'rRule freq must be 0, 1, 2, or 3'; - }, - }) + schema.oneOf([schema.literal(0), schema.literal(1), schema.literal(2), schema.literal(3)]) ), interval: schema.maybe( schema.number({ validate: (interval: number) => { - if (interval < 1) return 'rRule interval must be > 0'; + if (!Number.isInteger(interval)) { + return 'rRule interval must be an integer greater than 0'; + } }, + min: 1, }) ), until: schema.maybe(schema.string({ validate: validateSnoozeEndDate })), count: schema.maybe( schema.number({ validate: (count: number) => { - if (count < 1) return 'rRule count must be > 0'; + if (!Number.isInteger(count)) { + return 'rRule count must be an integer greater than 0'; + } }, + min: 1, }) ), byweekday: schema.maybe( diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/index.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/index.ts index c0488c21adb21..f0b58a32e2c3a 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/index.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/index.ts @@ -10,5 +10,7 @@ import { FtrProviderContext } from '../../../ftr_provider_context'; export default ({ loadTestFile }: FtrProviderContext) => { describe('Maintenance Windows', function () { loadTestFile(require.resolve('./maintenance_windows_table')); + loadTestFile(require.resolve('./maintenance_window_create_form')); + loadTestFile(require.resolve('./maintenance_window_update_form')); }); }; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_create_form.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_create_form.ts new file mode 100644 index 0000000000000..78e595d053585 --- /dev/null +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_create_form.ts @@ -0,0 +1,96 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { ObjectRemover } from '../../../lib/object_remover'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const testSubjects = getService('testSubjects'); + const supertest = getService('supertest'); + const pageObjects = getPageObjects(['common', 'header']); + const retry = getService('retry'); + const toasts = getService('toasts'); + const objectRemover = new ObjectRemover(supertest); + + describe('Maintenance window create form', () => { + beforeEach(async () => { + await pageObjects.common.navigateToApp('maintenanceWindows'); + }); + + after(async () => { + const { body } = await supertest.get('/internal/alerting/rules/maintenance_window/_find'); + + body?.data?.forEach((mw: { id: string }) => { + objectRemover.add(mw.id, 'rules/maintenance_window', 'alerting', true); + }); + + await objectRemover.removeAll(); + }); + + it('should create a maintenance window', async () => { + await pageObjects.header.waitUntilLoadingHasFinished(); + + await testSubjects.click('mw-create-button'); + + await retry.try(async () => { + await testSubjects.existOrFail('createMaintenanceWindowForm'); + }); + + const nameInput = await testSubjects.find('createMaintenanceWindowFormNameInput'); + + await nameInput.click(); + await nameInput.type('Test Maintenance Window'); + + // Turn on repeat + await (await testSubjects.find('createMaintenanceWindowRepeatSwitch')).click(); + + await retry.try(async () => { + await testSubjects.existOrFail('recurringScheduleRepeatSelect'); + }); + + // Open the repeat dropdown select + await (await testSubjects.find('recurringScheduleRepeatSelect')).click(); + // Select custom + await (await testSubjects.find('recurringScheduleOptionCustom')).click(); + + await retry.try(async () => { + await testSubjects.existOrFail('customRecurringScheduleFrequencySelect'); + }); + + // Change interval to 2 + const intervalInput = await testSubjects.find('customRecurringScheduleIntervalInput'); + + await intervalInput.click(); + await intervalInput.type('2'); + + // Open "every" frequency dropdown + await (await testSubjects.find('customRecurringScheduleFrequencySelect')).click(); + // Select daily + await (await testSubjects.find('customFrequencyDaily')).click(); + // Click on "End -> after {X}" + await (await testSubjects.find('recurrenceEndOptionAfterX')).click(); + + await retry.try(async () => { + await testSubjects.existOrFail('count-field'); + }); + + const afterXOccurenceInput = await testSubjects.find('recurringScheduleAfterXOccurenceInput'); + + await afterXOccurenceInput.click(); + await afterXOccurenceInput.clearValue(); + await afterXOccurenceInput.type('5'); + + await (await testSubjects.find('create-submit')).click(); + + await retry.try(async () => { + const toastTitle = await toasts.getTitleAndDismiss(); + expect(toastTitle).to.eql(`Created maintenance window 'Test Maintenance Window'`); + }); + }); + }); +}; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_update_form.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_update_form.ts new file mode 100644 index 0000000000000..f5daca1889926 --- /dev/null +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_window_update_form.ts @@ -0,0 +1,79 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { ObjectRemover } from '../../../lib/object_remover'; +import { createMaintenanceWindow } from './utils'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const testSubjects = getService('testSubjects'); + const supertest = getService('supertest'); + const pageObjects = getPageObjects(['common', 'maintenanceWindows', 'header']); + const retry = getService('retry'); + const toasts = getService('toasts'); + const objectRemover = new ObjectRemover(supertest); + const browser = getService('browser'); + + describe('Maintenance window update form', () => { + beforeEach(async () => { + await pageObjects.common.navigateToApp('maintenanceWindows'); + }); + + after(async () => { + await objectRemover.removeAll(); + }); + + it('should update a maintenance window', async () => { + const createdMaintenanceWindow = await createMaintenanceWindow({ + name: 'Test Maintenance Window', + getService, + overwrite: { + r_rule: { + dtstart: new Date().toISOString(), + tzid: 'UTC', + freq: 3, + interval: 12, + count: 5, + }, + category_ids: ['management', 'observability', 'securitySolution'], + }, + }); + + objectRemover.add(createdMaintenanceWindow.id, 'rules/maintenance_window', 'alerting', true); + + await browser.refresh(); + + await pageObjects.maintenanceWindows.searchMaintenanceWindows('Test Maintenance Window'); + + await testSubjects.click('table-actions-popover'); + await testSubjects.click('table-actions-edit'); + + await retry.try(async () => { + await testSubjects.existOrFail('createMaintenanceWindowForm'); + }); + + const nameInput = await testSubjects.find('createMaintenanceWindowFormNameInput'); + + await nameInput.click(); + await nameInput.clearValue(); + await nameInput.type('Test Maintenance Window updated'); + + // Open the repeat dropdown select + await (await testSubjects.find('recurringScheduleRepeatSelect')).click(); + // Select daily + await (await testSubjects.find('recurringScheduleOptionDaily')).click(); + + await (await testSubjects.find('create-submit')).click(); + + await retry.try(async () => { + const toastTitle = await toasts.getTitleAndDismiss(); + expect(toastTitle).to.eql(`Updated maintenance window 'Test Maintenance Window updated'`); + }); + }); + }); +}; diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_windows_table.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_windows_table.ts index 0b228be252ca3..5618a1a77cff6 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_windows_table.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/maintenance_windows_table.ts @@ -9,22 +9,18 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { ObjectRemover } from '../../../lib/object_remover'; import { generateUniqueKey } from '../../../lib/get_test_data'; -import { createMaintenanceWindow, createObjectRemover } from './utils'; +import { createMaintenanceWindow } from './utils'; export default ({ getPageObjects, getService }: FtrProviderContext) => { const testSubjects = getService('testSubjects'); + const supertest = getService('supertest'); const pageObjects = getPageObjects(['common', 'maintenanceWindows', 'header']); const retry = getService('retry'); const toasts = getService('toasts'); - - let objectRemover: ObjectRemover; + const objectRemover = new ObjectRemover(supertest); const browser = getService('browser'); describe('Maintenance windows table', function () { - before(async () => { - objectRemover = await createObjectRemover({ getService }); - }); - beforeEach(async () => { await pageObjects.common.navigateToApp('maintenanceWindows'); }); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/utils.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/utils.ts index f2bf6334d6b29..da1aca050e43b 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/utils.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/maintenance_windows/utils.ts @@ -5,30 +5,20 @@ * 2.0. */ -import { ObjectRemover } from '../../../lib/object_remover'; import { FtrProviderContext } from '../../../ftr_provider_context'; -export const createObjectRemover = async ({ - getService, -}: { - getService: FtrProviderContext['getService']; -}) => { - const supertest = getService('supertest'); - const objectRemover = new ObjectRemover(supertest); - - return objectRemover; -}; - export const createMaintenanceWindow = async ({ name, startDate, notRecurring, getService, + overwrite, }: { name: string; startDate?: Date; notRecurring?: boolean; getService: FtrProviderContext['getService']; + overwrite?: Record; }) => { const supertest = getService('supertest'); const dtstart = startDate ? startDate : new Date(); @@ -40,6 +30,7 @@ export const createMaintenanceWindow = async ({ tzid: 'UTC', ...(notRecurring ? { freq: 1, count: 1 } : { freq: 2 }), }, + ...overwrite, }; const { body } = await supertest From ceb1b1a4bf253ac94f9ba0ba649e9a4908a76c51 Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Mon, 16 Sep 2024 19:58:55 -0400 Subject: [PATCH 053/139] [Security Solution] Integration tests for `query` diff algorithms (#192655) ## Summary Completes https://github.com/elastic/kibana/issues/187658 Switches `kql_query`, `eql_query`, and `esql_query` fields to use the implemented diff algorithms assigned to them in https://github.com/elastic/kibana/pull/190179 Adds integration tests in accordance to https://github.com/elastic/kibana/pull/192529 for the `upgrade/_review` API endpoint for the `query` field diff algorithms. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../calculation/calculate_rule_fields_diff.ts | 19 +- .../trial_license_complete_tier/index.ts | 3 + ..._review_prebuilt_rules.eql_query_fields.ts | 465 +++++++ ...review_prebuilt_rules.esql_query_fields.ts | 434 +++++++ ..._review_prebuilt_rules.kql_query_fields.ts | 1128 +++++++++++++++++ 5 files changed, 2041 insertions(+), 8 deletions(-) create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts create mode 100644 x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/diff/calculation/calculate_rule_fields_diff.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/diff/calculation/calculate_rule_fields_diff.ts index 4f8126d315072..80536451b6f3c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/diff/calculation/calculate_rule_fields_diff.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/logic/diff/calculation/calculate_rule_fields_diff.ts @@ -44,6 +44,9 @@ import { scalarArrayDiffAlgorithm, simpleDiffAlgorithm, singleLineStringDiffAlgorithm, + kqlQueryDiffAlgorithm, + eqlQueryDiffAlgorithm, + esqlQueryDiffAlgorithm, } from './algorithms'; const BASE_TYPE_ERROR = `Base version can't be of different rule type`; @@ -210,7 +213,7 @@ const calculateCustomQueryFieldsDiff = ( const customQueryFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - kql_query: simpleDiffAlgorithm, + kql_query: kqlQueryDiffAlgorithm, data_source: dataSourceDiffAlgorithm, alert_suppression: simpleDiffAlgorithm, }; @@ -223,7 +226,7 @@ const calculateSavedQueryFieldsDiff = ( const savedQueryFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - kql_query: simpleDiffAlgorithm, + kql_query: kqlQueryDiffAlgorithm, data_source: dataSourceDiffAlgorithm, alert_suppression: simpleDiffAlgorithm, }; @@ -236,7 +239,7 @@ const calculateEqlFieldsDiff = ( const eqlFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - eql_query: simpleDiffAlgorithm, + eql_query: eqlQueryDiffAlgorithm, data_source: dataSourceDiffAlgorithm, event_category_override: singleLineStringDiffAlgorithm, timestamp_field: singleLineStringDiffAlgorithm, @@ -252,7 +255,7 @@ const calculateEsqlFieldsDiff = ( const esqlFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - esql_query: simpleDiffAlgorithm, + esql_query: esqlQueryDiffAlgorithm, alert_suppression: simpleDiffAlgorithm, }; @@ -264,9 +267,9 @@ const calculateThreatMatchFieldsDiff = ( const threatMatchFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - kql_query: simpleDiffAlgorithm, + kql_query: kqlQueryDiffAlgorithm, data_source: dataSourceDiffAlgorithm, - threat_query: simpleDiffAlgorithm, + threat_query: kqlQueryDiffAlgorithm, threat_index: scalarArrayDiffAlgorithm, threat_mapping: simpleDiffAlgorithm, threat_indicator_path: singleLineStringDiffAlgorithm, @@ -282,7 +285,7 @@ const calculateThresholdFieldsDiff = ( const thresholdFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - kql_query: simpleDiffAlgorithm, + kql_query: kqlQueryDiffAlgorithm, data_source: dataSourceDiffAlgorithm, threshold: simpleDiffAlgorithm, alert_suppression: simpleDiffAlgorithm, @@ -310,7 +313,7 @@ const calculateNewTermsFieldsDiff = ( const newTermsFieldsDiffAlgorithms: FieldsDiffAlgorithmsFor = { type: simpleDiffAlgorithm, - kql_query: simpleDiffAlgorithm, + kql_query: kqlQueryDiffAlgorithm, data_source: dataSourceDiffAlgorithm, new_terms_fields: scalarArrayDiffAlgorithm, history_window_start: singleLineStringDiffAlgorithm, diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts index 4c8efcfa751e0..819b253dc7a66 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/index.ts @@ -22,6 +22,9 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.scalar_array_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.multi_line_string_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.data_source_fields')); + loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.kql_query_fields')); + loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.eql_query_fields')); + loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.esql_query_fields')); loadTestFile(require.resolve('./upgrade_review_prebuilt_rules.stats')); }); }; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts new file mode 100644 index 0000000000000..f500f8691485b --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.eql_query_fields.ts @@ -0,0 +1,465 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import expect from 'expect'; +import { + AllFieldsDiff, + RuleUpdateProps, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + installPrebuiltRules, + createPrebuiltRuleAssetSavedObjects, + reviewPrebuiltRulesToUpgrade, + createHistoricalPrebuiltRuleAssetSavedObjects, + updateRule, +} from '../../../../utils'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe(`eql_query fields`, () => { + const getRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 1, + type: 'eql', + query: 'query where true', + language: 'eql', + filters: [], + }), + ]; + + describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'query where true', + language: 'eql', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but eql_query field is NOT returned + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Customize an eql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'eql', + query: 'query where false', + language: 'eql', + filters: [], + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related eql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'query where true', + language: 'eql', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that eql_query diff field is returned but field does not have an update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toEqual({ + base_version: { + query: 'query where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + target_version: { + query: 'query where true', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update but does not have a custom value - scenario AAB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'query where false', + language: 'eql', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toEqual({ + base_version: { + query: 'query where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'query where true', + language: 'eql', + filters: [], + }, + target_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Customize an eql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'eql', + query: 'query where false', + language: 'eql', + filters: [], + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'query where false', + language: 'eql', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains eql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toEqual({ + base_version: { + query: 'query where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + target_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are different - scenario ABC', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Customize an eql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'eql', + query: 'query where true', + language: 'eql', + filters: [{ field: 'query' }], + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'query where false', + language: 'eql', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and eql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toEqual({ + base_version: { + query: 'query where true', + language: 'eql', + filters: [], + }, + current_version: { + query: 'query where true', + language: 'eql', + filters: [{ field: 'query' }], + }, + target_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'query where true', + language: 'eql', + filters: [{ field: 'query' }], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when rule base version does not exist', () => { + describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Add a v2 rule asset to make the upgrade possible, but keep eql_query field unchanged + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'query where true', + language: 'eql', + filters: [], + }), + ]; + await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // but does NOT contain eql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // `version` is considered conflict + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are different - scenario -AB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Customize an eql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'eql', + query: 'query where false', + language: 'eql', + filters: [], + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update an eql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'eql', + query: 'new query where true', + language: 'eql', + filters: [], + }), + ]; + await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and eql_query field update does not have a conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.eql_query).toEqual({ + current_version: { + query: 'query where false', + language: 'eql', + filters: [], + }, + target_version: { + query: 'new query where true', + language: 'eql', + filters: [], + }, + merged_version: { + query: 'new query where true', + language: 'eql', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // version + query + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // version + query + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts new file mode 100644 index 0000000000000..f77f59b16a3e1 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.esql_query_fields.ts @@ -0,0 +1,434 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import expect from 'expect'; +import { + AllFieldsDiff, + RuleUpdateProps, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { getPrebuiltRuleMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + installPrebuiltRules, + createPrebuiltRuleAssetSavedObjects, + reviewPrebuiltRulesToUpgrade, + createHistoricalPrebuiltRuleAssetSavedObjects, + updateRule, +} from '../../../../utils'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe(`esql_query fields`, () => { + const getRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 1, + type: 'esql', + query: 'FROM query WHERE true', + language: 'esql', + }), + ]; + + describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM query WHERE true', + language: 'esql', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but esql_query field is NOT returned + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Customize an esql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'esql', + query: 'FROM query WHERE false', + language: 'esql', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related esql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM query WHERE true', + language: 'esql', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that esql_query diff field is returned but field does not have an update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toEqual({ + base_version: { + query: 'FROM query WHERE true', + language: 'esql', + }, + current_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + target_version: { + query: 'FROM query WHERE true', + language: 'esql', + }, + merged_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update but does not have a custom value - scenario AAB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM query WHERE false', + language: 'esql', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toEqual({ + base_version: { + query: 'FROM query WHERE true', + language: 'esql', + }, + current_version: { + query: 'FROM query WHERE true', + language: 'esql', + }, + target_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + merged_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Customize an esql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'esql', + query: 'FROM query WHERE false', + language: 'esql', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM query WHERE false', + language: 'esql', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains esql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toEqual({ + base_version: { + query: 'FROM query WHERE true', + language: 'esql', + }, + current_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + target_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + merged_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are different - scenario ABC', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Customize an esql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'esql', + query: 'FROM query WHERE false', + language: 'esql', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM new query WHERE true', + language: 'esql', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and esql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toEqual({ + base_version: { + query: 'FROM query WHERE true', + language: 'esql', + }, + current_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + target_version: { + query: 'FROM new query WHERE true', + language: 'esql', + }, + merged_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when rule base version does not exist', () => { + describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Add a v2 rule asset to make the upgrade possible, but keep esql_query field unchanged + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM query WHERE true', + language: 'esql', + }), + ]; + await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // but does NOT contain esql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // version is considered conflict + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are different - scenario -AB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createPrebuiltRuleAssetSavedObjects(es, getRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Customize an esql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'esql', + query: 'FROM query WHERE false', + language: 'esql', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update an esql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'esql', + query: 'FROM new query WHERE true', + language: 'esql', + }), + ]; + await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and esql_query field update does not have a conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.esql_query).toEqual({ + current_version: { + query: 'FROM query WHERE false', + language: 'esql', + }, + target_version: { + query: 'FROM new query WHERE true', + language: 'esql', + }, + merged_version: { + query: 'FROM new query WHERE true', + language: 'esql', + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // version + query + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts new file mode 100644 index 0000000000000..3de835ed42772 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/rules_management/prebuilt_rules/management/trial_license_complete_tier/upgrade_review_prebuilt_rules.kql_query_fields.ts @@ -0,0 +1,1128 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import expect from 'expect'; +import { + AllFieldsDiff, + KqlQueryType, + RuleUpdateProps, + ThreeWayDiffConflict, + ThreeWayDiffOutcome, + ThreeWayMergeOutcome, +} from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { + getPrebuiltRuleMock, + getPrebuiltThreatMatchRuleMock, +} from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; +import { PrebuiltRuleAsset } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules'; +import { FtrProviderContext } from '../../../../../../ftr_provider_context'; +import { + deleteAllTimelines, + deleteAllPrebuiltRuleAssets, + createRuleAssetSavedObject, + installPrebuiltRules, + createPrebuiltRuleAssetSavedObjects, + reviewPrebuiltRulesToUpgrade, + createHistoricalPrebuiltRuleAssetSavedObjects, + updateRule, + patchRule, +} from '../../../../utils'; +import { deleteAllRules } from '../../../../../../../common/utils/security_solution'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + const log = getService('log'); + + describe('@ess @serverless @skipInServerlessMKI review prebuilt rules updates from package with mock rule assets', () => { + beforeEach(async () => { + await deleteAllRules(supertest, log); + await deleteAllTimelines(es, log); + await deleteAllPrebuiltRuleAssets(es, log); + }); + + describe(`kql_query fields`, () => { + const getQueryRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 1, + type: 'query', + query: 'query string = true', + language: 'kuery', + filters: [], + }), + ]; + + const getSavedQueryRuleAssetSavedObjects = () => [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 1, + type: 'saved_query', + saved_id: 'saved-query-id', + }), + ]; + + describe("when rule field doesn't have an update and has no custom value - scenario AAA", () => { + describe('when all versions are inline query types', () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = true', + language: 'kuery', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but kql_query field is NOT returned + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when all versions are saved query types', () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getSavedQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'saved_query', + saved_id: 'saved-query-id', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that there is 1 rule eligible for update but kql_query field is NOT returned + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + + describe("when rule field doesn't have an update but has a custom value - scenario ABA", () => { + describe('when current version is inline query type', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getSavedQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'query', + query: 'query string = true', + language: 'kuery', + filters: [], + saved_id: undefined, + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'saved_query', + saved_id: 'saved-query-id', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that kql_query diff field is returned but field does not have an update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when current version is saved query type', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'saved_query', + query: undefined, + language: undefined, + filters: undefined, + saved_id: 'saved-query-id', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, do NOT update the related kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = true', + language: 'kuery', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that kql_query diff field is returned but field does not have an update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueNoUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + + describe('when rule field has an update but does not have a custom value - scenario AAB', () => { + describe('when all versions are inline query type', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = false', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when all versions are saved query type', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getSavedQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'saved_query', + saved_id: 'new-saved-query-id', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + current_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + target_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + merged_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + diff_outcome: ThreeWayDiffOutcome.StockValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.NONE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + + describe('when rule field has an update and a custom value that are the same - scenario ABB', () => { + describe('when all versions are inline query type', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await patchRule(supertest, log, { + rule_id: 'rule-1', + query: 'query string = false', + }); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = false', + language: 'kuery', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains kql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when all versions are saved query types', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getSavedQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'saved_query', + saved_id: 'new-saved-query-id', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'saved_query', + saved_id: 'new-saved-query-id', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update and contains kql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + current_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + target_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + merged_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueSameUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NONE, + has_update: false, + has_base_version: true, + }); + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(0); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(0); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + + describe('when rule field has an update and a custom value that are different - scenario ABC', () => { + describe('when current version is different type than base and target', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'saved_query', + query: undefined, + language: undefined, + filters: undefined, + saved_id: 'saved-query-id', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = false', + language: 'kuery', + filters: [], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and kql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when all versions are inline query type', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query on the installed rule + await patchRule(supertest, log, { + rule_id: 'rule-1', + query: 'query string = false', + }); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = true', + language: 'kuery', + filters: [{ field: 'query' }], + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and kql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [{ field: 'query' }], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when all versions are saved query type', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects( + es, + getSavedQueryRuleAssetSavedObjects() + ); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'saved_query', + saved_id: 'new-saved-query-id', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'saved_query', + saved_id: 'even-newer-saved-query-id', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and kql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'saved-query-id', + }, + current_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + target_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'even-newer-saved-query-id', + }, + merged_version: { + type: KqlQueryType.saved_query, + saved_query_id: 'new-saved-query-id', + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when rule type is threat match', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + ...getPrebuiltThreatMatchRuleMock(), + threat_filters: [], + } as PrebuiltRuleAsset), + ]); + await installPrebuiltRules(es, supertest); + + // Customize a threat_query on the installed rule + await updateRule(supertest, { + ...getPrebuiltThreatMatchRuleMock(), + rule_id: 'rule-1', + threat_query: '*', + threat_filters: [], + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a threat_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + ...getPrebuiltThreatMatchRuleMock(), + threat_query: `*:'new query'`, + threat_filters: [], + version: 2, + } as PrebuiltRuleAsset), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and threat_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.threat_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: '*:*', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: '*', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: `*:'new query'`, + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: '*', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when rule type is threshold', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 1, + type: 'threshold', + query: 'query string = true', + threshold: { + field: 'some.field', + value: 4, + }, + }), + ]); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'threshold', + query: 'query string = false', + threshold: { + field: 'some.field', + value: 4, + }, + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'threshold', + query: 'new query string = true', + threshold: { + field: 'some.field', + value: 4, + }, + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and kql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'new query string = true', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + + describe('when rule type is new_terms', () => { + it('should show a non-solvable conflict in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createHistoricalPrebuiltRuleAssetSavedObjects(es, [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 1, + type: 'new_terms', + query: 'query string = true', + new_terms_fields: ['user.name'], + history_window_start: 'now-7d', + }), + ]); + await installPrebuiltRules(es, supertest); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'new_terms', + query: 'query string = false', + new_terms_fields: ['user.name'], + history_window_start: 'now-7d', + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'new_terms', + query: 'new query string = true', + new_terms_fields: ['user.name'], + history_window_start: 'now-7d', + }), + ]; + await createHistoricalPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and kql_query field update has conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + base_version: { + type: KqlQueryType.inline_query, + query: 'query string = true', + language: 'kuery', + filters: [], + }, + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'new query string = true', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.CustomizedValueCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Current, + conflict: ThreeWayDiffConflict.NON_SOLVABLE, + has_update: true, + has_base_version: true, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(1); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(1); + }); + }); + }); + + describe('when rule base version does not exist', () => { + describe('when rule field has an update and a custom value that are the same - scenario -AA', () => { + it('should not show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createPrebuiltRuleAssetSavedObjects(es, getQueryRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Add a v2 rule asset to make the upgrade possible, but keep kql_query field unchanged + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'query string = true', + language: 'kuery', + filters: [], + }), + ]; + await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // but does NOT contain kql_query field + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toBeUndefined(); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(1); // `version` is considered an updated field + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(1); // `version` is considered conflict + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + + describe('when rule field has an update and a custom value that are different - scenario -AB', () => { + it('should show in the upgrade/_review API response', async () => { + // Install base prebuilt detection rule + await createPrebuiltRuleAssetSavedObjects(es, getQueryRuleAssetSavedObjects()); + await installPrebuiltRules(es, supertest); + + // Clear previous rule assets + await deleteAllPrebuiltRuleAssets(es, log); + + // Customize a kql_query field on the installed rule + await updateRule(supertest, { + ...getPrebuiltRuleMock(), + rule_id: 'rule-1', + type: 'query', + query: 'query string = false', + language: 'kuery', + filters: [], + } as RuleUpdateProps); + + // Add a v2 rule asset to make the upgrade possible, update a kql_query field, and create the new rule assets + const updatedRuleAssetSavedObjects = [ + createRuleAssetSavedObject({ + rule_id: 'rule-1', + version: 2, + type: 'query', + query: 'new query string = true', + language: 'kuery', + filters: [], + }), + ]; + await createPrebuiltRuleAssetSavedObjects(es, updatedRuleAssetSavedObjects); + + // Call the upgrade review prebuilt rules endpoint and check that one rule is eligible for update + // and kql_query field update does not have a conflict + const reviewResponse = await reviewPrebuiltRulesToUpgrade(supertest); + const fieldDiffObject = reviewResponse.rules[0].diff.fields as AllFieldsDiff; + expect(fieldDiffObject.kql_query).toEqual({ + current_version: { + type: KqlQueryType.inline_query, + query: 'query string = false', + language: 'kuery', + filters: [], + }, + target_version: { + type: KqlQueryType.inline_query, + query: 'new query string = true', + language: 'kuery', + filters: [], + }, + merged_version: { + type: KqlQueryType.inline_query, + query: 'new query string = true', + language: 'kuery', + filters: [], + }, + diff_outcome: ThreeWayDiffOutcome.MissingBaseCanUpdate, + merge_outcome: ThreeWayMergeOutcome.Target, + conflict: ThreeWayDiffConflict.SOLVABLE, + has_update: true, + has_base_version: false, + }); + + expect(reviewResponse.rules[0].diff.num_fields_with_updates).toBe(2); + expect(reviewResponse.rules[0].diff.num_fields_with_conflicts).toBe(2); // version + query + expect(reviewResponse.rules[0].diff.num_fields_with_non_solvable_conflicts).toBe(0); + + expect(reviewResponse.stats.num_rules_to_upgrade_total).toBe(1); + expect(reviewResponse.stats.num_rules_with_conflicts).toBe(1); + expect(reviewResponse.stats.num_rules_with_non_solvable_conflicts).toBe(0); + }); + }); + }); + }); + }); +}; From c4b9110699009d7dd99f09a6e11ae5373b48a1b0 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:20:12 +1000 Subject: [PATCH 054/139] [api-docs] 2024-09-17 Daily api_docs build (#193112) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/833 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- .../ai_assistant_management_selection.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.mdx | 2 +- api_docs/apm_data_access.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.mdx | 2 +- api_docs/data_quality.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/dataset_quality.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 4 +- api_docs/deprecations_by_team.mdx | 13 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/discover_shared.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/elastic_assistant.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/entities_data_access.mdx | 2 +- api_docs/entity_manager.devdocs.json | 40 ++--- api_docs/entity_manager.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/esql.mdx | 2 +- api_docs/esql_data_grid.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_annotation_listing.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/fields_metadata.mdx | 2 +- api_docs/file_upload.mdx | 4 +- api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.devdocs.json | 74 +++++++- api_docs/index_management.mdx | 4 +- api_docs/inference.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/ingest_pipelines.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/integration_assistant.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/inventory.mdx | 2 +- api_docs/investigate.mdx | 2 +- api_docs/investigate_app.devdocs.json | 44 +++-- api_docs/investigate_app.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_actions_types.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_log_pattern_analysis.mdx | 2 +- api_docs/kbn_aiops_log_rate_analysis.mdx | 2 +- .../kbn_alerting_api_integration_helpers.mdx | 2 +- api_docs/kbn_alerting_comparators.mdx | 2 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerting_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_grouping.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_collection_utils.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_data_view.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_types.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_avc_banner.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_bfetch_error.mdx | 2 +- api_docs/kbn_calculate_auto.mdx | 2 +- .../kbn_calculate_width_from_char_count.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cbor.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_cloud_security_posture.mdx | 2 +- .../kbn_cloud_security_posture_common.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mock.mdx | 2 +- api_docs/kbn_code_owners.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...ent_management_content_insights_public.mdx | 2 +- ...ent_management_content_insights_server.mdx | 2 +- ...bn_content_management_favorites_public.mdx | 2 +- ...bn_content_management_favorites_server.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...tent_management_table_list_view_common.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- .../kbn_content_management_user_profiles.mdx | 2 +- api_docs/kbn_content_management_utils.mdx | 2 +- .../kbn_core_analytics_browser.devdocs.json | 8 + api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- .../kbn_core_analytics_server.devdocs.json | 8 + api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 32 ++++ api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- .../kbn_core_plugins_contracts_browser.mdx | 2 +- .../kbn_core_plugins_contracts_server.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_security_browser.mdx | 2 +- .../kbn_core_security_browser_internal.mdx | 2 +- api_docs/kbn_core_security_browser_mocks.mdx | 2 +- api_docs/kbn_core_security_common.mdx | 2 +- api_docs/kbn_core_security_server.mdx | 2 +- .../kbn_core_security_server_internal.mdx | 2 +- api_docs/kbn_core_security_server_mocks.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- .../kbn_core_test_helpers_model_versions.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_profile_browser.mdx | 2 +- ...kbn_core_user_profile_browser_internal.mdx | 2 +- .../kbn_core_user_profile_browser_mocks.mdx | 2 +- api_docs/kbn_core_user_profile_common.mdx | 2 +- api_docs/kbn_core_user_profile_server.mdx | 2 +- .../kbn_core_user_profile_server_internal.mdx | 2 +- .../kbn_core_user_profile_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_custom_icons.mdx | 2 +- api_docs/kbn_custom_integrations.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_forge.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_data_stream_adapter.mdx | 2 +- api_docs/kbn_data_view_utils.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_fleet.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_deeplinks_security.mdx | 2 +- api_docs/kbn_deeplinks_shared.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_discover_utils.mdx | 2 +- api_docs/kbn_doc_links.devdocs.json | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_agent_utils.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_elastic_assistant_common.mdx | 2 +- api_docs/kbn_entities_schema.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_esql_ast.mdx | 2 +- api_docs/kbn_esql_utils.mdx | 2 +- ..._esql_validation_autocomplete.devdocs.json | 8 +- api_docs/kbn_esql_validation_autocomplete.mdx | 4 +- api_docs/kbn_event_annotation_common.mdx | 2 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.devdocs.json | 22 +-- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_field_utils.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- api_docs/kbn_formatters.mdx | 2 +- ...tr_common_functional_services.devdocs.json | 71 +++++++- .../kbn_ftr_common_functional_services.mdx | 4 +- .../kbn_ftr_common_functional_ui_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_grid_layout.mdx | 2 +- api_docs/kbn_grouping.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- .../kbn_index_management_shared_types.mdx | 2 +- api_docs/kbn_inference_integration_flyout.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- .../kbn_investigation_shared.devdocs.json | 169 ++++++++++++++---- api_docs/kbn_investigation_shared.mdx | 4 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_ipynb.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_json_schemas.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_lens_embeddable_utils.mdx | 2 +- api_docs/kbn_lens_formula_docs.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_content_badge.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- .../kbn_management_settings_application.mdx | 2 +- ...ent_settings_components_field_category.mdx | 2 +- ...gement_settings_components_field_input.mdx | 2 +- ...nagement_settings_components_field_row.mdx | 2 +- ...bn_management_settings_components_form.mdx | 2 +- ...n_management_settings_field_definition.mdx | 2 +- .../kbn_management_settings_ids.devdocs.json | 15 ++ api_docs/kbn_management_settings_ids.mdx | 4 +- ...n_management_settings_section_registry.mdx | 2 +- api_docs/kbn_management_settings_types.mdx | 2 +- .../kbn_management_settings_utilities.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 4 +- api_docs/kbn_maps_vector_tile_utils.mdx | 4 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- api_docs/kbn_ml_cancellable_search.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- api_docs/kbn_ml_chi2test.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_in_memory_table.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_time_buckets.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_ui_actions.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_mock_idp_utils.mdx | 2 +- api_docs/kbn_monaco.devdocs.json | 4 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_object_versioning_utils.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- .../kbn_observability_alerting_rule_utils.mdx | 2 +- .../kbn_observability_alerting_test_data.mdx | 2 +- ...ility_get_padded_alert_time_range_util.mdx | 2 +- api_docs/kbn_openapi_bundler.mdx | 2 +- api_docs/kbn_openapi_generator.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- api_docs/kbn_panel_loader.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_check.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_presentation_containers.mdx | 2 +- api_docs/kbn_presentation_publishing.mdx | 2 +- api_docs/kbn_profiling_utils.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_hooks.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.mdx | 2 +- api_docs/kbn_recently_accessed.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_reporting_csv_share_panel.mdx | 2 +- api_docs/kbn_reporting_export_types_csv.mdx | 2 +- .../kbn_reporting_export_types_csv_common.mdx | 2 +- api_docs/kbn_reporting_export_types_pdf.mdx | 2 +- .../kbn_reporting_export_types_pdf_common.mdx | 2 +- api_docs/kbn_reporting_export_types_png.mdx | 2 +- .../kbn_reporting_export_types_png_common.mdx | 2 +- api_docs/kbn_reporting_mocks_server.mdx | 2 +- api_docs/kbn_reporting_public.mdx | 2 +- api_docs/kbn_reporting_server.mdx | 2 +- api_docs/kbn_resizable_layout.mdx | 2 +- .../kbn_response_ops_feature_flag_service.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rollup.mdx | 2 +- api_docs/kbn_router_to_openapispec.mdx | 2 +- api_docs/kbn_router_utils.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_screenshotting_server.mdx | 2 +- api_docs/kbn_search_api_panels.mdx | 2 +- api_docs/kbn_search_connectors.mdx | 2 +- api_docs/kbn_search_errors.mdx | 2 +- api_docs/kbn_search_index_documents.mdx | 2 +- api_docs/kbn_search_response_warnings.mdx | 2 +- api_docs/kbn_search_types.mdx | 2 +- api_docs/kbn_security_api_key_management.mdx | 2 +- api_docs/kbn_security_authorization_core.mdx | 2 +- api_docs/kbn_security_form_components.mdx | 2 +- api_docs/kbn_security_hardening.mdx | 2 +- api_docs/kbn_security_plugin_types_common.mdx | 2 +- api_docs/kbn_security_plugin_types_public.mdx | 2 +- ..._security_plugin_types_server.devdocs.json | 10 +- api_docs/kbn_security_plugin_types_server.mdx | 2 +- .../kbn_security_role_management_model.mdx | 2 +- api_docs/kbn_security_solution_common.mdx | 2 +- ...kbn_security_solution_distribution_bar.mdx | 2 +- api_docs/kbn_security_solution_features.mdx | 2 +- api_docs/kbn_security_solution_navigation.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- api_docs/kbn_security_ui_components.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- .../kbn_server_route_repository_client.mdx | 2 +- .../kbn_server_route_repository_utils.mdx | 2 +- api_docs/kbn_serverless_common_settings.mdx | 2 +- .../kbn_serverless_observability_settings.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_search_settings.mdx | 2 +- api_docs/kbn_serverless_security_settings.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_error_boundary.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_tabbed_modal.mdx | 2 +- api_docs/kbn_shared_ux_table_persist.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_sort_predicates.mdx | 2 +- api_docs/kbn_sse_utils.mdx | 2 +- api_docs/kbn_sse_utils_client.mdx | 2 +- api_docs/kbn_sse_utils_server.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_synthetics_e2e.mdx | 2 +- api_docs/kbn_synthetics_private_location.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_eui_helpers.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_timerange.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_triggers_actions_ui_types.mdx | 2 +- api_docs/kbn_try_in_console.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_data_table.mdx | 2 +- api_docs/kbn_unified_doc_viewer.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_unsaved_changes_badge.mdx | 2 +- api_docs/kbn_unsaved_changes_prompt.mdx | 2 +- api_docs/kbn_use_tracked_promise.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_visualization_ui_components.mdx | 2 +- api_docs/kbn_visualization_utils.mdx | 2 +- api_docs/kbn_xstate_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kbn_zod.mdx | 2 +- api_docs/kbn_zod_helpers.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/links.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/logs_data_access.mdx | 2 +- api_docs/logs_explorer.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 4 +- api_docs/maps_ems.mdx | 4 +- api_docs/metrics_data_access.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/mock_idp_plugin.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/no_data_page.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 98 ++++++++++ api_docs/observability.mdx | 4 +- api_docs/observability_a_i_assistant.mdx | 2 +- api_docs/observability_a_i_assistant_app.mdx | 2 +- .../observability_ai_assistant_management.mdx | 2 +- api_docs/observability_logs_explorer.mdx | 2 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/painless_lab.mdx | 2 +- api_docs/plugin_directory.mdx | 32 ++-- api_docs/presentation_panel.mdx | 2 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/profiling_data_access.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/search_assistant.mdx | 2 +- api_docs/search_connectors.mdx | 2 +- api_docs/search_homepage.mdx | 2 +- api_docs/search_indices.mdx | 2 +- api_docs/search_inference_endpoints.mdx | 2 +- api_docs/search_notebooks.mdx | 2 +- api_docs/search_playground.devdocs.json | 50 +++++- api_docs/search_playground.mdx | 7 +- api_docs/security.devdocs.json | 10 +- api_docs/security.mdx | 2 +- api_docs/security_solution.devdocs.json | 29 ++- api_docs/security_solution.mdx | 4 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/slo.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_doc_viewer.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 753 files changed, 1365 insertions(+), 871 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 70e65ec3ed3da..c4fbdfcb5e34d 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index a48b067ad9790..d0c58de4628b9 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index a1013eb0966d2..4ea3f14f56f5b 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index d2be63d8ed7cd..24d7ca55ff7b6 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index d27f6497a9543..dcced67417b45 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 5f2aadf4ec2d8..433d6fb2b679d 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index b46bd1a0c3436..46e2986eeb328 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 82649312c9982..b75d2a41566e6 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 2900c30036e4d..2613028c72646 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 55d203b475c98..b831ca7e3e130 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index ea895dcdd8d2e..062ea20eb220f 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index e9d9eef843f02..8aff7784b2a3f 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 0bfd3fd4f77b9..efc875903dea3 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index b06b4188189bd..5ac7ea3f03785 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 346048dff210d..24d4768c51d71 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 5355d303114ad..4a4f102c5272d 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index a146286825fcc..52883854358fc 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index 269ed079e6d4b..54ed24f38d8b7 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 29cb35ccf33c1..18d9c8e5afdff 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 877a9fd6ce269..4ac6ce620f80c 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 694a647e81678..567e9d7c9fc0b 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index f31e8d8618d6b..05321d69a10ec 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index f9b744f0ea11a..e5adcacb2c091 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 2b609646c8ef7..ee6d8e87c60d3 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_quality.mdx b/api_docs/data_quality.mdx index be2d80e86e248..95f02cc14f6ee 100644 --- a/api_docs/data_quality.mdx +++ b/api_docs/data_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataQuality title: "dataQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the dataQuality plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataQuality'] --- import dataQualityObj from './data_quality.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 5cc04a4ab8957..65dcfafbcf977 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 37a07d0ea1ac6..f9c15b4060797 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index c57fc4d611383..306dfa0ad8dd8 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 6b12ca5a703f6..67e265ee785da 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 8302b0bf3e709..e890a14638061 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 100593d0e55ef..3f64a90a57d08 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 971a21d9e5557..d7571f53693e5 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index 5626a1013f4f0..43e3fda676941 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 324987e7f3b8f..19cc34810eb43 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 5425334348f11..170b6f6b03dd1 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -795,7 +795,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [enable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/enable.ts#:~:text=authc), [disable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/disable.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [enable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/enable.ts#:~:text=authc), [disable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/disable.ts#:~:text=authc) | - | +| | [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [enable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts#:~:text=authc), [disable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [api_key.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts#:~:text=authc), [enable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/routes/enablement/enable.ts#:~:text=authc), [disable.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/entity_manager/server/routes/enablement/disable.ts#:~:text=authc) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 5c74ba7845e44..88e6d3a8a0136 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -48,15 +48,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] -## @elastic/kibana-gis - -| Plugin | Deprecated API | Reference location(s) | Remove By | -| --------|-------|-----------|-----------| -| mapsEms | | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/maps_ems/server/plugin.ts#:~:text=license%24) | 8.8.0 | -| mapsEms | | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/maps_ems/server/plugin.ts#:~:text=refresh) | 8.8.0 | - - - ## @elastic/kibana-management | Plugin | Deprecated API | Reference location(s) | Remove By | @@ -72,6 +63,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| | dashboard | | [save_modal.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_container/embeddable/api/overlays/save_modal.tsx#:~:text=SavedObjectSaveModal), [add_to_library_action.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx#:~:text=SavedObjectSaveModal), [add_to_library_action.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/dashboard/public/dashboard_actions/add_to_library_action.tsx#:~:text=SavedObjectSaveModal), [saved_object_save_modal_dashboard.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx#:~:text=SavedObjectSaveModal), [saved_object_save_modal_dashboard.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx#:~:text=SavedObjectSaveModal), [attribute_service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx#:~:text=SavedObjectSaveModal), [attribute_service.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx#:~:text=SavedObjectSaveModal), [save_to_library.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/links/public/content_management/save_to_library.tsx#:~:text=SavedObjectSaveModal), [save_to_library.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/links/public/content_management/save_to_library.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | +| mapsEms | | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/maps_ems/server/plugin.ts#:~:text=license%24) | 8.8.0 | +| mapsEms | | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/maps_ems/server/plugin.ts#:~:text=refresh) | 8.8.0 | diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index c1e6520ee8963..8249e59ac6ac0 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 0ab2219b2ef49..32ce679b6b3df 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 27da0dc2a563b..737a29e23bc69 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/discover_shared.mdx b/api_docs/discover_shared.mdx index 117c2246e4cd7..b5e621a85caf7 100644 --- a/api_docs/discover_shared.mdx +++ b/api_docs/discover_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverShared title: "discoverShared" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverShared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverShared'] --- import discoverSharedObj from './discover_shared.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 348cef252ef76..93216bca36426 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index 4d5e76e5c56c8..a057596b1d93f 100644 --- a/api_docs/elastic_assistant.mdx +++ b/api_docs/elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/elasticAssistant title: "elasticAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the elasticAssistant plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index ad028690f665a..c8d5fc4e07b4d 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 1075d2e29b4e5..9fc217338d020 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index eb49e8bff6a78..4c689e194aef4 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index cc143c729bd61..35c5c2b7fd192 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/entities_data_access.mdx b/api_docs/entities_data_access.mdx index 6986fb214184f..5ba160bf8cbdd 100644 --- a/api_docs/entities_data_access.mdx +++ b/api_docs/entities_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entitiesDataAccess title: "entitiesDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the entitiesDataAccess plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entitiesDataAccess'] --- import entitiesDataAccessObj from './entities_data_access.devdocs.json'; diff --git a/api_docs/entity_manager.devdocs.json b/api_docs/entity_manager.devdocs.json index 617634d5c931c..0e10719557be2 100644 --- a/api_docs/entity_manager.devdocs.json +++ b/api_docs/entity_manager.devdocs.json @@ -19,7 +19,7 @@ }, " extends Error" ], - "path": "x-pack/plugins/observability_solution/entity_manager/public/lib/errors.ts", + "path": "x-pack/plugins/entity_manager/public/lib/errors.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -33,7 +33,7 @@ "signature": [ "any" ], - "path": "x-pack/plugins/observability_solution/entity_manager/public/lib/errors.ts", + "path": "x-pack/plugins/entity_manager/public/lib/errors.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -47,7 +47,7 @@ "signature": [ "string" ], - "path": "x-pack/plugins/observability_solution/entity_manager/public/lib/errors.ts", + "path": "x-pack/plugins/entity_manager/public/lib/errors.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -73,7 +73,7 @@ "signature": [ "\"entityManager\"" ], - "path": "x-pack/plugins/observability_solution/entity_manager/public/index.ts", + "path": "x-pack/plugins/entity_manager/public/index.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -88,7 +88,7 @@ "signature": [ "\"api_key_not_found\"" ], - "path": "x-pack/plugins/observability_solution/entity_manager/common/errors.ts", + "path": "x-pack/plugins/entity_manager/common/errors.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -103,7 +103,7 @@ "signature": [ "\"api_key_not_valid\"" ], - "path": "x-pack/plugins/observability_solution/entity_manager/common/errors.ts", + "path": "x-pack/plugins/entity_manager/common/errors.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -118,7 +118,7 @@ "signature": [ "\"api_key_service_disabled\"" ], - "path": "x-pack/plugins/observability_solution/entity_manager/common/errors.ts", + "path": "x-pack/plugins/entity_manager/common/errors.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -133,7 +133,7 @@ "signature": [ "\"error_definition_stopped\"" ], - "path": "x-pack/plugins/observability_solution/entity_manager/common/errors.ts", + "path": "x-pack/plugins/entity_manager/common/errors.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -148,7 +148,7 @@ "signature": [ "\"partial_builtin_installation\"" ], - "path": "x-pack/plugins/observability_solution/entity_manager/common/errors.ts", + "path": "x-pack/plugins/entity_manager/common/errors.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -162,7 +162,7 @@ "tags": [], "label": "EntityManagerPublicPluginSetup", "description": [], - "path": "x-pack/plugins/observability_solution/entity_manager/public/types.ts", + "path": "x-pack/plugins/entity_manager/public/types.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -176,7 +176,7 @@ "signature": [ "EntityClient" ], - "path": "x-pack/plugins/observability_solution/entity_manager/public/types.ts", + "path": "x-pack/plugins/entity_manager/public/types.ts", "deprecated": false, "trackAdoption": false } @@ -191,7 +191,7 @@ "tags": [], "label": "EntityManagerPublicPluginStart", "description": [], - "path": "x-pack/plugins/observability_solution/entity_manager/public/types.ts", + "path": "x-pack/plugins/entity_manager/public/types.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -205,7 +205,7 @@ "signature": [ "EntityClient" ], - "path": "x-pack/plugins/observability_solution/entity_manager/public/types.ts", + "path": "x-pack/plugins/entity_manager/public/types.ts", "deprecated": false, "trackAdoption": false } @@ -230,7 +230,7 @@ "signature": [ "{}" ], - "path": "x-pack/plugins/observability_solution/entity_manager/common/config.ts", + "path": "x-pack/plugins/entity_manager/common/config.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -597,7 +597,7 @@ }, ">; }" ], - "path": "x-pack/plugins/observability_solution/entity_manager/server/routes/index.ts", + "path": "x-pack/plugins/entity_manager/server/routes/index.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -611,7 +611,7 @@ "tags": [], "label": "EntityManagerServerPluginSetup", "description": [], - "path": "x-pack/plugins/observability_solution/entity_manager/server/plugin.ts", + "path": "x-pack/plugins/entity_manager/server/plugin.ts", "deprecated": false, "trackAdoption": false, "children": [], @@ -625,7 +625,7 @@ "tags": [], "label": "EntityManagerServerPluginStart", "description": [], - "path": "x-pack/plugins/observability_solution/entity_manager/server/plugin.ts", + "path": "x-pack/plugins/entity_manager/server/plugin.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -649,7 +649,7 @@ "EntityClient", ">" ], - "path": "x-pack/plugins/observability_solution/entity_manager/server/plugin.ts", + "path": "x-pack/plugins/entity_manager/server/plugin.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -660,7 +660,7 @@ "tags": [], "label": "options", "description": [], - "path": "x-pack/plugins/observability_solution/entity_manager/server/plugin.ts", + "path": "x-pack/plugins/entity_manager/server/plugin.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -681,7 +681,7 @@ }, "" ], - "path": "x-pack/plugins/observability_solution/entity_manager/server/plugin.ts", + "path": "x-pack/plugins/entity_manager/server/plugin.ts", "deprecated": false, "trackAdoption": false } diff --git a/api_docs/entity_manager.mdx b/api_docs/entity_manager.mdx index 247eb727bb5ab..7f89b3d508637 100644 --- a/api_docs/entity_manager.mdx +++ b/api_docs/entity_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/entityManager title: "entityManager" image: https://source.unsplash.com/400x175/?github description: API docs for the entityManager plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'entityManager'] --- import entityManagerObj from './entity_manager.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 269b8f45b676d..617f7b9376a59 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/esql.mdx b/api_docs/esql.mdx index 119acb6e5d70e..5f49d43b2ba08 100644 --- a/api_docs/esql.mdx +++ b/api_docs/esql.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esql title: "esql" image: https://source.unsplash.com/400x175/?github description: API docs for the esql plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esql'] --- import esqlObj from './esql.devdocs.json'; diff --git a/api_docs/esql_data_grid.mdx b/api_docs/esql_data_grid.mdx index 74339796bbdfe..6854eb2543bd0 100644 --- a/api_docs/esql_data_grid.mdx +++ b/api_docs/esql_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esqlDataGrid title: "esqlDataGrid" image: https://source.unsplash.com/400x175/?github description: API docs for the esqlDataGrid plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esqlDataGrid'] --- import esqlDataGridObj from './esql_data_grid.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index d18d268a0388c..f18fe4c39ca5b 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_annotation_listing.mdx b/api_docs/event_annotation_listing.mdx index d067c71442497..801e1bbf1269f 100644 --- a/api_docs/event_annotation_listing.mdx +++ b/api_docs/event_annotation_listing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotationListing title: "eventAnnotationListing" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotationListing plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotationListing'] --- import eventAnnotationListingObj from './event_annotation_listing.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index aac4d166d85aa..11a90044beac6 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index d7a6fe407fc8e..dccdd8fb0d076 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 37aa871c2f9e1..1bcbf5fb9d763 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index e8746ac39cdf7..1c4147774119b 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index 375884c2d42b0..f54ff3d8fbfba 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 308f5ebd36aa6..b8651d3ee835e 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index b8f0d175507a2..28fbb00638c70 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 62dc073388a35..0f2a6096212a8 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index e6811e7f1090c..015a6f5efe06a 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 50d72b87f8ead..b318af14ba084 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 2c28f87b7732e..fef1442a8aa60 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 55d6f9e9a162f..a9efad1af3afd 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 47539dae74edd..ad15bc68d6bef 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index d34aeab32c4cb..8409d2fbe9fc6 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index f28a499fe5d78..3d8e5f1a86110 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 7aee414de7a1a..e79d4e5c626af 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 3d14fcc6470f7..96700c8ef1b5d 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 4bb84c6945011..1bf027f21a72d 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/fields_metadata.mdx b/api_docs/fields_metadata.mdx index 5d4f719e6a827..043ce48788631 100644 --- a/api_docs/fields_metadata.mdx +++ b/api_docs/fields_metadata.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldsMetadata title: "fieldsMetadata" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldsMetadata plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldsMetadata'] --- import fieldsMetadataObj from './fields_metadata.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 9b5b4af29654e..7c24d649991c9 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. -Contact [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) for questions regarding this plugin. +Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/files.mdx b/api_docs/files.mdx index e32929eb9ce2f..6b552d78c3bf5 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index c9177103781b2..5664324e76c09 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 46947a661ce66..a2f666d15b9bf 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 9ec721584a40e..a2b7ea7cf67f2 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index fa612c8fb0153..83cb014b8aa84 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index fcca7ce317b81..c3c8155964cb4 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 748320ecfc75f..3664ca37017ed 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 1e4fb2a322ecd..9583635638396 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.devdocs.json b/api_docs/index_management.devdocs.json index 0e6c5e0f704ef..d7125c7bcee9d 100644 --- a/api_docs/index_management.devdocs.json +++ b/api_docs/index_management.devdocs.json @@ -1168,7 +1168,7 @@ "signature": [ "(field: string) => { size: string; unit: string; }" ], - "path": "x-pack/plugins/index_management/common/lib/data_stream_serialization.ts", + "path": "x-pack/plugins/index_management/common/lib/data_stream_utils.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -1182,7 +1182,7 @@ "signature": [ "string" ], - "path": "x-pack/plugins/index_management/common/lib/data_stream_serialization.ts", + "path": "x-pack/plugins/index_management/common/lib/data_stream_utils.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -1831,6 +1831,48 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "indexManagement", + "id": "def-common.DataStream.meteringStorageSizeBytes", + "type": "number", + "tags": [], + "label": "meteringStorageSizeBytes", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/data_streams.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "indexManagement", + "id": "def-common.DataStream.meteringStorageSize", + "type": "string", + "tags": [], + "label": "meteringStorageSize", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/data_streams.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "indexManagement", + "id": "def-common.DataStream.meteringDocsCount", + "type": "number", + "tags": [], + "label": "meteringDocsCount", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/data_streams.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "indexManagement", "id": "def-common.DataStream._meta", @@ -2024,6 +2066,34 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "indexManagement", + "id": "def-common.EnhancedDataStreamFromEs.metering_size_in_bytes", + "type": "number", + "tags": [], + "label": "metering_size_in_bytes", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/data_streams.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "indexManagement", + "id": "def-common.EnhancedDataStreamFromEs.metering_doc_count", + "type": "number", + "tags": [], + "label": "metering_doc_count", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/index_management/common/types/data_streams.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "indexManagement", "id": "def-common.EnhancedDataStreamFromEs.indices", diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index aab6c815de772..b5f6c23e13e6b 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kiban | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 238 | 0 | 233 | 1 | +| 243 | 0 | 238 | 1 | ## Client diff --git a/api_docs/inference.mdx b/api_docs/inference.mdx index e32414ade4bc9..b4c53d98880b0 100644 --- a/api_docs/inference.mdx +++ b/api_docs/inference.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inference title: "inference" image: https://source.unsplash.com/400x175/?github description: API docs for the inference plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inference'] --- import inferenceObj from './inference.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 133bdddf8fd65..b8b2fa8842037 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/ingest_pipelines.mdx b/api_docs/ingest_pipelines.mdx index a39bbf1c195a9..bfe50abb06198 100644 --- a/api_docs/ingest_pipelines.mdx +++ b/api_docs/ingest_pipelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ingestPipelines title: "ingestPipelines" image: https://source.unsplash.com/400x175/?github description: API docs for the ingestPipelines plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ingestPipelines'] --- import ingestPipelinesObj from './ingest_pipelines.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 12c88f74c115c..a0f4e00a51998 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/integration_assistant.mdx b/api_docs/integration_assistant.mdx index 549932c21dea2..b6fadc08f0430 100644 --- a/api_docs/integration_assistant.mdx +++ b/api_docs/integration_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/integrationAssistant title: "integrationAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the integrationAssistant plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'integrationAssistant'] --- import integrationAssistantObj from './integration_assistant.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index dbe988497a1c5..fcf123e97b8bd 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/inventory.mdx b/api_docs/inventory.mdx index 438359ff00cad..17fb584da67a0 100644 --- a/api_docs/inventory.mdx +++ b/api_docs/inventory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inventory title: "inventory" image: https://source.unsplash.com/400x175/?github description: API docs for the inventory plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inventory'] --- import inventoryObj from './inventory.devdocs.json'; diff --git a/api_docs/investigate.mdx b/api_docs/investigate.mdx index c3c540de2f7f3..21137d89bd5da 100644 --- a/api_docs/investigate.mdx +++ b/api_docs/investigate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigate title: "investigate" image: https://source.unsplash.com/400x175/?github description: API docs for the investigate plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigate'] --- import investigateObj from './investigate.devdocs.json'; diff --git a/api_docs/investigate_app.devdocs.json b/api_docs/investigate_app.devdocs.json index 089eb27f74985..2c1f3e3fa13d0 100644 --- a/api_docs/investigate_app.devdocs.json +++ b/api_docs/investigate_app.devdocs.json @@ -50,7 +50,31 @@ "label": "InvestigateAppServerRouteRepository", "description": [], "signature": [ - "{ \"GET /api/observability/investigations/{investigationId}/items 2023-10-31\": ", + "{ \"GET /api/observability/investigations/_tags 2023-10-31\": ", + { + "pluginId": "@kbn/server-route-repository-utils", + "scope": "common", + "docId": "kibKbnServerRouteRepositoryUtilsPluginApi", + "section": "def-common.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /api/observability/investigations/_tags 2023-10-31\", Zod.ZodObject<{ query: Zod.ZodObject<{}, \"strip\", Zod.ZodTypeAny, {}, {}>; }, \"strip\", Zod.ZodTypeAny, { query: {}; }, { query: {}; }>, ", + "InvestigateAppRouteHandlerResources", + ", string[], ", + "InvestigateAppRouteCreateOptions", + ">; \"GET /api/observability/investigations/_stats 2023-10-31\": ", + { + "pluginId": "@kbn/server-route-repository-utils", + "scope": "common", + "docId": "kibKbnServerRouteRepositoryUtilsPluginApi", + "section": "def-common.ServerRoute", + "text": "ServerRoute" + }, + "<\"GET /api/observability/investigations/_stats 2023-10-31\", Zod.ZodObject<{ query: Zod.ZodObject<{}, \"strip\", Zod.ZodTypeAny, {}, {}>; }, \"strip\", Zod.ZodTypeAny, { query: {}; }, { query: {}; }>, ", + "InvestigateAppRouteHandlerResources", + ", { count: Partial>; total: number; }, ", + "InvestigateAppRouteCreateOptions", + ">; \"GET /api/observability/investigations/{investigationId}/items 2023-10-31\": ", { "pluginId": "@kbn/server-route-repository-utils", "scope": "common", @@ -60,7 +84,7 @@ }, "<\"GET /api/observability/investigations/{investigationId}/items 2023-10-31\", Zod.ZodObject<{ path: Zod.ZodObject<{ investigationId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { investigationId: string; }, { investigationId: string; }>; }, \"strip\", Zod.ZodTypeAny, { path: { investigationId: string; }; }, { path: { investigationId: string; }; }>, ", "InvestigateAppRouteHandlerResources", - ", ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[], ", + ", ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[], ", "InvestigateAppRouteCreateOptions", ">; \"PUT /api/observability/investigations/{investigationId}/items/{itemId} 2023-10-31\": ", { @@ -96,7 +120,7 @@ }, "<\"POST /api/observability/investigations/{investigationId}/items 2023-10-31\", Zod.ZodObject<{ path: Zod.ZodObject<{ investigationId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { investigationId: string; }, { investigationId: string; }>; body: Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>; }, \"strip\", Zod.ZodTypeAny, { body: { params: Record; type: string; title: string; }; path: { investigationId: string; }; }, { body: { params: Record; type: string; title: string; }; path: { investigationId: string; }; }>, ", "InvestigateAppRouteHandlerResources", - ", { id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; }, ", + ", { id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; }, ", "InvestigateAppRouteCreateOptions", ">; \"DELETE /api/observability/investigations/{investigationId}/notes/{noteId} 2023-10-31\": ", { @@ -132,7 +156,7 @@ }, "<\"GET /api/observability/investigations/{investigationId}/notes 2023-10-31\", Zod.ZodObject<{ path: Zod.ZodObject<{ investigationId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { investigationId: string; }, { investigationId: string; }>; }, \"strip\", Zod.ZodTypeAny, { path: { investigationId: string; }; }, { path: { investigationId: string; }; }>, ", "InvestigateAppRouteHandlerResources", - ", { id: string; createdBy: string; createdAt: number; content: string; }[], ", + ", { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[], ", "InvestigateAppRouteCreateOptions", ">; \"POST /api/observability/investigations/{investigationId}/notes 2023-10-31\": ", { @@ -144,7 +168,7 @@ }, "<\"POST /api/observability/investigations/{investigationId}/notes 2023-10-31\", Zod.ZodObject<{ path: Zod.ZodObject<{ investigationId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { investigationId: string; }, { investigationId: string; }>; body: Zod.ZodObject<{ content: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { content: string; }, { content: string; }>; }, \"strip\", Zod.ZodTypeAny, { body: { content: string; }; path: { investigationId: string; }; }, { body: { content: string; }; path: { investigationId: string; }; }>, ", "InvestigateAppRouteHandlerResources", - ", { id: string; createdBy: string; createdAt: number; content: string; }, ", + ", { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }, ", "InvestigateAppRouteCreateOptions", ">; \"DELETE /api/observability/investigations/{investigationId} 2023-10-31\": ", { @@ -168,7 +192,7 @@ }, "<\"PUT /api/observability/investigations/{investigationId} 2023-10-31\", Zod.ZodObject<{ path: Zod.ZodObject<{ investigationId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { investigationId: string; }, { investigationId: string; }>; body: Zod.ZodObject<{ title: Zod.ZodOptional; status: Zod.ZodOptional, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>>; params: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>>; tags: Zod.ZodOptional>; }, \"strip\", Zod.ZodTypeAny, { params?: { timeRange: { from: number; to: number; }; } | undefined; tags?: string[] | undefined; title?: string | undefined; status?: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\" | undefined; }, { params?: { timeRange: { from: number; to: number; }; } | undefined; tags?: string[] | undefined; title?: string | undefined; status?: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\" | undefined; }>; }, \"strip\", Zod.ZodTypeAny, { body: { params?: { timeRange: { from: number; to: number; }; } | undefined; tags?: string[] | undefined; title?: string | undefined; status?: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\" | undefined; }; path: { investigationId: string; }; }, { body: { params?: { timeRange: { from: number; to: number; }; } | undefined; tags?: string[] | undefined; title?: string | undefined; status?: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\" | undefined; }; path: { investigationId: string; }; }>, ", "InvestigateAppRouteHandlerResources", - ", { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, ", + ", { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, ", "InvestigateAppRouteCreateOptions", ">; \"GET /api/observability/investigations/{investigationId} 2023-10-31\": ", { @@ -180,7 +204,7 @@ }, "<\"GET /api/observability/investigations/{investigationId} 2023-10-31\", Zod.ZodObject<{ path: Zod.ZodObject<{ investigationId: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { investigationId: string; }, { investigationId: string; }>; }, \"strip\", Zod.ZodTypeAny, { path: { investigationId: string; }; }, { path: { investigationId: string; }; }>, ", "InvestigateAppRouteHandlerResources", - ", { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, ", + ", { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, ", "InvestigateAppRouteCreateOptions", ">; \"GET /api/observability/investigations 2023-10-31\": ", { @@ -190,9 +214,9 @@ "section": "def-common.ServerRoute", "text": "ServerRoute" }, - "<\"GET /api/observability/investigations 2023-10-31\", Zod.ZodObject<{ query: Zod.ZodOptional; page: Zod.ZodOptional; perPage: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; }, { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { query?: { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; } | undefined; }, { query?: { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; } | undefined; }>, ", + "<\"GET /api/observability/investigations 2023-10-31\", Zod.ZodObject<{ query: Zod.ZodOptional; search: Zod.ZodOptional; filter: Zod.ZodOptional; page: Zod.ZodOptional; perPage: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; }, { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { query?: { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; } | undefined; }, { query?: { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; } | undefined; }>, ", "InvestigateAppRouteHandlerResources", - ", { page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }[]; perPage: number; total: number; }, ", + ", { page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }[]; perPage: number; total: number; }, ", "InvestigateAppRouteCreateOptions", ">; \"POST /api/observability/investigations 2023-10-31\": ", { @@ -204,7 +228,7 @@ }, "<\"POST /api/observability/investigations 2023-10-31\", Zod.ZodObject<{ body: Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; tags: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; }>; }, \"strip\", Zod.ZodTypeAny, { body: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; }; }, { body: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; }; }>, ", "InvestigateAppRouteHandlerResources", - ", { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, ", + ", { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, ", "InvestigateAppRouteCreateOptions", ">; }" ], diff --git a/api_docs/investigate_app.mdx b/api_docs/investigate_app.mdx index 800cd212dbdba..4434f14f16ab9 100644 --- a/api_docs/investigate_app.mdx +++ b/api_docs/investigate_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/investigateApp title: "investigateApp" image: https://source.unsplash.com/400x175/?github description: API docs for the investigateApp plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'investigateApp'] --- import investigateAppObj from './investigate_app.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 8d38bd5aab9a8..866b16a6b5fad 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index 6c6e95b152d4e..d11a58d21f16c 100644 --- a/api_docs/kbn_actions_types.mdx +++ b/api_docs/kbn_actions_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-actions-types title: "@kbn/actions-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/actions-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index 14eab4e516aec..5c29f09b64ec5 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_pattern_analysis.mdx b/api_docs/kbn_aiops_log_pattern_analysis.mdx index 67db1a10d31c6..8a9eda36479e6 100644 --- a/api_docs/kbn_aiops_log_pattern_analysis.mdx +++ b/api_docs/kbn_aiops_log_pattern_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-pattern-analysis title: "@kbn/aiops-log-pattern-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-pattern-analysis plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-pattern-analysis'] --- import kbnAiopsLogPatternAnalysisObj from './kbn_aiops_log_pattern_analysis.devdocs.json'; diff --git a/api_docs/kbn_aiops_log_rate_analysis.mdx b/api_docs/kbn_aiops_log_rate_analysis.mdx index bfb2d31be4cf6..6f332fe6cb953 100644 --- a/api_docs/kbn_aiops_log_rate_analysis.mdx +++ b/api_docs/kbn_aiops_log_rate_analysis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-log-rate-analysis title: "@kbn/aiops-log-rate-analysis" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-log-rate-analysis plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-log-rate-analysis'] --- import kbnAiopsLogRateAnalysisObj from './kbn_aiops_log_rate_analysis.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index ed5c88415cf06..67345c411f3db 100644 --- a/api_docs/kbn_alerting_api_integration_helpers.mdx +++ b/api_docs/kbn_alerting_api_integration_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-api-integration-helpers title: "@kbn/alerting-api-integration-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-api-integration-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_comparators.mdx b/api_docs/kbn_alerting_comparators.mdx index 8027193871167..5bf205bedbffd 100644 --- a/api_docs/kbn_alerting_comparators.mdx +++ b/api_docs/kbn_alerting_comparators.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-comparators title: "@kbn/alerting-comparators" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-comparators plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-comparators'] --- import kbnAlertingComparatorsObj from './kbn_alerting_comparators.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 38e15414ee87b..591a4b4d336ed 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerting_types.mdx b/api_docs/kbn_alerting_types.mdx index e5b1131bcbd42..11bd24d848b59 100644 --- a/api_docs/kbn_alerting_types.mdx +++ b/api_docs/kbn_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-types title: "@kbn/alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-types'] --- import kbnAlertingTypesObj from './kbn_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 7b07c4266f2c6..6f8c8f9d7f898 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_grouping.mdx b/api_docs/kbn_alerts_grouping.mdx index 80721130e4797..f071209d66ba4 100644 --- a/api_docs/kbn_alerts_grouping.mdx +++ b/api_docs/kbn_alerts_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-grouping title: "@kbn/alerts-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-grouping plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-grouping'] --- import kbnAlertsGroupingObj from './kbn_alerts_grouping.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 164f1b1e678cc..98a9d83f9fc28 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index b5360f43e50a1..f9be95a24ea03 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 356b94b5b147c..655ae4d6994f2 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index e4003a21704b0..5aae0950fd43d 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_data_view.mdx b/api_docs/kbn_apm_data_view.mdx index 33fb5d7d44173..05d4993864418 100644 --- a/api_docs/kbn_apm_data_view.mdx +++ b/api_docs/kbn_apm_data_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-data-view title: "@kbn/apm-data-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-data-view plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-data-view'] --- import kbnApmDataViewObj from './kbn_apm_data_view.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 01e1c158024ea..3622c1028e95a 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 3ce66e195254a..c972c71ddc976 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_types.mdx b/api_docs/kbn_apm_types.mdx index 83327cef25953..f83cc7e4ca2c6 100644 --- a/api_docs/kbn_apm_types.mdx +++ b/api_docs/kbn_apm_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-types title: "@kbn/apm-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-types'] --- import kbnApmTypesObj from './kbn_apm_types.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index d53ea4526ab27..f3da51db40c3d 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_avc_banner.mdx b/api_docs/kbn_avc_banner.mdx index 233d64762f81d..64ee13d1014f8 100644 --- a/api_docs/kbn_avc_banner.mdx +++ b/api_docs/kbn_avc_banner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-avc-banner title: "@kbn/avc-banner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/avc-banner plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/avc-banner'] --- import kbnAvcBannerObj from './kbn_avc_banner.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 431dde47131ab..9eac8ce257436 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_bfetch_error.mdx b/api_docs/kbn_bfetch_error.mdx index 72e0634b95007..e781f438eec18 100644 --- a/api_docs/kbn_bfetch_error.mdx +++ b/api_docs/kbn_bfetch_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-bfetch-error title: "@kbn/bfetch-error" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/bfetch-error plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bfetch-error'] --- import kbnBfetchErrorObj from './kbn_bfetch_error.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index b3087deea5837..d0c0f67a41675 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_calculate_width_from_char_count.mdx b/api_docs/kbn_calculate_width_from_char_count.mdx index e2ab61dcb1f7f..d6e072f6a820b 100644 --- a/api_docs/kbn_calculate_width_from_char_count.mdx +++ b/api_docs/kbn_calculate_width_from_char_count.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-width-from-char-count title: "@kbn/calculate-width-from-char-count" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-width-from-char-count plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-width-from-char-count'] --- import kbnCalculateWidthFromCharCountObj from './kbn_calculate_width_from_char_count.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 8847c805efde0..7d02875b9b309 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cbor.mdx b/api_docs/kbn_cbor.mdx index 6ec6babc7fb58..c505a7754e432 100644 --- a/api_docs/kbn_cbor.mdx +++ b/api_docs/kbn_cbor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cbor title: "@kbn/cbor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cbor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cbor'] --- import kbnCborObj from './kbn_cbor.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 1cdf8bb8fd27a..554f4467d7b86 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index af779b6352f8f..313130b0c011a 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index 3cd7fd83ef675..fb10f57d2a4a1 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index d36f032077178..94e6d4f323b7a 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 4557bb5299e54..4614784ce9d82 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 158927f168a33..7f1f1f4482ea4 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index 458b21a9e9c26..767371636e61c 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture.mdx b/api_docs/kbn_cloud_security_posture.mdx index dddebd2460fa8..68227061c3d4d 100644 --- a/api_docs/kbn_cloud_security_posture.mdx +++ b/api_docs/kbn_cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture title: "@kbn/cloud-security-posture" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture'] --- import kbnCloudSecurityPostureObj from './kbn_cloud_security_posture.devdocs.json'; diff --git a/api_docs/kbn_cloud_security_posture_common.mdx b/api_docs/kbn_cloud_security_posture_common.mdx index 06636275aac11..53f5f0b091d5f 100644 --- a/api_docs/kbn_cloud_security_posture_common.mdx +++ b/api_docs/kbn_cloud_security_posture_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cloud-security-posture-common title: "@kbn/cloud-security-posture-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cloud-security-posture-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cloud-security-posture-common'] --- import kbnCloudSecurityPostureCommonObj from './kbn_cloud_security_posture_common.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index ef1f930f73a73..8b4a136d3f539 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mock.mdx b/api_docs/kbn_code_editor_mock.mdx index 4cd0ac063b295..959d76c3d5dab 100644 --- a/api_docs/kbn_code_editor_mock.mdx +++ b/api_docs/kbn_code_editor_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mock title: "@kbn/code-editor-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mock plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mock'] --- import kbnCodeEditorMockObj from './kbn_code_editor_mock.devdocs.json'; diff --git a/api_docs/kbn_code_owners.mdx b/api_docs/kbn_code_owners.mdx index 1837a351ab81f..631868dc59023 100644 --- a/api_docs/kbn_code_owners.mdx +++ b/api_docs/kbn_code_owners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-owners title: "@kbn/code-owners" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-owners plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index fa7b9b3370873..e01bb5c895c69 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index ffdcb0df99ff7..25b825449ab7a 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index d5c5afaa1ff4a..32b34161badb2 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 7b0267bf91d70..7d81b571fe349 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 1c6873650a77d..8b0a4aa85917e 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_public.mdx b/api_docs/kbn_content_management_content_insights_public.mdx index c0c9b3b664627..5aa2c3426fb00 100644 --- a/api_docs/kbn_content_management_content_insights_public.mdx +++ b/api_docs/kbn_content_management_content_insights_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-public title: "@kbn/content-management-content-insights-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-public plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-public'] --- import kbnContentManagementContentInsightsPublicObj from './kbn_content_management_content_insights_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_insights_server.mdx b/api_docs/kbn_content_management_content_insights_server.mdx index 3475f4b887614..513975becaa77 100644 --- a/api_docs/kbn_content_management_content_insights_server.mdx +++ b/api_docs/kbn_content_management_content_insights_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-insights-server title: "@kbn/content-management-content-insights-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-insights-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-insights-server'] --- import kbnContentManagementContentInsightsServerObj from './kbn_content_management_content_insights_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_public.mdx b/api_docs/kbn_content_management_favorites_public.mdx index 0f9def9418f08..cae21cd6d4c97 100644 --- a/api_docs/kbn_content_management_favorites_public.mdx +++ b/api_docs/kbn_content_management_favorites_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-public title: "@kbn/content-management-favorites-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-public plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-public'] --- import kbnContentManagementFavoritesPublicObj from './kbn_content_management_favorites_public.devdocs.json'; diff --git a/api_docs/kbn_content_management_favorites_server.mdx b/api_docs/kbn_content_management_favorites_server.mdx index 93c38d33446d4..b94e0076ece94 100644 --- a/api_docs/kbn_content_management_favorites_server.mdx +++ b/api_docs/kbn_content_management_favorites_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-favorites-server title: "@kbn/content-management-favorites-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-favorites-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-favorites-server'] --- import kbnContentManagementFavoritesServerObj from './kbn_content_management_favorites_server.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index c5874a17a7e44..6ebb853d6aa2d 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 1695b9b4cf7a0..36abef5e2fe63 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_common.mdx b/api_docs/kbn_content_management_table_list_view_common.mdx index 1e6d22f0e395d..5331a884a089d 100644 --- a/api_docs/kbn_content_management_table_list_view_common.mdx +++ b/api_docs/kbn_content_management_table_list_view_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-common title: "@kbn/content-management-table-list-view-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-common'] --- import kbnContentManagementTableListViewCommonObj from './kbn_content_management_table_list_view_common.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 5297d8f4a120f..06986166076f5 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_user_profiles.mdx b/api_docs/kbn_content_management_user_profiles.mdx index 54b5be39e5992..ae3e8911d7fd8 100644 --- a/api_docs/kbn_content_management_user_profiles.mdx +++ b/api_docs/kbn_content_management_user_profiles.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-user-profiles title: "@kbn/content-management-user-profiles" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-user-profiles plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-user-profiles'] --- import kbnContentManagementUserProfilesObj from './kbn_content_management_user_profiles.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 3ff84783eec75..9d3a61f39f739 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.devdocs.json b/api_docs/kbn_core_analytics_browser.devdocs.json index 1b2f965ed1619..c72c8e37bd6b3 100644 --- a/api_docs/kbn_core_analytics_browser.devdocs.json +++ b/api_docs/kbn_core_analytics_browser.devdocs.json @@ -978,6 +978,14 @@ "plugin": "apm", "path": "x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_client.ts" }, + { + "plugin": "apm", + "path": "x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_client.ts" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_client.ts" + }, { "plugin": "observabilityLogsExplorer", "path": "x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/observability_logs_explorer/src/telemetry_events.ts" diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 8ec085dfba3e5..98eeb597d8995 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index f56d94ce1c1c7..3810dce9fb521 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index d329f90a85725..da3e4c49e96ec 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.devdocs.json b/api_docs/kbn_core_analytics_server.devdocs.json index e507fa869a6ef..634566ac17f0b 100644 --- a/api_docs/kbn_core_analytics_server.devdocs.json +++ b/api_docs/kbn_core_analytics_server.devdocs.json @@ -986,6 +986,14 @@ "plugin": "apm", "path": "x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_client.ts" }, + { + "plugin": "apm", + "path": "x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_client.ts" + }, + { + "plugin": "apm", + "path": "x-pack/plugins/observability_solution/apm/public/services/telemetry/telemetry_client.ts" + }, { "plugin": "observabilityLogsExplorer", "path": "x-pack/plugins/observability_solution/observability_logs_explorer/public/state_machines/observability_logs_explorer/src/telemetry_events.ts" diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 5114fb3dbf83a..a65c6b7db8a90 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 71d17250a65fb..b5a875f854a2b 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 26ec671e63652..ce30cf6398c8e 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 6da1034bc5900..b648ea5af7fa9 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 100ef9c48e53c..9088d908c9c07 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 2068679e41060..ba2aeb9a1d230 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 5afc3c31f07ff..fa26c36ccef06 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index c38bee8197eb4..86d79a09915b0 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 99061d4ee9dbf..8761bb65a0048 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 513fac7a1d164..a192ec5203a69 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index fc1574f3ffa5d..2798e6ca7a81d 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 82e8ce70f7644..ea86337a9c53c 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 25d96744f8d90..aa247ee1428b8 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 6ac844b6ab62f..0e7313b2f1c38 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 0156d4bb6a216..1a243573deb97 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index c2de5533641cb..254c1979d1e49 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index dbeae64609253..77828c70c422b 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 55e78ca2f1354..0a11dfd768355 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 36cc7511677d7..ed4055d0542d6 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 94bc58481f62d..6b384a6351f94 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index a81585f3e2bf6..7cdc2b2a3ad66 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 8bbfd04b44d91..1be2a2661590c 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 1e3f4df6d6712..47f1b9d62236a 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index e87533f446bf6..40a21f0a1bf6f 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 45f604e553f9b..01ebedfb8496e 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index e99e65bcbc9b4..f19fc7a2c5ae4 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index 129b273546d49..2432a55ace7a7 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index c0175f3203325..10bcc8c0f4009 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index d8e1c14611fe9..e2851b48d0756 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 5ee9a49bb3711..0a5f07b2f97db 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 39d097b05c6af..cceb200bdc95e 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 2c304f1621f00..2af03727c8355 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index c8f71ac2048aa..79fe6b3ebad28 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 2fc8ee5cc6e08..7292c78a39d21 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index 4b559adbb8f57..94c8e764b34ef 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index e23684271a62e..b8cf4eabeb5b3 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 2d8544beb3963..66c5cd624c525 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 37fb3282ccb11..9f06c2191caec 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 23d413a014cff..969bfcbb182e6 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 223057aa76828..85bb343e5a620 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 00d95d44e6784..50ae9da931c65 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 46652758eac87..819b7796714dc 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index ceb10897fa4d2..78e02900e12d5 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 5672e3320fe34..af2bedeae9959 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index ff771cdf88623..64f14c837c9d1 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index f0da8bfb29d36..1e6c6d01faed1 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 11f2e73fe7d36..2bdc0cd92ebc1 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 0ec0b27c0fdf0..82d24f1e79db6 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 21be12294aade..a74d3119203da 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index fe4eb753599fd..3829b2a1d6bc3 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index c3b0dc19d8f24..bb98f680cac34 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index bed630363560a..459be354c1162 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 295607d98d13d..8567111159a5c 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 89a791ab6f81e..1d920e7c15bf1 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index fd33da167c615..b042e8438378d 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 61be0b0a4ed55..2a651155a84e8 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index dc22767351e39..62ed998af4027 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 4551c3ba09b3e..f733769a873c9 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index db09c2a9a7868..0e5c4144aaa65 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 1a579720428f7..889c5aed5588f 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index d731693893a86..e15700ccacb1f 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index c3df575a1da21..0d6fb26c8d94c 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 8a0577c4b90d0..9868c64e2d1a7 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index da5066b59b6bc..1021cad56dc95 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index bebfe0c6ea899..709fd4e41765e 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index d92f6c6db61b8..b1c3cb3c26092 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 3ceda5885b570..ddd611dbeb970 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -7236,6 +7236,10 @@ "plugin": "searchPlayground", "path": "x-pack/plugins/search_playground/server/routes.ts" }, + { + "plugin": "searchPlayground", + "path": "x-pack/plugins/search_playground/server/routes.ts" + }, { "plugin": "searchprofiler", "path": "x-pack/plugins/searchprofiler/server/routes/profile.ts" @@ -15018,6 +15022,14 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/settings.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/get.ts" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/list.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/endpoint/routes/metadata/index.ts" @@ -16472,6 +16484,18 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/risk_engine/routes/schedule_now.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/init.ts" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/start.ts" + }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stop.ts" + }, { "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts" @@ -16564,6 +16588,10 @@ "plugin": "synthetics", "path": "x-pack/plugins/observability_solution/synthetics/server/server.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/stats.ts" + }, { "plugin": "controls", "path": "src/plugins/controls/server/options_list/options_list_suggestions_route.ts" @@ -17030,6 +17058,10 @@ "plugin": "securitySolution", "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/delete.ts" }, + { + "plugin": "securitySolution", + "path": "x-pack/plugins/security_solution/server/lib/entity_analytics/entity_store/routes/delete.ts" + }, { "plugin": "synthetics", "path": "x-pack/plugins/observability_solution/synthetics/server/server.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 8267ac272233d..75cecd3065d29 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index e8fb07352b982..6e9ab6f3b05e6 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index d9b26755f3bee..046ed2bcbfb35 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index 9e8140935a19e..07ccd6c4a396a 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 3d00ba9302dfb..73a652f53e8ea 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index eae90099a6639..d6992bcf51c47 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index ef5ec29bbb9ad..cf3bd3b713ecc 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 9c1b3c95106c2..ddc9ba842c892 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index f010c8b75273f..e7544e7a8d6dc 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index 32d348478ffef..2843fc3afff78 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index f1208b2d1da65..18095bc3d6e8e 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index c91fcf1bb2342..d7805bafd2dcf 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 8d702b8382f38..ca3c940894abd 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index cdde236c79842..d39a49820ede8 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 87528841eea11..bd95191a0661c 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index e5ea66d095629..20777b130ac42 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 15c7161f20b31..067ce2810ed18 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index f3938004d1bf4..6aea4d10593cd 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 2eedaaf5c530d..0ad6ff325a86d 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 8da2b1f519cf6..2850db3b6d11f 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index ead61b1758574..b8103f8c5f889 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index e80ad71c5139c..8f3c81402bced 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 2372703cf6d21..f3b8e71307d07 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index 2d049dae63595..060eb1c590abd 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index fdf27ca280067..f845506fefdb5 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 3bdddcb8eca75..8169873c49645 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index bcda7033730f3..159dfe658fd6a 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 887b3b3b9471c..8f6c1f81f4c00 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index cd64a225c7a76..0cd467345ea1a 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 8cce4107aa925..d26307ee4a605 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index df3f6e41e3e1b..881c68ded85bc 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index 3cc718ccb17f8..2fbfd89d9dd87 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 89305a5b91734..91573b47ba3dd 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 1e1af76e01831..ded234cfa8ba0 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index f378a489ec147..82b89eb346d5c 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index a0568812f41ac..3fed1694e10c1 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index 652a957d550ec..d730faa050f91 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index b9efa108d2f86..2ed9db24b7428 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index 6348383b66a9e..c083d5dddc23e 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index c8bcbd18ff193..3a0be00b5b3cc 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 2e73a3b7ecffb..77251fb0af476 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 6a7c04d0a3449..366d8e4e69f9e 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 085f9d9e67bf3..fc745ce96e62e 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index b3833f739d3ed..42f2ee6b7ed74 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 7d277c1218886..854924f41c3bf 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 64639b5376cf3..b8c7cc015b4cb 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index f5e1821fe2df7..c2c0a440d3304 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 6d3a27d87f263..22693240cf562 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index a4bcf57e3681c..1638eec5caa40 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 043e473a20ff9..2ffb35721b97b 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index fdab7bdf94f1d..9f8cda1c29d61 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index 30d014db8ed89..37f7fc901ba7e 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 67387b08b956e..b67fab6009072 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index c68f30a6e4de0..0db036e1346d9 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 6702daa6184db..dcc9c5eeeeaac 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 826ec0fdd6ee6..0175848f3e433 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index ed5f3c383f41c..ac485bb33c7d1 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 797909c8702cb..55eb0a1f8010b 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index ec8afbba97d31..6fb016d686f79 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index b631da28cb914..d681975fb5cca 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 1d93a99a4a400..c06563abe8665 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 1b7ed797bbe8e..e2b6ac6208508 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 24be9a429b1b3..dd98faa4f4c6b 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 7c68d79393db2..0f612201181a5 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser.mdx b/api_docs/kbn_core_security_browser.mdx index 188d36b3a2be4..55f81e26b720f 100644 --- a/api_docs/kbn_core_security_browser.mdx +++ b/api_docs/kbn_core_security_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser title: "@kbn/core-security-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser'] --- import kbnCoreSecurityBrowserObj from './kbn_core_security_browser.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_internal.mdx b/api_docs/kbn_core_security_browser_internal.mdx index f43f182f98229..e71518159163a 100644 --- a/api_docs/kbn_core_security_browser_internal.mdx +++ b/api_docs/kbn_core_security_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-internal title: "@kbn/core-security-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-internal'] --- import kbnCoreSecurityBrowserInternalObj from './kbn_core_security_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_browser_mocks.mdx b/api_docs/kbn_core_security_browser_mocks.mdx index bd82e6ac32142..503951d7542e5 100644 --- a/api_docs/kbn_core_security_browser_mocks.mdx +++ b/api_docs/kbn_core_security_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-browser-mocks title: "@kbn/core-security-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-browser-mocks'] --- import kbnCoreSecurityBrowserMocksObj from './kbn_core_security_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_security_common.mdx b/api_docs/kbn_core_security_common.mdx index 0cad54309f9bb..b4ee40d4ea792 100644 --- a/api_docs/kbn_core_security_common.mdx +++ b/api_docs/kbn_core_security_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-common title: "@kbn/core-security-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-common'] --- import kbnCoreSecurityCommonObj from './kbn_core_security_common.devdocs.json'; diff --git a/api_docs/kbn_core_security_server.mdx b/api_docs/kbn_core_security_server.mdx index ac179f1ea4c61..89c6a21e46f1d 100644 --- a/api_docs/kbn_core_security_server.mdx +++ b/api_docs/kbn_core_security_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server title: "@kbn/core-security-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server'] --- import kbnCoreSecurityServerObj from './kbn_core_security_server.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_internal.mdx b/api_docs/kbn_core_security_server_internal.mdx index 4dae3f48804d6..f699b9419c16a 100644 --- a/api_docs/kbn_core_security_server_internal.mdx +++ b/api_docs/kbn_core_security_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-internal title: "@kbn/core-security-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-internal'] --- import kbnCoreSecurityServerInternalObj from './kbn_core_security_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_security_server_mocks.mdx b/api_docs/kbn_core_security_server_mocks.mdx index 21ec8acd07f01..53ec26d266192 100644 --- a/api_docs/kbn_core_security_server_mocks.mdx +++ b/api_docs/kbn_core_security_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-security-server-mocks title: "@kbn/core-security-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-security-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-security-server-mocks'] --- import kbnCoreSecurityServerMocksObj from './kbn_core_security_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 88c7ba4e9e23e..3813dc6ef452a 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 100d54f6e4879..4e9a916f10062 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index fd3dd82aa754d..d9fc03fce3a58 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index a1926e3fb486e..7e474178956a8 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index e75ab77fb3fc8..3890ac3e150a7 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index ec9eff57347c2..49861c61d7f4d 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 9608a2c90110c..4263004f2670a 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index f9d1b537e58ce..8dbc56b3c77aa 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index 2cbee006f1e5b..75e87d8876323 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 626449c698a16..58ea01f2b7db1 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index f48630a187b03..628b3bb27c601 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index f297480ed6b3a..826408bcadef2 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 34161d02910e2..cd1a9b8956761 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index e4e9dd21291f1..4128c149668e8 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index e98a69122cfba..1072f46195c57 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 3faefc8b89cf4..c28e4dd2bdb50 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index c53ffcc1bea3b..69c5aea2df7c4 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index ff54486e38222..56a57fc834f81 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index 9e6afde1a2a67..bfe847b564c1f 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 46d2ecbc68a86..0edc5cc1b32b5 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index e05b557faef7c..835c8eaef7ec1 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index bfef508232741..152527655d353 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index e9a49cba00b5f..7b28b2dfa1eed 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser.mdx b/api_docs/kbn_core_user_profile_browser.mdx index d1f14e2c46d63..96d84ea25c2b6 100644 --- a/api_docs/kbn_core_user_profile_browser.mdx +++ b/api_docs/kbn_core_user_profile_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser title: "@kbn/core-user-profile-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser'] --- import kbnCoreUserProfileBrowserObj from './kbn_core_user_profile_browser.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_internal.mdx b/api_docs/kbn_core_user_profile_browser_internal.mdx index 6eafd8e35bca7..e28980e6b7692 100644 --- a/api_docs/kbn_core_user_profile_browser_internal.mdx +++ b/api_docs/kbn_core_user_profile_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-internal title: "@kbn/core-user-profile-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-internal'] --- import kbnCoreUserProfileBrowserInternalObj from './kbn_core_user_profile_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_browser_mocks.mdx b/api_docs/kbn_core_user_profile_browser_mocks.mdx index 7485b3ebbb913..9bf57cb0bdb1c 100644 --- a/api_docs/kbn_core_user_profile_browser_mocks.mdx +++ b/api_docs/kbn_core_user_profile_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-browser-mocks title: "@kbn/core-user-profile-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-browser-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-browser-mocks'] --- import kbnCoreUserProfileBrowserMocksObj from './kbn_core_user_profile_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_common.mdx b/api_docs/kbn_core_user_profile_common.mdx index bec4a7e4c6527..e9a8a9c3a7d08 100644 --- a/api_docs/kbn_core_user_profile_common.mdx +++ b/api_docs/kbn_core_user_profile_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-common title: "@kbn/core-user-profile-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-common'] --- import kbnCoreUserProfileCommonObj from './kbn_core_user_profile_common.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server.mdx b/api_docs/kbn_core_user_profile_server.mdx index 4a08cd62b359f..cecceb3655c28 100644 --- a/api_docs/kbn_core_user_profile_server.mdx +++ b/api_docs/kbn_core_user_profile_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server title: "@kbn/core-user-profile-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server'] --- import kbnCoreUserProfileServerObj from './kbn_core_user_profile_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_internal.mdx b/api_docs/kbn_core_user_profile_server_internal.mdx index fb80b2213934b..2f528734e05a0 100644 --- a/api_docs/kbn_core_user_profile_server_internal.mdx +++ b/api_docs/kbn_core_user_profile_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-internal title: "@kbn/core-user-profile-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-internal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-internal'] --- import kbnCoreUserProfileServerInternalObj from './kbn_core_user_profile_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_profile_server_mocks.mdx b/api_docs/kbn_core_user_profile_server_mocks.mdx index 304e9c4a6129b..29753f776ee72 100644 --- a/api_docs/kbn_core_user_profile_server_mocks.mdx +++ b/api_docs/kbn_core_user_profile_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-profile-server-mocks title: "@kbn/core-user-profile-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-profile-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-profile-server-mocks'] --- import kbnCoreUserProfileServerMocksObj from './kbn_core_user_profile_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 48149a8705613..07417660c3c4d 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index e3036ccf40e2d..c1c4319a0f2e1 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 218f5ce1b4fbe..d1c514949cafd 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index f93d62ab7b860..003e92937e140 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index a604b5f7d67ba..8e7455868b938 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index 677464e163f5f..eff00f095afb7 100644 --- a/api_docs/kbn_custom_integrations.mdx +++ b/api_docs/kbn_custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-integrations title: "@kbn/custom-integrations" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-integrations plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-integrations'] --- import kbnCustomIntegrationsObj from './kbn_custom_integrations.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 9212af971bc9a..a121d601f55d1 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_forge.mdx b/api_docs/kbn_data_forge.mdx index ffe5bc0599ed1..49a18e8b4b307 100644 --- a/api_docs/kbn_data_forge.mdx +++ b/api_docs/kbn_data_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-forge title: "@kbn/data-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-forge plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-forge'] --- import kbnDataForgeObj from './kbn_data_forge.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 21167e1c0c3f9..7d28fcdb4d95a 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_data_stream_adapter.mdx b/api_docs/kbn_data_stream_adapter.mdx index a1bfc3a561eb5..cac7190a21673 100644 --- a/api_docs/kbn_data_stream_adapter.mdx +++ b/api_docs/kbn_data_stream_adapter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-stream-adapter title: "@kbn/data-stream-adapter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-stream-adapter plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-stream-adapter'] --- import kbnDataStreamAdapterObj from './kbn_data_stream_adapter.devdocs.json'; diff --git a/api_docs/kbn_data_view_utils.mdx b/api_docs/kbn_data_view_utils.mdx index 7e5d95f6a35ac..ce54d04d81fb0 100644 --- a/api_docs/kbn_data_view_utils.mdx +++ b/api_docs/kbn_data_view_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-view-utils title: "@kbn/data-view-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-view-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-view-utils'] --- import kbnDataViewUtilsObj from './kbn_data_view_utils.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 5805ff251e48b..8f47ca9d0dbb4 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index 3eaf1529882b6..d28882c2a64d6 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index 59577356c8116..8fb95b2010ac3 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_fleet.mdx b/api_docs/kbn_deeplinks_fleet.mdx index 64db325878077..1a9fa0396d110 100644 --- a/api_docs/kbn_deeplinks_fleet.mdx +++ b/api_docs/kbn_deeplinks_fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-fleet title: "@kbn/deeplinks-fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-fleet plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-fleet'] --- import kbnDeeplinksFleetObj from './kbn_deeplinks_fleet.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 1500804687668..5eb1925cdd34e 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index f54e6a8337ef7..65538c4314c50 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index 2e07fa3b3de57..5f54b3f8e5a96 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index b7e70207b1528..2e2c681598f4a 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_security.mdx b/api_docs/kbn_deeplinks_security.mdx index 3f9609d4cfd24..c06c062bea021 100644 --- a/api_docs/kbn_deeplinks_security.mdx +++ b/api_docs/kbn_deeplinks_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-security title: "@kbn/deeplinks-security" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-security plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-security'] --- import kbnDeeplinksSecurityObj from './kbn_deeplinks_security.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_shared.mdx b/api_docs/kbn_deeplinks_shared.mdx index 6431437e9e6dc..b056bc2fcb577 100644 --- a/api_docs/kbn_deeplinks_shared.mdx +++ b/api_docs/kbn_deeplinks_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-shared title: "@kbn/deeplinks-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-shared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-shared'] --- import kbnDeeplinksSharedObj from './kbn_deeplinks_shared.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 349db2ce9357d..895da54ea660e 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index 9276e1a95b531..b962ebd447c05 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 7aa84b34f6c33..860d2d119b027 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index b8da6c9a6735c..d948a75f72b80 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 067cf50c32288..1ffc1548e4fb5 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index b8f3c27df90c5..1878f0c1b6523 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 469299a27f883..7a5a18355cc4c 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index a596762acf431..87479814127ea 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 7a95ead5a80e4..162c0e50fb2c4 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 9a1f8d1f46207..0cce251902dcb 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -311,7 +311,7 @@ "label": "enterpriseSearch", "description": [], "signature": [ - "{ readonly aiSearchDoc: string; readonly aiSearchHelp: string; readonly apiKeys: string; readonly behavioralAnalytics: string; readonly behavioralAnalyticsCORS: string; readonly behavioralAnalyticsEvents: string; readonly buildConnector: string; readonly bulkApi: string; readonly configuration: string; readonly connectors: string; readonly connectorsClientDeploy: string; readonly connectorsMappings: string; readonly connectorsAzureBlobStorage: string; readonly connectorsBox: string; readonly connectorsClients: string; readonly connectorsConfluence: string; readonly connectorsContentExtraction: string; readonly connectorsDropbox: string; readonly connectorsGithub: string; readonly connectorsGoogleCloudStorage: string; readonly connectorsGoogleDrive: string; readonly connectorsGmail: string; readonly connectorsJira: string; readonly connectorsMicrosoftSQL: string; readonly connectorsMongoDB: string; readonly connectorsMySQL: string; readonly connectorsNative: string; readonly connectorsNetworkDrive: string; readonly connectorsNotion: string; readonly connectorsOneDrive: string; readonly connectorsOracle: string; readonly connectorsOutlook: string; readonly connectorsPostgreSQL: string; readonly connectorsRedis: string; readonly connectorsS3: string; readonly connectorsSalesforce: string; readonly connectorsServiceNow: string; readonly connectorsSharepoint: string; readonly connectorsSharepointOnline: string; readonly connectorsTeams: string; readonly connectorsSlack: string; readonly connectorsZoom: string; readonly crawlerExtractionRules: string; readonly crawlerManaging: string; readonly crawlerOverview: string; readonly deployTrainedModels: string; readonly documentLevelSecurity: string; readonly e5Model: string; readonly elser: string; readonly engines: string; readonly indexApi: string; readonly inferenceApiCreate: string; readonly ingestionApis: string; readonly ingestPipelines: string; readonly knnSearch: string; readonly knnSearchCombine: string; readonly languageAnalyzers: string; readonly languageClients: string; readonly licenseManagement: string; readonly machineLearningStart: string; readonly mailService: string; readonly mlDocumentEnrichment: string; readonly searchApplicationsTemplates: string; readonly searchApplicationsSearchApi: string; readonly searchApplications: string; readonly searchApplicationsSearch: string; readonly searchLabs: string; readonly searchLabsRepo: string; readonly searchTemplates: string; readonly semanticTextField: string; readonly start: string; readonly supportedNlpModels: string; readonly syncRules: string; readonly syncRulesAdvanced: string; readonly trainedModels: string; readonly textEmbedding: string; readonly troubleshootSetup: string; readonly usersAccess: string; }" + "{ readonly aiSearchDoc: string; readonly aiSearchHelp: string; readonly apiKeys: string; readonly behavioralAnalytics: string; readonly behavioralAnalyticsCORS: string; readonly behavioralAnalyticsEvents: string; readonly buildConnector: string; readonly bulkApi: string; readonly configuration: string; readonly connectors: string; readonly connectorsClientDeploy: string; readonly connectorsMappings: string; readonly connectorsAzureBlobStorage: string; readonly connectorsBox: string; readonly connectorsClients: string; readonly connectorsConfluence: string; readonly connectorsContentExtraction: string; readonly connectorsDropbox: string; readonly connectorsGithub: string; readonly connectorsGoogleCloudStorage: string; readonly connectorsGoogleDrive: string; readonly connectorsGmail: string; readonly connectorsJira: string; readonly connectorsMicrosoftSQL: string; readonly connectorsMongoDB: string; readonly connectorsMySQL: string; readonly connectorsNative: string; readonly connectorsNetworkDrive: string; readonly connectorsNotion: string; readonly connectorsOneDrive: string; readonly connectorsOracle: string; readonly connectorsOutlook: string; readonly connectorsPostgreSQL: string; readonly connectorsRedis: string; readonly connectorsS3: string; readonly connectorsSalesforce: string; readonly connectorsServiceNow: string; readonly connectorsSharepoint: string; readonly connectorsSharepointOnline: string; readonly connectorsTeams: string; readonly connectorsSlack: string; readonly connectorsZoom: string; readonly crawlerExtractionRules: string; readonly crawlerManaging: string; readonly crawlerOverview: string; readonly deployTrainedModels: string; readonly documentLevelSecurity: string; readonly e5Model: string; readonly elser: string; readonly engines: string; readonly indexApi: string; readonly inferenceApiCreate: string; readonly ingestionApis: string; readonly ingestPipelines: string; readonly knnSearch: string; readonly knnSearchCombine: string; readonly languageAnalyzers: string; readonly languageClients: string; readonly licenseManagement: string; readonly machineLearningStart: string; readonly mailService: string; readonly mlDocumentEnrichment: string; readonly searchApplicationsTemplates: string; readonly searchApplicationsSearchApi: string; readonly searchApplications: string; readonly searchApplicationsSearch: string; readonly searchLabs: string; readonly searchLabsRepo: string; readonly semanticSearch: string; readonly searchTemplates: string; readonly semanticTextField: string; readonly start: string; readonly supportedNlpModels: string; readonly syncRules: string; readonly syncRulesAdvanced: string; readonly trainedModels: string; readonly textEmbedding: string; readonly troubleshootSetup: string; readonly usersAccess: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index ee498608d2209..db67e56edcfb2 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index e62c0b9373c89..825cbd95382f8 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index ffa77e1f7dd5c..bded84b1c24ed 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 2bfb045edce81..7c9ee51f58075 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 17566b5944544..7e929d52a9aed 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index 30f95b20fa2e5..c0ca1dd6696f5 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 71c2b8647a109..fc0dcad51b1de 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant_common.mdx b/api_docs/kbn_elastic_assistant_common.mdx index 1b8d8f913afab..14e005b36a80c 100644 --- a/api_docs/kbn_elastic_assistant_common.mdx +++ b/api_docs/kbn_elastic_assistant_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant-common title: "@kbn/elastic-assistant-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_entities_schema.mdx b/api_docs/kbn_entities_schema.mdx index 35421c0749a3b..9b2e95795cf82 100644 --- a/api_docs/kbn_entities_schema.mdx +++ b/api_docs/kbn_entities_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-entities-schema title: "@kbn/entities-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/entities-schema plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/entities-schema'] --- import kbnEntitiesSchemaObj from './kbn_entities_schema.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index e703e9b694d51..a49320c529c43 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 2108e48b5b031..d642226833101 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index 3363b0668d89a..0ae7ba903cada 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index 31e15a6861754..2fdd0fdb88fbd 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 37ab340f947f5..b32a8b4381b00 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 77819091456f9..96da413c58f2b 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_esql_ast.mdx b/api_docs/kbn_esql_ast.mdx index da77090b5eba1..fe54780c3baf2 100644 --- a/api_docs/kbn_esql_ast.mdx +++ b/api_docs/kbn_esql_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-ast title: "@kbn/esql-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-ast plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-ast'] --- import kbnEsqlAstObj from './kbn_esql_ast.devdocs.json'; diff --git a/api_docs/kbn_esql_utils.mdx b/api_docs/kbn_esql_utils.mdx index 3a12e57cf17f7..d1662fb612e5b 100644 --- a/api_docs/kbn_esql_utils.mdx +++ b/api_docs/kbn_esql_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-utils title: "@kbn/esql-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_esql_validation_autocomplete.devdocs.json b/api_docs/kbn_esql_validation_autocomplete.devdocs.json index bee047bed7c0e..89c335334053a 100644 --- a/api_docs/kbn_esql_validation_autocomplete.devdocs.json +++ b/api_docs/kbn_esql_validation_autocomplete.devdocs.json @@ -1536,7 +1536,9 @@ "section": "def-common.ESQLCallbacks", "text": "ESQLCallbacks" }, - " | undefined) => () => Promise<{ name: string; hidden: boolean; title?: string | undefined; dataStreams?: { name: string; title?: string | undefined; }[] | undefined; type?: string | undefined; }[]>" + " | undefined) => () => Promise<", + "ESQLSourceResult", + "[]>" ], "path": "packages/kbn-esql-validation-autocomplete/src/shared/resources_helpers.ts", "deprecated": false, @@ -3054,7 +3056,9 @@ "label": "getSources", "description": [], "signature": [ - "CallbackFn<{}, { name: string; hidden: boolean; title?: string | undefined; dataStreams?: { name: string; title?: string | undefined; }[] | undefined; type?: string | undefined; }> | undefined" + "CallbackFn<{}, ", + "ESQLSourceResult", + "> | undefined" ], "path": "packages/kbn-esql-validation-autocomplete/src/shared/types.ts", "deprecated": false, diff --git a/api_docs/kbn_esql_validation_autocomplete.mdx b/api_docs/kbn_esql_validation_autocomplete.mdx index a48b6490d981a..fdef952d49bc4 100644 --- a/api_docs/kbn_esql_validation_autocomplete.mdx +++ b/api_docs/kbn_esql_validation_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-esql-validation-autocomplete title: "@kbn/esql-validation-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/esql-validation-autocomplete plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-validation-autocomplete'] --- import kbnEsqlValidationAutocompleteObj from './kbn_esql_validation_autocomplete.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 197 | 0 | 185 | 10 | +| 197 | 0 | 185 | 11 | ## Common diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 77353cf843f43..e7532bd3827c2 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index 2eac9dde1a696..905c5fff291bc 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.devdocs.json b/api_docs/kbn_expandable_flyout.devdocs.json index e460fcf5387c3..a1b9164f7efb7 100644 --- a/api_docs/kbn_expandable_flyout.devdocs.json +++ b/api_docs/kbn_expandable_flyout.devdocs.json @@ -130,8 +130,8 @@ "pluginId": "@kbn/expandable-flyout", "scope": "public", "docId": "kibKbnExpandableFlyoutPluginApi", - "section": "def-public.FlyoutState", - "text": "FlyoutState" + "section": "def-public.FlyoutPanels", + "text": "FlyoutPanels" } ], "path": "packages/kbn-expandable-flyout/src/hooks/use_expandable_flyout_state.ts", @@ -745,18 +745,18 @@ }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-public.FlyoutState", + "id": "def-public.FlyoutPanels", "type": "Interface", "tags": [], - "label": "FlyoutState", + "label": "FlyoutPanels", "description": [], - "path": "packages/kbn-expandable-flyout/src/state.ts", + "path": "packages/kbn-expandable-flyout/src/store/state.ts", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-public.FlyoutState.left", + "id": "def-public.FlyoutPanels.left", "type": "Object", "tags": [], "label": "left", @@ -773,13 +773,13 @@ }, " | undefined" ], - "path": "packages/kbn-expandable-flyout/src/state.ts", + "path": "packages/kbn-expandable-flyout/src/store/state.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-public.FlyoutState.right", + "id": "def-public.FlyoutPanels.right", "type": "Object", "tags": [], "label": "right", @@ -796,13 +796,13 @@ }, " | undefined" ], - "path": "packages/kbn-expandable-flyout/src/state.ts", + "path": "packages/kbn-expandable-flyout/src/store/state.ts", "deprecated": false, "trackAdoption": false }, { "parentPluginId": "@kbn/expandable-flyout", - "id": "def-public.FlyoutState.preview", + "id": "def-public.FlyoutPanels.preview", "type": "Array", "tags": [], "label": "preview", @@ -819,7 +819,7 @@ }, "[] | undefined" ], - "path": "packages/kbn-expandable-flyout/src/state.ts", + "path": "packages/kbn-expandable-flyout/src/store/state.ts", "deprecated": false, "trackAdoption": false } diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index d9cfbb36b0817..6fc378cdb2ea7 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 4a227628e34ca..c3e126e8cb90d 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 2dd8c3122dcff..5e086a612d494 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 0f78820dedcf7..295e42dfb1a27 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_formatters.mdx b/api_docs/kbn_formatters.mdx index 1312f6127e8ad..1ca04804f3d0b 100644 --- a/api_docs/kbn_formatters.mdx +++ b/api_docs/kbn_formatters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-formatters title: "@kbn/formatters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/formatters plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/formatters'] --- import kbnFormattersObj from './kbn_formatters.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.devdocs.json b/api_docs/kbn_ftr_common_functional_services.devdocs.json index 9c02c7376aba2..b24cbd1852db8 100644 --- a/api_docs/kbn_ftr_common_functional_services.devdocs.json +++ b/api_docs/kbn_ftr_common_functional_services.devdocs.json @@ -803,7 +803,15 @@ "\nUse to retry block {options.retryCount} times within {options.timeout} period and return block result" ], "signature": [ - "(description: string, block: () => Promise, options: TryWithRetriesOptions, onFailureBlock?: (() => Promise) | undefined) => Promise" + "(description: string, block: () => Promise, options: ", + { + "pluginId": "@kbn/ftr-common-functional-services", + "scope": "common", + "docId": "kibKbnFtrCommonFunctionalServicesPluginApi", + "section": "def-common.TryWithRetriesOptions", + "text": "TryWithRetriesOptions" + }, + ", onFailureBlock?: (() => Promise) | undefined) => Promise" ], "path": "packages/kbn-ftr-common-functional-services/services/retry/retry.ts", "deprecated": false, @@ -853,7 +861,13 @@ "options.retryCount for how many attempts to retry" ], "signature": [ - "TryWithRetriesOptions" + { + "pluginId": "@kbn/ftr-common-functional-services", + "scope": "common", + "docId": "kibKbnFtrCommonFunctionalServicesPluginApi", + "section": "def-common.TryWithRetriesOptions", + "text": "TryWithRetriesOptions" + } ], "path": "packages/kbn-ftr-common-functional-services/services/retry/retry.ts", "deprecated": false, @@ -1314,6 +1328,59 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ftr-common-functional-services", + "id": "def-common.TryWithRetriesOptions", + "type": "Interface", + "tags": [], + "label": "TryWithRetriesOptions", + "description": [], + "path": "packages/kbn-ftr-common-functional-services/services/retry/retry.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ftr-common-functional-services", + "id": "def-common.TryWithRetriesOptions.retryCount", + "type": "number", + "tags": [], + "label": "retryCount", + "description": [], + "path": "packages/kbn-ftr-common-functional-services/services/retry/retry.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ftr-common-functional-services", + "id": "def-common.TryWithRetriesOptions.retryDelay", + "type": "number", + "tags": [], + "label": "retryDelay", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-ftr-common-functional-services/services/retry/retry.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ftr-common-functional-services", + "id": "def-common.TryWithRetriesOptions.timeout", + "type": "number", + "tags": [], + "label": "timeout", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/kbn-ftr-common-functional-services/services/retry/retry.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false } ], "enums": [], diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 00e605cbd1cb2..2ac3275610645 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kiban | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 102 | 0 | 77 | 1 | +| 106 | 0 | 81 | 1 | ## Common diff --git a/api_docs/kbn_ftr_common_functional_ui_services.mdx b/api_docs/kbn_ftr_common_functional_ui_services.mdx index e35fdff8de817..6b030440e2dc2 100644 --- a/api_docs/kbn_ftr_common_functional_ui_services.mdx +++ b/api_docs/kbn_ftr_common_functional_ui_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-ui-services title: "@kbn/ftr-common-functional-ui-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-ui-services plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-ui-services'] --- import kbnFtrCommonFunctionalUiServicesObj from './kbn_ftr_common_functional_ui_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index fbb6d8439fb62..26efa35838e33 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index 213f59efa659d..f7ca67eecb6ab 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index e916f3560b56f..daa11f42385d0 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_grid_layout.mdx b/api_docs/kbn_grid_layout.mdx index c6cc93b6159ee..0a3c92f507c05 100644 --- a/api_docs/kbn_grid_layout.mdx +++ b/api_docs/kbn_grid_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grid-layout title: "@kbn/grid-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grid-layout plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grid-layout'] --- import kbnGridLayoutObj from './kbn_grid_layout.devdocs.json'; diff --git a/api_docs/kbn_grouping.mdx b/api_docs/kbn_grouping.mdx index e602598f63a0e..5a8c4686215b8 100644 --- a/api_docs/kbn_grouping.mdx +++ b/api_docs/kbn_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-grouping title: "@kbn/grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/grouping plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/grouping'] --- import kbnGroupingObj from './kbn_grouping.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 65a9aa587bd9d..ceee7ad2e7345 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 8d42345f95696..c5f6ee2e73dc5 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 3d83727c3f1b7..9c459318cd35b 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 591503b456224..c6ee8ca9d0852 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index b801b78e1773d..ef8629485ba20 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index ce1b27ca9ebb3..abf65bfcaace1 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 82b14c1802a2b..301672e1deb24 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index c3f0240347fa6..aee0217ec16c4 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index fb74e7b5c33fa..9504a1f22fe03 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_index_management_shared_types.mdx b/api_docs/kbn_index_management_shared_types.mdx index c2e5fa6b96aca..3f17151c21cd4 100644 --- a/api_docs/kbn_index_management_shared_types.mdx +++ b/api_docs/kbn_index_management_shared_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-index-management-shared-types title: "@kbn/index-management-shared-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/index-management-shared-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/index-management-shared-types'] --- import kbnIndexManagementSharedTypesObj from './kbn_index_management_shared_types.devdocs.json'; diff --git a/api_docs/kbn_inference_integration_flyout.mdx b/api_docs/kbn_inference_integration_flyout.mdx index 0f9da046e6563..be1ef8e3cb101 100644 --- a/api_docs/kbn_inference_integration_flyout.mdx +++ b/api_docs/kbn_inference_integration_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-inference_integration_flyout title: "@kbn/inference_integration_flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/inference_integration_flyout plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/inference_integration_flyout'] --- import kbnInferenceIntegrationFlyoutObj from './kbn_inference_integration_flyout.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index b2f3b84caba44..c0795f82e7076 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 49fdc2f56129b..f2f3e92223800 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_investigation_shared.devdocs.json b/api_docs/kbn_investigation_shared.devdocs.json index 8b23840009fb8..79431d4fb12e6 100644 --- a/api_docs/kbn_investigation_shared.devdocs.json +++ b/api_docs/kbn_investigation_shared.devdocs.json @@ -45,7 +45,7 @@ "label": "CreateInvestigationItemResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/create_item.ts", "deprecated": false, @@ -75,7 +75,7 @@ "label": "CreateInvestigationNoteResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; content: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/create_note.ts", "deprecated": false, @@ -105,7 +105,7 @@ "label": "CreateInvestigationResponse", "description": [], "signature": [ - "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }" + "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/create.ts", "deprecated": false, @@ -165,7 +165,7 @@ "label": "FindInvestigationsParams", "description": [], "signature": [ - "{ page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; } | undefined" + "{ page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; } | undefined" ], "path": "packages/kbn-investigation-shared/src/rest_specs/find.ts", "deprecated": false, @@ -180,13 +180,43 @@ "label": "FindInvestigationsResponse", "description": [], "signature": [ - "{ page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }[]; perPage: number; total: number; }" + "{ page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }[]; perPage: number; total: number; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/find.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.GetAllInvestigationStatsResponse", + "type": "Type", + "tags": [], + "label": "GetAllInvestigationStatsResponse", + "description": [], + "signature": [ + "{ count: Partial>; total: number; }" + ], + "path": "packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.GetAllInvestigationTagsResponse", + "type": "Type", + "tags": [], + "label": "GetAllInvestigationTagsResponse", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/investigation-shared", "id": "def-common.GetInvestigationItemsResponse", @@ -195,7 +225,7 @@ "label": "GetInvestigationItemsResponse", "description": [], "signature": [ - "({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]" + "({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]" ], "path": "packages/kbn-investigation-shared/src/rest_specs/get_items.ts", "deprecated": false, @@ -210,7 +240,7 @@ "label": "GetInvestigationNotesResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; content: string; }[]" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]" ], "path": "packages/kbn-investigation-shared/src/rest_specs/get_notes.ts", "deprecated": false, @@ -240,7 +270,7 @@ "label": "GetInvestigationResponse", "description": [], "signature": [ - "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }" + "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/get.ts", "deprecated": false, @@ -255,7 +285,7 @@ "label": "InvestigationItem", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; }" ], "path": "packages/kbn-investigation-shared/src/schema/investigation_item.ts", "deprecated": false, @@ -270,7 +300,7 @@ "label": "InvestigationItemResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/investigation_item.ts", "deprecated": false, @@ -285,7 +315,7 @@ "label": "InvestigationNoteResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; content: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/investigation_note.ts", "deprecated": false, @@ -300,7 +330,7 @@ "label": "InvestigationResponse", "description": [], "signature": [ - "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }" + "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/investigation.ts", "deprecated": false, @@ -322,6 +352,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.Status", + "type": "Type", + "tags": [], + "label": "Status", + "description": [], + "signature": [ + "\"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"" + ], + "path": "packages/kbn-investigation-shared/src/schema/investigation.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/investigation-shared", "id": "def-common.UpdateInvestigationItemParams", @@ -345,7 +390,7 @@ "label": "UpdateInvestigationItemResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/update_item.ts", "deprecated": false, @@ -375,7 +420,7 @@ "label": "UpdateInvestigationNoteResponse", "description": [], "signature": [ - "{ id: string; createdBy: string; createdAt: number; content: string; }" + "{ id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/update_note.ts", "deprecated": false, @@ -405,7 +450,7 @@ "label": "UpdateInvestigationResponse", "description": [], "signature": [ - "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }" + "{ params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }" ], "path": "packages/kbn-investigation-shared/src/rest_specs/update.ts", "deprecated": false, @@ -467,7 +512,7 @@ "label": "createInvestigationItemResponseSchema", "description": [], "signature": [ - "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" + "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/create_item.ts", "deprecated": false, @@ -497,7 +542,7 @@ "label": "createInvestigationNoteResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; content: string; }>" + "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; updatedAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/create_note.ts", "deprecated": false, @@ -527,7 +572,7 @@ "label": "createInvestigationResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }>" + "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; updatedAt: Zod.ZodNumber; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/create.ts", "deprecated": false, @@ -587,7 +632,7 @@ "label": "findInvestigationsParamsSchema", "description": [], "signature": [ - "Zod.ZodObject<{ query: Zod.ZodOptional; page: Zod.ZodOptional; perPage: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; }, { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { query?: { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; } | undefined; }, { query?: { page?: string | undefined; perPage?: string | undefined; alertId?: string | undefined; } | undefined; }>" + "Zod.ZodObject<{ query: Zod.ZodOptional; search: Zod.ZodOptional; filter: Zod.ZodOptional; page: Zod.ZodOptional; perPage: Zod.ZodOptional; }, \"strip\", Zod.ZodTypeAny, { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; }, { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; }>>; }, \"strip\", Zod.ZodTypeAny, { query?: { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; } | undefined; }, { query?: { page?: number | undefined; filter?: string | undefined; search?: string | undefined; perPage?: number | undefined; alertId?: string | undefined; } | undefined; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/find.ts", "deprecated": false, @@ -602,13 +647,73 @@ "label": "findInvestigationsResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ page: Zod.ZodNumber; perPage: Zod.ZodNumber; total: Zod.ZodNumber; results: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }[]; perPage: number; total: number; }, { page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }[]; perPage: number; total: number; }>" + "Zod.ZodObject<{ page: Zod.ZodNumber; perPage: Zod.ZodNumber; total: Zod.ZodNumber; results: Zod.ZodArray; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }[]; perPage: number; total: number; }, { page: number; results: { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }[]; perPage: number; total: number; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/find.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.getAllInvestigationStatsParamsSchema", + "type": "Object", + "tags": [], + "label": "getAllInvestigationStatsParamsSchema", + "description": [], + "signature": [ + "Zod.ZodObject<{ query: Zod.ZodObject<{}, \"strip\", Zod.ZodTypeAny, {}, {}>; }, \"strip\", Zod.ZodTypeAny, { query: {}; }, { query: {}; }>" + ], + "path": "packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.getAllInvestigationStatsResponseSchema", + "type": "Object", + "tags": [], + "label": "getAllInvestigationStatsResponseSchema", + "description": [], + "signature": [ + "Zod.ZodObject<{ count: Zod.ZodRecord, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>, Zod.ZodNumber>; total: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { count: Partial>; total: number; }, { count: Partial>; total: number; }>" + ], + "path": "packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_stats.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.getAllInvestigationTagsParamsSchema", + "type": "Object", + "tags": [], + "label": "getAllInvestigationTagsParamsSchema", + "description": [], + "signature": [ + "Zod.ZodObject<{ query: Zod.ZodObject<{}, \"strip\", Zod.ZodTypeAny, {}, {}>; }, \"strip\", Zod.ZodTypeAny, { query: {}; }, { query: {}; }>" + ], + "path": "packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/investigation-shared", + "id": "def-common.getAllInvestigationTagsResponseSchema", + "type": "Object", + "tags": [], + "label": "getAllInvestigationTagsResponseSchema", + "description": [], + "signature": [ + "Zod.ZodArray" + ], + "path": "packages/kbn-investigation-shared/src/rest_specs/get_all_investigation_tags.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/investigation-shared", "id": "def-common.getInvestigationItemsParamsSchema", @@ -632,7 +737,7 @@ "label": "getInvestigationItemsResponseSchema", "description": [], "signature": [ - "Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">" + "Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">" ], "path": "packages/kbn-investigation-shared/src/rest_specs/get_items.ts", "deprecated": false, @@ -662,7 +767,7 @@ "label": "getInvestigationNotesResponseSchema", "description": [], "signature": [ - "Zod.ZodArray, \"many\">" + "Zod.ZodArray, \"many\">" ], "path": "packages/kbn-investigation-shared/src/rest_specs/get_notes.ts", "deprecated": false, @@ -692,7 +797,7 @@ "label": "getInvestigationResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }>" + "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; updatedAt: Zod.ZodNumber; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/get.ts", "deprecated": false, @@ -707,7 +812,7 @@ "label": "investigationItemResponseSchema", "description": [], "signature": [ - "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" + "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/investigation_item.ts", "deprecated": false, @@ -722,7 +827,7 @@ "label": "investigationItemSchema", "description": [], "signature": [ - "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" + "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" ], "path": "packages/kbn-investigation-shared/src/schema/investigation_item.ts", "deprecated": false, @@ -737,7 +842,7 @@ "label": "investigationNoteResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; content: string; }>" + "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; updatedAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/investigation_note.ts", "deprecated": false, @@ -752,7 +857,7 @@ "label": "investigationNoteSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; content: string; }>" + "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; updatedAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }>" ], "path": "packages/kbn-investigation-shared/src/schema/investigation_note.ts", "deprecated": false, @@ -767,7 +872,7 @@ "label": "investigationResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }>" + "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; updatedAt: Zod.ZodNumber; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/investigation.ts", "deprecated": false, @@ -782,7 +887,7 @@ "label": "investigationSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }>" + "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; updatedAt: Zod.ZodNumber; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }>" ], "path": "packages/kbn-investigation-shared/src/schema/investigation.ts", "deprecated": false, @@ -842,7 +947,7 @@ "label": "updateInvestigationItemResponseSchema", "description": [], "signature": [ - "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" + "Zod.ZodIntersection, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/update_item.ts", "deprecated": false, @@ -872,7 +977,7 @@ "label": "updateInvestigationNoteResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; content: string; }>" + "Zod.ZodObject<{ id: Zod.ZodString; content: Zod.ZodString; createdAt: Zod.ZodNumber; updatedAt: Zod.ZodNumber; createdBy: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }, { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/update_note.ts", "deprecated": false, @@ -902,7 +1007,7 @@ "label": "updateInvestigationResponseSchema", "description": [], "signature": [ - "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; content: string; }[]; }>" + "Zod.ZodObject<{ id: Zod.ZodString; title: Zod.ZodString; createdAt: Zod.ZodNumber; createdBy: Zod.ZodString; updatedAt: Zod.ZodNumber; params: Zod.ZodObject<{ timeRange: Zod.ZodObject<{ from: Zod.ZodNumber; to: Zod.ZodNumber; }, \"strip\", Zod.ZodTypeAny, { from: number; to: number; }, { from: number; to: number; }>; }, \"strip\", Zod.ZodTypeAny, { timeRange: { from: number; to: number; }; }, { timeRange: { from: number; to: number; }; }>; origin: Zod.ZodUnion<[Zod.ZodObject<{ type: Zod.ZodLiteral<\"alert\">; id: Zod.ZodString; }, \"strip\", Zod.ZodTypeAny, { id: string; type: \"alert\"; }, { id: string; type: \"alert\"; }>, Zod.ZodObject<{ type: Zod.ZodLiteral<\"blank\">; }, \"strip\", Zod.ZodTypeAny, { type: \"blank\"; }, { type: \"blank\"; }>]>; status: Zod.ZodUnion<[Zod.ZodLiteral<\"triage\">, Zod.ZodLiteral<\"active\">, Zod.ZodLiteral<\"mitigated\">, Zod.ZodLiteral<\"resolved\">, Zod.ZodLiteral<\"cancelled\">]>; tags: Zod.ZodArray; notes: Zod.ZodArray, \"many\">; items: Zod.ZodArray, Zod.ZodObject<{ title: Zod.ZodString; type: Zod.ZodString; params: Zod.ZodRecord; }, \"strip\", Zod.ZodTypeAny, { params: Record; type: string; title: string; }, { params: Record; type: string; title: string; }>>, \"many\">; }, \"strip\", Zod.ZodTypeAny, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }, { params: { timeRange: { from: number; to: number; }; }; id: string; tags: string[]; title: string; createdBy: string; createdAt: number; updatedAt: number; status: \"active\" | \"triage\" | \"mitigated\" | \"resolved\" | \"cancelled\"; items: ({ id: string; createdBy: string; createdAt: number; updatedAt: number; } & { params: Record; type: string; title: string; })[]; origin: { id: string; type: \"alert\"; } | { type: \"blank\"; }; notes: { id: string; createdBy: string; createdAt: number; updatedAt: number; content: string; }[]; }>" ], "path": "packages/kbn-investigation-shared/src/rest_specs/update.ts", "deprecated": false, diff --git a/api_docs/kbn_investigation_shared.mdx b/api_docs/kbn_investigation_shared.mdx index 0caaa8fe89cf6..259634a2d9c12 100644 --- a/api_docs/kbn_investigation_shared.mdx +++ b/api_docs/kbn_investigation_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-investigation-shared title: "@kbn/investigation-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/investigation-shared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/investigation-shared'] --- import kbnInvestigationSharedObj from './kbn_investigation_shared.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 59 | 0 | 59 | 0 | +| 66 | 0 | 66 | 0 | ## Common diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index a9dea8305f8eb..b342089867903 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_ipynb.mdx b/api_docs/kbn_ipynb.mdx index deaad141f0c2e..91428bdd0bcb6 100644 --- a/api_docs/kbn_ipynb.mdx +++ b/api_docs/kbn_ipynb.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ipynb title: "@kbn/ipynb" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ipynb plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ipynb'] --- import kbnIpynbObj from './kbn_ipynb.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index d85e843c6fc6c..62c523cbe1fce 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 2a6962324f0d4..4a0992b1e27a1 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 332d3d181d4c6..465b1cda48017 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_json_schemas.mdx b/api_docs/kbn_json_schemas.mdx index 2ad6968cf1132..5e3c51b7172f2 100644 --- a/api_docs/kbn_json_schemas.mdx +++ b/api_docs/kbn_json_schemas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-schemas title: "@kbn/json-schemas" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-schemas plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-schemas'] --- import kbnJsonSchemasObj from './kbn_json_schemas.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index d200858245a7b..5253e75a130b2 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index 11a0f3de4d53f..f98a92255c6a4 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index 0a89f170ef611..8dbb197be9c8e 100644 --- a/api_docs/kbn_lens_embeddable_utils.mdx +++ b/api_docs/kbn_lens_embeddable_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-embeddable-utils title: "@kbn/lens-embeddable-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-embeddable-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_lens_formula_docs.mdx b/api_docs/kbn_lens_formula_docs.mdx index eb2321fd7f55d..543f819a55601 100644 --- a/api_docs/kbn_lens_formula_docs.mdx +++ b/api_docs/kbn_lens_formula_docs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-lens-formula-docs title: "@kbn/lens-formula-docs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/lens-formula-docs plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-formula-docs'] --- import kbnLensFormulaDocsObj from './kbn_lens_formula_docs.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 323fbb620cd0d..ad423d27ce94b 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index f9fde99a5b430..0b6f2eee87670 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_content_badge.mdx b/api_docs/kbn_managed_content_badge.mdx index 0e9b167ecb9e5..816b42f2f1e1e 100644 --- a/api_docs/kbn_managed_content_badge.mdx +++ b/api_docs/kbn_managed_content_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-content-badge title: "@kbn/managed-content-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-content-badge plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-content-badge'] --- import kbnManagedContentBadgeObj from './kbn_managed_content_badge.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 5be29cc83b7b0..705063b8f87a7 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index 1b422b93b8af7..1f905d1a42f0a 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index eb28ad73f8c56..cd6b4663ef349 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index 5bf3574beb174..0f18e1dfb8f55 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index b48fabc78bea7..525b840430f9e 100644 --- a/api_docs/kbn_management_settings_components_field_input.mdx +++ b/api_docs/kbn_management_settings_components_field_input.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-input title: "@kbn/management-settings-components-field-input" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-input plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-input'] --- import kbnManagementSettingsComponentsFieldInputObj from './kbn_management_settings_components_field_input.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_row.mdx b/api_docs/kbn_management_settings_components_field_row.mdx index 223a64e7a982e..8c3dbd31ed439 100644 --- a/api_docs/kbn_management_settings_components_field_row.mdx +++ b/api_docs/kbn_management_settings_components_field_row.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-row title: "@kbn/management-settings-components-field-row" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-row plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index d66a64f9e150e..09d69f4df27b1 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index ce9e90da1f9b1..5913dc6094119 100644 --- a/api_docs/kbn_management_settings_field_definition.mdx +++ b/api_docs/kbn_management_settings_field_definition.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-field-definition title: "@kbn/management-settings-field-definition" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-field-definition plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-field-definition'] --- import kbnManagementSettingsFieldDefinitionObj from './kbn_management_settings_field_definition.devdocs.json'; diff --git a/api_docs/kbn_management_settings_ids.devdocs.json b/api_docs/kbn_management_settings_ids.devdocs.json index 02da2b2d9b18f..6295c9949a986 100644 --- a/api_docs/kbn_management_settings_ids.devdocs.json +++ b/api_docs/kbn_management_settings_ids.devdocs.json @@ -1507,6 +1507,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/management-settings-ids", + "id": "def-common.OBSERVABILITY_SEARCH_EXCLUDED_DATA_TIERS", + "type": "string", + "tags": [], + "label": "OBSERVABILITY_SEARCH_EXCLUDED_DATA_TIERS", + "description": [], + "signature": [ + "\"observability:searchExcludedDataTiers\"" + ], + "path": "packages/kbn-management/settings/setting_ids/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/management-settings-ids", "id": "def-common.QUERY_ALLOW_LEADING_WILDCARDS_ID", diff --git a/api_docs/kbn_management_settings_ids.mdx b/api_docs/kbn_management_settings_ids.mdx index 492de46c2a79d..dc873e9d4af7c 100644 --- a/api_docs/kbn_management_settings_ids.mdx +++ b/api_docs/kbn_management_settings_ids.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-ids title: "@kbn/management-settings-ids" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-ids plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 142 | 0 | 140 | 0 | +| 143 | 0 | 141 | 0 | ## Common diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index 13a136a5652ce..0e74dfbb1aa42 100644 --- a/api_docs/kbn_management_settings_section_registry.mdx +++ b/api_docs/kbn_management_settings_section_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-section-registry title: "@kbn/management-settings-section-registry" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-section-registry plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-section-registry'] --- import kbnManagementSettingsSectionRegistryObj from './kbn_management_settings_section_registry.devdocs.json'; diff --git a/api_docs/kbn_management_settings_types.mdx b/api_docs/kbn_management_settings_types.mdx index 39c080fda374d..5a6311557955c 100644 --- a/api_docs/kbn_management_settings_types.mdx +++ b/api_docs/kbn_management_settings_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-types title: "@kbn/management-settings-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-types'] --- import kbnManagementSettingsTypesObj from './kbn_management_settings_types.devdocs.json'; diff --git a/api_docs/kbn_management_settings_utilities.mdx b/api_docs/kbn_management_settings_utilities.mdx index 1d41a8bfc7a92..2e27a69862b3c 100644 --- a/api_docs/kbn_management_settings_utilities.mdx +++ b/api_docs/kbn_management_settings_utilities.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-utilities title: "@kbn/management-settings-utilities" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-utilities plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-utilities'] --- import kbnManagementSettingsUtilitiesObj from './kbn_management_settings_utilities.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index 30f01d1d0e610..9d48f422340fe 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index eddd72eb11629..9da665fdf7fa2 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; -Contact [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) for questions regarding this plugin. +Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 5e8af4ac2d3b0..fdc0278b939e7 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; -Contact [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) for questions regarding this plugin. +Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 5b4c8c8217aed..94d32bc4b0591 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index 48f3a90ab2cd8..31a87e3302cc1 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_cancellable_search.mdx b/api_docs/kbn_ml_cancellable_search.mdx index ee45572011f0c..71234e591beeb 100644 --- a/api_docs/kbn_ml_cancellable_search.mdx +++ b/api_docs/kbn_ml_cancellable_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-cancellable-search title: "@kbn/ml-cancellable-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-cancellable-search plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-cancellable-search'] --- import kbnMlCancellableSearchObj from './kbn_ml_cancellable_search.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 189e40899f8a7..4a572e44ddf3d 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index c66a71c49f67e..7ffb4dd89045f 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 42eea620e6cda..6fcf2c9dbe27a 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index c931d65721bcb..9a982eb1d177f 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 4a9c95912a1aa..7d59d7b0e51fb 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index cdf02bab8c97a..4720106350b26 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index d665e70b910b5..5009332f934d9 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index e28964fbe66bb..a8eb320df44b2 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 0d263d4ab2fce..428995533ae80 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index 200c8e651e0fa..8e88b8d9b00ce 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 46c4ff9e5b04a..b9368bd0f2e5a 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 7190e5d9a8229..3d8fed1c892de 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 57329a3f1996f..bca29edf6f272 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index 2474fb2c29454..75c02ebefba79 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 604d2572910eb..a1191402b2e7f 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index 18c8a38fb03c0..da355ca120a9c 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index 82f2f994b6cf1..76658ba429aa4 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index be1808d91984d..4cf7592fcd58f 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 8a4449686ae93..5fc0a63322f30 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_time_buckets.mdx b/api_docs/kbn_ml_time_buckets.mdx index aeb7548359519..4e5ab3538e32c 100644 --- a/api_docs/kbn_ml_time_buckets.mdx +++ b/api_docs/kbn_ml_time_buckets.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-time-buckets title: "@kbn/ml-time-buckets" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-time-buckets plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-time-buckets'] --- import kbnMlTimeBucketsObj from './kbn_ml_time_buckets.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index a4b4e37615524..6c863e47813ef 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx index 4fb35f53e2c26..6422569c82a5d 100644 --- a/api_docs/kbn_ml_ui_actions.mdx +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-ui-actions title: "@kbn/ml-ui-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-ui-actions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] --- import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 8cc5eeb77c13c..dd05b910f1f27 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index 594a780321cd2..00c2b34d4bc07 100644 --- a/api_docs/kbn_mock_idp_utils.mdx +++ b/api_docs/kbn_mock_idp_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mock-idp-utils title: "@kbn/mock-idp-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mock-idp-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mock-idp-utils'] --- import kbnMockIdpUtilsObj from './kbn_mock_idp_utils.devdocs.json'; diff --git a/api_docs/kbn_monaco.devdocs.json b/api_docs/kbn_monaco.devdocs.json index 50ee211f14029..73ffb0419efb9 100644 --- a/api_docs/kbn_monaco.devdocs.json +++ b/api_docs/kbn_monaco.devdocs.json @@ -482,7 +482,9 @@ "label": "getSources", "description": [], "signature": [ - "CallbackFn<{}, { name: string; hidden: boolean; title?: string | undefined; dataStreams?: { name: string; title?: string | undefined; }[] | undefined; type?: string | undefined; }> | undefined" + "CallbackFn<{}, ", + "ESQLSourceResult", + "> | undefined" ], "path": "packages/kbn-esql-validation-autocomplete/src/shared/types.ts", "deprecated": false, diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 010aac44acb67..3da4e1953520c 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 8367646437d74..cddccdfeb49f0 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_object_versioning_utils.mdx b/api_docs/kbn_object_versioning_utils.mdx index d1f67b43f75c9..6109a3cb55e5d 100644 --- a/api_docs/kbn_object_versioning_utils.mdx +++ b/api_docs/kbn_object_versioning_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning-utils title: "@kbn/object-versioning-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning-utils'] --- import kbnObjectVersioningUtilsObj from './kbn_object_versioning_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index e3fd96e6a5fab..9e6c70aa44791 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_rule_utils.mdx b/api_docs/kbn_observability_alerting_rule_utils.mdx index 14935aa523b63..ff0eae2d9f42d 100644 --- a/api_docs/kbn_observability_alerting_rule_utils.mdx +++ b/api_docs/kbn_observability_alerting_rule_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-rule-utils title: "@kbn/observability-alerting-rule-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-rule-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-rule-utils'] --- import kbnObservabilityAlertingRuleUtilsObj from './kbn_observability_alerting_rule_utils.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 9b855c42672ad..9c8cb91348be7 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx index 652ba42b46b9e..d54e6dd2e92fc 100644 --- a/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx +++ b/api_docs/kbn_observability_get_padded_alert_time_range_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-get-padded-alert-time-range-util title: "@kbn/observability-get-padded-alert-time-range-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-get-padded-alert-time-range-util plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 513ea700f3a5f..363c2cce49bde 100644 --- a/api_docs/kbn_openapi_bundler.mdx +++ b/api_docs/kbn_openapi_bundler.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-bundler title: "@kbn/openapi-bundler" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-bundler plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-bundler'] --- import kbnOpenapiBundlerObj from './kbn_openapi_bundler.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index e0ede1600d22b..647143e700c12 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 94eaf0805d90f..cf7df47e39bd2 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index a7c1b0df2c9bc..79a6f56016721 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 5bc54755ee712..92356fd2b92ce 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_panel_loader.mdx b/api_docs/kbn_panel_loader.mdx index 1d9c1b0c63926..acacb3792e87e 100644 --- a/api_docs/kbn_panel_loader.mdx +++ b/api_docs/kbn_panel_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-panel-loader title: "@kbn/panel-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/panel-loader plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/panel-loader'] --- import kbnPanelLoaderObj from './kbn_panel_loader.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 1a2efe56ad378..1cd5e9fb9746e 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_check.mdx b/api_docs/kbn_plugin_check.mdx index 4ebd65625f4d8..ed3938adeb68a 100644 --- a/api_docs/kbn_plugin_check.mdx +++ b/api_docs/kbn_plugin_check.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-check title: "@kbn/plugin-check" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-check plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-check'] --- import kbnPluginCheckObj from './kbn_plugin_check.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 2fff1d6e944d5..5c941a8a2d6ef 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index ae6425a3ddeee..4e6a1a24027fd 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_presentation_containers.mdx b/api_docs/kbn_presentation_containers.mdx index 13e7aa584b9da..c9bf1261806cf 100644 --- a/api_docs/kbn_presentation_containers.mdx +++ b/api_docs/kbn_presentation_containers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-containers title: "@kbn/presentation-containers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-containers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index dd721dfe4a279..d16174ee32d03 100644 --- a/api_docs/kbn_presentation_publishing.mdx +++ b/api_docs/kbn_presentation_publishing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-publishing title: "@kbn/presentation-publishing" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-publishing plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index bb4c6e4c39841..a94047c2e746a 100644 --- a/api_docs/kbn_profiling_utils.mdx +++ b/api_docs/kbn_profiling_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-profiling-utils title: "@kbn/profiling-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/profiling-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 09db5d7409200..d53d6cfa5ec83 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 2148a7e0ded75..9093a794a388d 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_hooks.mdx b/api_docs/kbn_react_hooks.mdx index 40380736beff3..3c4fbdf2f9c4a 100644 --- a/api_docs/kbn_react_hooks.mdx +++ b/api_docs/kbn_react_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-hooks title: "@kbn/react-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-hooks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-hooks'] --- import kbnReactHooksObj from './kbn_react_hooks.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 55f51bd11645f..2c04e3c718a09 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index e2a6cebb95242..a92959f154a70 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index b8bdb238e53a8..368fb22332666 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index ace4517630f6a..e5423e543eb47 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index 073ca0446fc46..0b90f54e32e65 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index d29397ac2a842..41124bf602c30 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_recently_accessed.mdx b/api_docs/kbn_recently_accessed.mdx index 51c97e5daa56d..e9e3c28fde7b0 100644 --- a/api_docs/kbn_recently_accessed.mdx +++ b/api_docs/kbn_recently_accessed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-recently-accessed title: "@kbn/recently-accessed" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/recently-accessed plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/recently-accessed'] --- import kbnRecentlyAccessedObj from './kbn_recently_accessed.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 30c6e46fa546a..f6040d23d78a0 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 6f8714856f53c..2c6ea69b99898 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index b34c99ec03f64..bd0c1a8441b11 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 0aabbd83f2723..b0703fdbea965 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 41f81fe8c25ad..aa52df3b9af02 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_csv_share_panel.mdx b/api_docs/kbn_reporting_csv_share_panel.mdx index f82a352381a1d..558ba1078332c 100644 --- a/api_docs/kbn_reporting_csv_share_panel.mdx +++ b/api_docs/kbn_reporting_csv_share_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-csv-share-panel title: "@kbn/reporting-csv-share-panel" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-csv-share-panel plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-csv-share-panel'] --- import kbnReportingCsvSharePanelObj from './kbn_reporting_csv_share_panel.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index ea7dc36c745bc..b076d1e2d4281 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index e7714d27cc412..440c16e25ac79 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index 65f7222f241c0..183aad22d548a 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index cc70475201a59..9dd4f7d4fba5e 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index 1d3d5b1947770..0144f67ff9d09 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 112cd2c7c7aad..7d89c640502f7 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index 36edcb8746f08..80d075caa8eb8 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index af67a4cfe1d01..b6077e48df033 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index 0f997482148ba..a051705af44be 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index 7af8aa71f3636..1c984dd5975b5 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_response_ops_feature_flag_service.mdx b/api_docs/kbn_response_ops_feature_flag_service.mdx index 057137e528c94..ce97ad1b9b41d 100644 --- a/api_docs/kbn_response_ops_feature_flag_service.mdx +++ b/api_docs/kbn_response_ops_feature_flag_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-response-ops-feature-flag-service title: "@kbn/response-ops-feature-flag-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/response-ops-feature-flag-service plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/response-ops-feature-flag-service'] --- import kbnResponseOpsFeatureFlagServiceObj from './kbn_response_ops_feature_flag_service.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 6619bbbd814d7..9980c10c5275a 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rollup.mdx b/api_docs/kbn_rollup.mdx index 8f0b632a76327..b621ec4974509 100644 --- a/api_docs/kbn_rollup.mdx +++ b/api_docs/kbn_rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rollup title: "@kbn/rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rollup plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rollup'] --- import kbnRollupObj from './kbn_rollup.devdocs.json'; diff --git a/api_docs/kbn_router_to_openapispec.mdx b/api_docs/kbn_router_to_openapispec.mdx index 93716fe82e622..b7eb2c5e36995 100644 --- a/api_docs/kbn_router_to_openapispec.mdx +++ b/api_docs/kbn_router_to_openapispec.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-to-openapispec title: "@kbn/router-to-openapispec" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-to-openapispec plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-to-openapispec'] --- import kbnRouterToOpenapispecObj from './kbn_router_to_openapispec.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index 737b5c2d6c9ef..932b25480f852 100644 --- a/api_docs/kbn_router_utils.mdx +++ b/api_docs/kbn_router_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-router-utils title: "@kbn/router-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/router-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/router-utils'] --- import kbnRouterUtilsObj from './kbn_router_utils.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 283721e4c423e..24a2489dac09f 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 9fe61f49924a5..720ed6e29bd8a 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index 4b81761d07012..a869ed999750f 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_screenshotting_server.mdx b/api_docs/kbn_screenshotting_server.mdx index 6c1db5a3e311a..1bcba6c235083 100644 --- a/api_docs/kbn_screenshotting_server.mdx +++ b/api_docs/kbn_screenshotting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-screenshotting-server title: "@kbn/screenshotting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/screenshotting-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/screenshotting-server'] --- import kbnScreenshottingServerObj from './kbn_screenshotting_server.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 61b49f67dfea9..470edf9117325 100644 --- a/api_docs/kbn_search_api_panels.mdx +++ b/api_docs/kbn_search_api_panels.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-api-panels title: "@kbn/search-api-panels" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-api-panels plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index b0024e0ecfb68..edd03a9482a77 100644 --- a/api_docs/kbn_search_connectors.mdx +++ b/api_docs/kbn_search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-connectors title: "@kbn/search-connectors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-connectors plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index cadaf0a1ce645..a303a1defb270 100644 --- a/api_docs/kbn_search_errors.mdx +++ b/api_docs/kbn_search_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-errors title: "@kbn/search-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-errors plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-errors'] --- import kbnSearchErrorsObj from './kbn_search_errors.devdocs.json'; diff --git a/api_docs/kbn_search_index_documents.mdx b/api_docs/kbn_search_index_documents.mdx index c4a98588b7464..53deab2b6e1c6 100644 --- a/api_docs/kbn_search_index_documents.mdx +++ b/api_docs/kbn_search_index_documents.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-index-documents title: "@kbn/search-index-documents" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-index-documents plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-index-documents'] --- import kbnSearchIndexDocumentsObj from './kbn_search_index_documents.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index 477b14f14d826..69f1aaf15f6ff 100644 --- a/api_docs/kbn_search_response_warnings.mdx +++ b/api_docs/kbn_search_response_warnings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-response-warnings title: "@kbn/search-response-warnings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-response-warnings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_search_types.mdx b/api_docs/kbn_search_types.mdx index df104962a59dc..2486d7900cc2d 100644 --- a/api_docs/kbn_search_types.mdx +++ b/api_docs/kbn_search_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-search-types title: "@kbn/search-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/search-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-types'] --- import kbnSearchTypesObj from './kbn_search_types.devdocs.json'; diff --git a/api_docs/kbn_security_api_key_management.mdx b/api_docs/kbn_security_api_key_management.mdx index e36253329d1aa..e9027f26c82b0 100644 --- a/api_docs/kbn_security_api_key_management.mdx +++ b/api_docs/kbn_security_api_key_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-api-key-management title: "@kbn/security-api-key-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-api-key-management plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-api-key-management'] --- import kbnSecurityApiKeyManagementObj from './kbn_security_api_key_management.devdocs.json'; diff --git a/api_docs/kbn_security_authorization_core.mdx b/api_docs/kbn_security_authorization_core.mdx index 78d9f92936d75..12b32f2866455 100644 --- a/api_docs/kbn_security_authorization_core.mdx +++ b/api_docs/kbn_security_authorization_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-authorization-core title: "@kbn/security-authorization-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-authorization-core plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-authorization-core'] --- import kbnSecurityAuthorizationCoreObj from './kbn_security_authorization_core.devdocs.json'; diff --git a/api_docs/kbn_security_form_components.mdx b/api_docs/kbn_security_form_components.mdx index 7b7e5b8ce9a7b..2be7282d3d24f 100644 --- a/api_docs/kbn_security_form_components.mdx +++ b/api_docs/kbn_security_form_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-form-components title: "@kbn/security-form-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-form-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-form-components'] --- import kbnSecurityFormComponentsObj from './kbn_security_form_components.devdocs.json'; diff --git a/api_docs/kbn_security_hardening.mdx b/api_docs/kbn_security_hardening.mdx index 86caab608d898..6caeb91521fca 100644 --- a/api_docs/kbn_security_hardening.mdx +++ b/api_docs/kbn_security_hardening.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-hardening title: "@kbn/security-hardening" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-hardening plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-hardening'] --- import kbnSecurityHardeningObj from './kbn_security_hardening.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index ad3255608e237..13194a614a1d9 100644 --- a/api_docs/kbn_security_plugin_types_common.mdx +++ b/api_docs/kbn_security_plugin_types_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-common title: "@kbn/security-plugin-types-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-common'] --- import kbnSecurityPluginTypesCommonObj from './kbn_security_plugin_types_common.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_public.mdx b/api_docs/kbn_security_plugin_types_public.mdx index 85c99b584487d..e7d034fce9f2c 100644 --- a/api_docs/kbn_security_plugin_types_public.mdx +++ b/api_docs/kbn_security_plugin_types_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-public title: "@kbn/security-plugin-types-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-public plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-public'] --- import kbnSecurityPluginTypesPublicObj from './kbn_security_plugin_types_public.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_server.devdocs.json b/api_docs/kbn_security_plugin_types_server.devdocs.json index ce04849d4bd72..f718c3ddb240d 100644 --- a/api_docs/kbn_security_plugin_types_server.devdocs.json +++ b/api_docs/kbn_security_plugin_types_server.devdocs.json @@ -4286,23 +4286,23 @@ }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts" + "path": "x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts" + "path": "x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts" + "path": "x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/enable.ts" + "path": "x-pack/plugins/entity_manager/server/routes/enablement/enable.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/disable.ts" + "path": "x-pack/plugins/entity_manager/server/routes/enablement/disable.ts" }, { "plugin": "serverlessSearch", diff --git a/api_docs/kbn_security_plugin_types_server.mdx b/api_docs/kbn_security_plugin_types_server.mdx index 3c66a756e419b..a62ef4b7d9952 100644 --- a/api_docs/kbn_security_plugin_types_server.mdx +++ b/api_docs/kbn_security_plugin_types_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-plugin-types-server title: "@kbn/security-plugin-types-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-plugin-types-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-plugin-types-server'] --- import kbnSecurityPluginTypesServerObj from './kbn_security_plugin_types_server.devdocs.json'; diff --git a/api_docs/kbn_security_role_management_model.mdx b/api_docs/kbn_security_role_management_model.mdx index d4a98e60298f2..876c0a3d5f31b 100644 --- a/api_docs/kbn_security_role_management_model.mdx +++ b/api_docs/kbn_security_role_management_model.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-role-management-model title: "@kbn/security-role-management-model" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-role-management-model plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-role-management-model'] --- import kbnSecurityRoleManagementModelObj from './kbn_security_role_management_model.devdocs.json'; diff --git a/api_docs/kbn_security_solution_common.mdx b/api_docs/kbn_security_solution_common.mdx index 8e762dab8e569..4445be53b82d9 100644 --- a/api_docs/kbn_security_solution_common.mdx +++ b/api_docs/kbn_security_solution_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-common title: "@kbn/security-solution-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-common plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-common'] --- import kbnSecuritySolutionCommonObj from './kbn_security_solution_common.devdocs.json'; diff --git a/api_docs/kbn_security_solution_distribution_bar.mdx b/api_docs/kbn_security_solution_distribution_bar.mdx index 962163387af86..b922e7a8dacc5 100644 --- a/api_docs/kbn_security_solution_distribution_bar.mdx +++ b/api_docs/kbn_security_solution_distribution_bar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-distribution-bar title: "@kbn/security-solution-distribution-bar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-distribution-bar plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-distribution-bar'] --- import kbnSecuritySolutionDistributionBarObj from './kbn_security_solution_distribution_bar.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index bd02234340faf..01aaaee02c287 100644 --- a/api_docs/kbn_security_solution_features.mdx +++ b/api_docs/kbn_security_solution_features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-features title: "@kbn/security-solution-features" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-features plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-features'] --- import kbnSecuritySolutionFeaturesObj from './kbn_security_solution_features.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index 56050c6d5522f..5ce26f24f3436 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index e4b1ba0043b4c..0e7e8292d1933 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index 0435006008eeb..f9dd479b75b3b 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_security_ui_components.mdx b/api_docs/kbn_security_ui_components.mdx index 0cbdd4041d663..ef5e6f5312238 100644 --- a/api_docs/kbn_security_ui_components.mdx +++ b/api_docs/kbn_security_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-ui-components title: "@kbn/security-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-ui-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-ui-components'] --- import kbnSecurityUiComponentsObj from './kbn_security_ui_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 9319edbdb175f..7d5e064ea4530 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index f02a28ba3ce5d..676e4ad9c5287 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index 20fb15b9bfcb2..9e4c02261cbb2 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 6750b47129f18..4bc9b4c7e6d09 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index df86e5b288cbe..5ce297dfa9160 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index e6f496c232df4..5461dd2371cad 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 6129366fe2202..d5d36d8fd6d35 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 61731c0bb3958..dda7c52cb8ff3 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index d3f90b7e0f14c..70a3321def413 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 59297b772b80b..c13954de418f7 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 82e4ab04c1cf7..767e876b3e426 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 3bbd78305ae85..928f55045c4b6 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 41744fbb4fc43..f2f310d6e0a79 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 569a567200fac..7460fbe1282ca 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index cacd67d7d1392..24c3440edfd7c 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 7ab5bc41ec5f6..45d98c23170f5 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 3923668aa4222..b559b607f1adf 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 16166c272e785..5a3ceafb89908 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index ec9a2ec6575a8..6539a702a93ba 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_client.mdx b/api_docs/kbn_server_route_repository_client.mdx index 02b646ab0643d..78cf759432249 100644 --- a/api_docs/kbn_server_route_repository_client.mdx +++ b/api_docs/kbn_server_route_repository_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-client title: "@kbn/server-route-repository-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-client plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-client'] --- import kbnServerRouteRepositoryClientObj from './kbn_server_route_repository_client.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository_utils.mdx b/api_docs/kbn_server_route_repository_utils.mdx index cb74c8bb25ca9..7eb70f0eec0cd 100644 --- a/api_docs/kbn_server_route_repository_utils.mdx +++ b/api_docs/kbn_server_route_repository_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository-utils title: "@kbn/server-route-repository-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository-utils'] --- import kbnServerRouteRepositoryUtilsObj from './kbn_server_route_repository_utils.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 0792fc5032ac4..26ebadc013b52 100644 --- a/api_docs/kbn_serverless_common_settings.mdx +++ b/api_docs/kbn_serverless_common_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-common-settings title: "@kbn/serverless-common-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-common-settings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-common-settings'] --- import kbnServerlessCommonSettingsObj from './kbn_serverless_common_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_observability_settings.mdx b/api_docs/kbn_serverless_observability_settings.mdx index 44644cc470e97..e602c1289636f 100644 --- a/api_docs/kbn_serverless_observability_settings.mdx +++ b/api_docs/kbn_serverless_observability_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-observability-settings title: "@kbn/serverless-observability-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-observability-settings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-observability-settings'] --- import kbnServerlessObservabilitySettingsObj from './kbn_serverless_observability_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index edabf158ff207..c52f352ca9115 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_search_settings.mdx b/api_docs/kbn_serverless_search_settings.mdx index b243feddf7372..306800cece8e1 100644 --- a/api_docs/kbn_serverless_search_settings.mdx +++ b/api_docs/kbn_serverless_search_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-search-settings title: "@kbn/serverless-search-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-search-settings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-search-settings'] --- import kbnServerlessSearchSettingsObj from './kbn_serverless_search_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_security_settings.mdx b/api_docs/kbn_serverless_security_settings.mdx index cd4854927df2f..7830a3ec7727e 100644 --- a/api_docs/kbn_serverless_security_settings.mdx +++ b/api_docs/kbn_serverless_security_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-security-settings title: "@kbn/serverless-security-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-security-settings plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-security-settings'] --- import kbnServerlessSecuritySettingsObj from './kbn_serverless_security_settings.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index adbd44fef6856..e215a1de2f541 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 77c288f9cf183..ae2349ae7659d 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 69cbd82babb69..77c1331b149ab 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 5fbc3b725e515..9001d953ad0ee 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 4a318200ef5df..fe2d21cf4194b 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 34b2d69864c14..23756e612f3b8 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index a4380d4eb1f65..dbefb716e3a97 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index abc280c5045e4..42fada28cf3cd 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index 6901292a7b02a..b31eab58148b1 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index f8fd8cae72cdc..0f74c3c924f9d 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index e391372125c0a..7a94352a9ee73 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index b8b55368b4406..bedc80fadb757 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index cbc49a9e69722..5c6f0dc41c2d5 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 356c1e2dad620..e333ca4d41ff6 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 2e44f2db2427f..8e01c8215d202 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index d06ad88805152..3281d7f36d961 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 418bb3382e747..7ecc378b56d2a 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index e62e5533d788c..8ea8c726c097b 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index a58d7e521c95c..14f634a50c81b 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 2c12d7fbb63ba..ac5d641b63243 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index a6fa075838143..2bc6c3d52f3bb 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index a4fb3ea0be9ec..2df0d85de75c1 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 6322a5ab0f24b..bbf3224a67ab3 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 74c6d80feb7bb..860d6b0e7741c 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 3dacc0c77a471..6c16279846ad6 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 04d826bfdd1a3..1311d49439d44 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index a935d3fd1cadd..a6db788384a3c 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index f766c86efef85..bdf92ed310551 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 61764bbf6904e..c9fb9e9df261d 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 70d4be9b9fd0a..2d14eab05e4e4 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 0f71aa28e0172..93b8acd82e3ae 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 7e51334a9f7ef..a99586924fa89 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 92f585923e037..1d5d5074d16a2 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 994e96c9a21f5..060edf06b6285 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 62fe0edda4056..f9d3f5734279b 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 1650e066eb3be..c3f4dc7a6c9e7 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index d33438d6b2a90..92c998ee59641 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 2dd715a66a14e..02520eb9c3557 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 7469668c2baf8..3d43e933acdee 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_tabbed_modal.mdx b/api_docs/kbn_shared_ux_tabbed_modal.mdx index 212e983ff36a1..c43ed37a29c43 100644 --- a/api_docs/kbn_shared_ux_tabbed_modal.mdx +++ b/api_docs/kbn_shared_ux_tabbed_modal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-tabbed-modal title: "@kbn/shared-ux-tabbed-modal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-tabbed-modal plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-tabbed-modal'] --- import kbnSharedUxTabbedModalObj from './kbn_shared_ux_tabbed_modal.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_table_persist.mdx b/api_docs/kbn_shared_ux_table_persist.mdx index 524aebe6905ea..a045de8fe1960 100644 --- a/api_docs/kbn_shared_ux_table_persist.mdx +++ b/api_docs/kbn_shared_ux_table_persist.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-table-persist title: "@kbn/shared-ux-table-persist" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-table-persist plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-table-persist'] --- import kbnSharedUxTablePersistObj from './kbn_shared_ux_table_persist.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 1a0739d0cb237..870de75ebd46d 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 3e7ad217ee64f..fc91c1b32b7b1 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 6b0564f1c1f31..9c08af1208446 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_predicates.mdx b/api_docs/kbn_sort_predicates.mdx index db3738005a235..0f3abed332d5e 100644 --- a/api_docs/kbn_sort_predicates.mdx +++ b/api_docs/kbn_sort_predicates.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-predicates title: "@kbn/sort-predicates" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-predicates plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_sse_utils.mdx b/api_docs/kbn_sse_utils.mdx index e38989a1ca2db..53dcf809f463a 100644 --- a/api_docs/kbn_sse_utils.mdx +++ b/api_docs/kbn_sse_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils title: "@kbn/sse-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils'] --- import kbnSseUtilsObj from './kbn_sse_utils.devdocs.json'; diff --git a/api_docs/kbn_sse_utils_client.mdx b/api_docs/kbn_sse_utils_client.mdx index 40837d625933e..d8c6578089a13 100644 --- a/api_docs/kbn_sse_utils_client.mdx +++ b/api_docs/kbn_sse_utils_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils-client title: "@kbn/sse-utils-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils-client plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils-client'] --- import kbnSseUtilsClientObj from './kbn_sse_utils_client.devdocs.json'; diff --git a/api_docs/kbn_sse_utils_server.mdx b/api_docs/kbn_sse_utils_server.mdx index 3e8c831d204ae..c317e93978f44 100644 --- a/api_docs/kbn_sse_utils_server.mdx +++ b/api_docs/kbn_sse_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sse-utils-server title: "@kbn/sse-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sse-utils-server plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sse-utils-server'] --- import kbnSseUtilsServerObj from './kbn_sse_utils_server.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 06429862009fb..d54c30dc41d1a 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index b2bd3f397b21f..dc23a211b8364 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 90455353f8602..bd9c950861231 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_synthetics_e2e.mdx b/api_docs/kbn_synthetics_e2e.mdx index 291bb3b71e28a..44499c1dcccae 100644 --- a/api_docs/kbn_synthetics_e2e.mdx +++ b/api_docs/kbn_synthetics_e2e.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-e2e title: "@kbn/synthetics-e2e" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-e2e plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-e2e'] --- import kbnSyntheticsE2eObj from './kbn_synthetics_e2e.devdocs.json'; diff --git a/api_docs/kbn_synthetics_private_location.mdx b/api_docs/kbn_synthetics_private_location.mdx index 8239cdbfe702b..a7f018d55c432 100644 --- a/api_docs/kbn_synthetics_private_location.mdx +++ b/api_docs/kbn_synthetics_private_location.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-synthetics-private-location title: "@kbn/synthetics-private-location" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/synthetics-private-location plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/synthetics-private-location'] --- import kbnSyntheticsPrivateLocationObj from './kbn_synthetics_private_location.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index ed5c622ae7766..420cbe74231ab 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 65273e4ae1783..c696210a28b1e 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_eui_helpers.mdx b/api_docs/kbn_test_eui_helpers.mdx index 540d4a09a630f..baed511a9a61b 100644 --- a/api_docs/kbn_test_eui_helpers.mdx +++ b/api_docs/kbn_test_eui_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-eui-helpers title: "@kbn/test-eui-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-eui-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-eui-helpers'] --- import kbnTestEuiHelpersObj from './kbn_test_eui_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index e8b40413368ca..7491ac275ebe7 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 5333ef6ab58cc..db3ce917b19aa 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 748a85928e0c7..9001781290a8d 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_timerange.mdx b/api_docs/kbn_timerange.mdx index c331eb93f6991..3b6db8e96738c 100644 --- a/api_docs/kbn_timerange.mdx +++ b/api_docs/kbn_timerange.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-timerange title: "@kbn/timerange" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/timerange plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/timerange'] --- import kbnTimerangeObj from './kbn_timerange.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index ffff78435abd3..bf40a7ddcaabc 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index 01fe12c7cfa64..62f07b9d0c021 100644 --- a/api_docs/kbn_triggers_actions_ui_types.mdx +++ b/api_docs/kbn_triggers_actions_ui_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-triggers-actions-ui-types title: "@kbn/triggers-actions-ui-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/triggers-actions-ui-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/triggers-actions-ui-types'] --- import kbnTriggersActionsUiTypesObj from './kbn_triggers_actions_ui_types.devdocs.json'; diff --git a/api_docs/kbn_try_in_console.mdx b/api_docs/kbn_try_in_console.mdx index 5eb284913eac7..df07253223e18 100644 --- a/api_docs/kbn_try_in_console.mdx +++ b/api_docs/kbn_try_in_console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-try-in-console title: "@kbn/try-in-console" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/try-in-console plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/try-in-console'] --- import kbnTryInConsoleObj from './kbn_try_in_console.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 749516f2d5c9b..5c38609a7f4ed 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 30bf65eb3fb72..4152f61a8a851 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 9a5d7c8a9fc8c..f3b60e8bc67c4 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 0d17547212c06..6904f2c87468c 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index bcda14d552e0c..64f9357ac6c28 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index 7a9da1c914ca6..e799704ce451f 100644 --- a/api_docs/kbn_unified_data_table.mdx +++ b/api_docs/kbn_unified_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-data-table title: "@kbn/unified-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-data-table plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index f1a071751304a..8a1acf9b8815e 100644 --- a/api_docs/kbn_unified_doc_viewer.mdx +++ b/api_docs/kbn_unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-doc-viewer title: "@kbn/unified-doc-viewer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-doc-viewer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-doc-viewer'] --- import kbnUnifiedDocViewerObj from './kbn_unified_doc_viewer.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index fada9f340d836..85bbab6dbb49d 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 59298d7c2fc23..c3b9c89fd2b59 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_prompt.mdx b/api_docs/kbn_unsaved_changes_prompt.mdx index 9ade999c38c39..3387466e06c0e 100644 --- a/api_docs/kbn_unsaved_changes_prompt.mdx +++ b/api_docs/kbn_unsaved_changes_prompt.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-prompt title: "@kbn/unsaved-changes-prompt" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-prompt plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-prompt'] --- import kbnUnsavedChangesPromptObj from './kbn_unsaved_changes_prompt.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 64a1c5c283d17..f3d24d302efbf 100644 --- a/api_docs/kbn_use_tracked_promise.mdx +++ b/api_docs/kbn_use_tracked_promise.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-use-tracked-promise title: "@kbn/use-tracked-promise" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/use-tracked-promise plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/use-tracked-promise'] --- import kbnUseTrackedPromiseObj from './kbn_use_tracked_promise.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index b3bd469679bb8..ad2bbb0d6e85b 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index e818b0869ddc0..b1ea5dc792074 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 786b78c009b71..c74807b62c488 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 3e224edd55945..5b96a448782cc 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index 6bc692b3d1d3f..150c694870534 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_visualization_utils.mdx b/api_docs/kbn_visualization_utils.mdx index 787315350f0a9..3d1d18519ada2 100644 --- a/api_docs/kbn_visualization_utils.mdx +++ b/api_docs/kbn_visualization_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-utils title: "@kbn/visualization-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-utils'] --- import kbnVisualizationUtilsObj from './kbn_visualization_utils.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index a77e1a664b032..36bc4b08333ca 100644 --- a/api_docs/kbn_xstate_utils.mdx +++ b/api_docs/kbn_xstate_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-xstate-utils title: "@kbn/xstate-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/xstate-utils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/xstate-utils'] --- import kbnXstateUtilsObj from './kbn_xstate_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index dd126036f0c23..87053f7550612 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod.mdx b/api_docs/kbn_zod.mdx index 563294de0edf8..0c44481e26c49 100644 --- a/api_docs/kbn_zod.mdx +++ b/api_docs/kbn_zod.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod title: "@kbn/zod" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod'] --- import kbnZodObj from './kbn_zod.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index d62a7f6c49c92..1f3c27ff5a1bb 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index fa6c238fa7800..8e38fed53ea1c 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index cba2b1ce1648c..8a2aff206afcb 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 0a4674502959f..7b70c34465579 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 24e0272883296..1d33181359145 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 12fd0b398cfdd..a1651aa55ca92 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 3fc60dbb0dd26..06ed6e26ae276 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index cb1ff50182afb..e215428a5d8f3 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 0ef3172a61244..96b36df9073d5 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.mdx b/api_docs/links.mdx index 818c2ac82a7a6..90626d7735f93 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 767734b3c9d3c..608cedb06670b 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_data_access.mdx b/api_docs/logs_data_access.mdx index af96766666cd1..68a3e9b207c34 100644 --- a/api_docs/logs_data_access.mdx +++ b/api_docs/logs_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsDataAccess title: "logsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the logsDataAccess plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsDataAccess'] --- import logsDataAccessObj from './logs_data_access.devdocs.json'; diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index 4c86876f2ce98..d9a2cfe524fc7 100644 --- a/api_docs/logs_explorer.mdx +++ b/api_docs/logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsExplorer title: "logsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logsExplorer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsExplorer'] --- import logsExplorerObj from './logs_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 697e1ee33aa87..f41bd9426e896 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 096313fba48ca..0f165095ddcf0 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index d027bb30a8329..004ce2bb21168 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; -Contact [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) for questions regarding this plugin. +Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 046f26cc9edb1..0a7f1b8958468 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; -Contact [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) for questions regarding this plugin. +Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index 27c857687a2b8..e9263ce03590f 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 631a1506b17bd..4566390bf96db 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx index a1bcdaf060393..97b80031183a1 100644 --- a/api_docs/mock_idp_plugin.mdx +++ b/api_docs/mock_idp_plugin.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mockIdpPlugin title: "mockIdpPlugin" image: https://source.unsplash.com/400x175/?github description: API docs for the mockIdpPlugin plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] --- import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 2ca761284d1e0..21e821290a6a4 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index c2dda73f35726..7e0d2e48ab300 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 0e93de25a89a1..d188d8087a10c 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 233050fea8efc..05ca45aecbdb8 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/no_data_page.mdx b/api_docs/no_data_page.mdx index 99416ad1ee0bb..8c1a4e2ba0b38 100644 --- a/api_docs/no_data_page.mdx +++ b/api_docs/no_data_page.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/noDataPage title: "noDataPage" image: https://source.unsplash.com/400x175/?github description: API docs for the noDataPage plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'noDataPage'] --- import noDataPageObj from './no_data_page.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index f73ec119b5760..cfd0007885dfc 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index df57c1b532c37..3b39d598e2478 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -12947,6 +12947,104 @@ "trackAdoption": false } ] + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers", + "type": "Object", + "tags": [], + "label": "[searchExcludedDataTiers]", + "description": [], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers.category", + "type": "Array", + "tags": [], + "label": "category", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers.value", + "type": "Array", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "never[]" + ], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [], + "signature": [ + { + "pluginId": "@kbn/config-schema", + "scope": "common", + "docId": "kibKbnConfigSchemaPluginApi", + "section": "def-common.Type", + "text": "Type" + }, + "<(\"data_cold\" | \"data_frozen\")[]>" + ], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.searchExcludedDataTiers.requiresPageReload", + "type": "boolean", + "tags": [], + "label": "requiresPageReload", + "description": [], + "signature": [ + "false" + ], + "path": "x-pack/plugins/observability_solution/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ] } ], "initialIsOpen": false diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index d328829906668..4e8119025c312 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 705 | 2 | 698 | 22 | +| 712 | 2 | 705 | 22 | ## Client diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 8df0c80b4f7b3..fd88ecc2c74bc 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant_app.mdx b/api_docs/observability_a_i_assistant_app.mdx index bbf024f9241f2..9ccaa172b7413 100644 --- a/api_docs/observability_a_i_assistant_app.mdx +++ b/api_docs/observability_a_i_assistant_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistantApp title: "observabilityAIAssistantApp" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistantApp plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistantApp'] --- import observabilityAIAssistantAppObj from './observability_a_i_assistant_app.devdocs.json'; diff --git a/api_docs/observability_ai_assistant_management.mdx b/api_docs/observability_ai_assistant_management.mdx index a1f56e774a6c1..cf02d9dea3716 100644 --- a/api_docs/observability_ai_assistant_management.mdx +++ b/api_docs/observability_ai_assistant_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAiAssistantManagement title: "observabilityAiAssistantManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAiAssistantManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAiAssistantManagement'] --- import observabilityAiAssistantManagementObj from './observability_ai_assistant_management.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index f4e66e35942ae..df92289115be2 100644 --- a/api_docs/observability_logs_explorer.mdx +++ b/api_docs/observability_logs_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogsExplorer title: "observabilityLogsExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogsExplorer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogsExplorer'] --- import observabilityLogsExplorerObj from './observability_logs_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index d7f711fa592da..76ca275b05831 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 92deb6b8fc266..6f5372c71b407 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 51906c837cfab..e52ae93c7caf4 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/painless_lab.mdx b/api_docs/painless_lab.mdx index e50c55dada803..99a08465e3cc4 100644 --- a/api_docs/painless_lab.mdx +++ b/api_docs/painless_lab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/painlessLab title: "painlessLab" image: https://source.unsplash.com/400x175/?github description: API docs for the painlessLab plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'painlessLab'] --- import painlessLabObj from './painless_lab.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 39add68e0e4c7..9b696a1185028 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 854 | 728 | 46 | +| 854 | 728 | 45 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 53130 | 245 | 39936 | 1978 | +| 53159 | 245 | 39965 | 1980 | ## Plugin Directory @@ -99,7 +99,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 255 | 0 | 105 | 2 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Index pattern fields and ambiguous values formatters | 292 | 5 | 253 | 3 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes services for async usage and search of fields metadata. | 42 | 0 | 42 | 7 | -| | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 88 | 0 | 88 | 8 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 88 | 0 | 88 | 8 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 240 | 0 | 24 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Simple UI for managing files in Kibana | 3 | 0 | 3 | 0 | | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1361 | 5 | 1238 | 74 | @@ -113,7 +113,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 149 | 0 | 111 | 1 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Image embeddable | 1 | 0 | 1 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 4 | 0 | 4 | 0 | -| | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 238 | 0 | 233 | 1 | +| | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 243 | 0 | 238 | 1 | | | [@elastic/appex-ai-infra](https://github.com/orgs/elastic/teams/appex-ai-infra) | - | 49 | 0 | 44 | 12 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 23 | 0 | 23 | 5 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 4 | 0 | 4 | 0 | @@ -140,8 +140,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes the shared components and APIs to access and visualize logs. | 310 | 0 | 281 | 32 | | logstash | [@elastic/logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 44 | 0 | 44 | 7 | -| | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 209 | 0 | 205 | 28 | -| | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 60 | 0 | 60 | 0 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 209 | 0 | 205 | 28 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 60 | 0 | 60 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Exposes utilities for accessing metrics data | 137 | 8 | 137 | 5 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 154 | 3 | 67 | 102 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 2 | 0 | 2 | 0 | @@ -151,7 +151,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 1 | -| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 705 | 2 | 698 | 22 | +| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 712 | 2 | 705 | 22 | | | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 286 | 1 | 284 | 27 | | | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 4 | 0 | 4 | 0 | | | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 2 | 0 | 2 | 0 | @@ -183,10 +183,10 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 11 | 0 | 11 | 0 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 10 | 0 | 6 | 1 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | Plugin to provide access to and rendering of python notebooks for use in the persistent developer console. | 10 | 0 | 10 | 1 | -| | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 17 | 0 | 11 | 1 | +| | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 21 | 0 | 15 | 1 | | searchprofiler | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 448 | 0 | 231 | 0 | -| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 192 | 0 | 123 | 33 | +| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 193 | 0 | 124 | 34 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 7 | 0 | 7 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | The core Serverless plugin, providing APIs to Serverless Project plugins. | 25 | 0 | 24 | 0 | @@ -512,7 +512,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | | | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 177 | 1 | 139 | 31 | | | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 73 | 0 | 69 | 0 | -| | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 197 | 0 | 185 | 10 | +| | [@elastic/kibana-esql](https://github.com/orgs/elastic/teams/kibana-esql) | - | 197 | 0 | 185 | 11 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 40 | 0 | 40 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 0 | 52 | 1 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 43 | 0 | 17 | 2 | @@ -520,7 +520,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 49 | 0 | 40 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 0 | 0 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 3 | 0 | 3 | 0 | -| | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 102 | 0 | 77 | 1 | +| | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 106 | 0 | 81 | 1 | | | [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) | - | 560 | 6 | 520 | 7 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 0 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 1 | 0 | 1 | 0 | @@ -540,7 +540,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 7 | 1 | 7 | 1 | | | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 9 | 0 | 9 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 52 | 12 | 43 | 0 | -| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 59 | 0 | 59 | 0 | +| | [@elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/obs-ux-management-team) | - | 66 | 0 | 66 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 60 | 0 | 60 | 4 | | | [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-kibana) | - | 44 | 0 | 44 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 13 | 0 | 13 | 0 | @@ -562,13 +562,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 23 | 0 | 7 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 8 | 0 | 2 | 3 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 45 | 0 | 0 | 0 | -| | [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 142 | 0 | 140 | 0 | +| | [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 143 | 0 | 141 | 0 | | | [@elastic/appex-sharedux @elastic/kibana-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 20 | 0 | 11 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 88 | 0 | 10 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 56 | 0 | 6 | 0 | | | [@elastic/kibana-management](https://github.com/orgs/elastic/teams/kibana-management) | - | 2 | 0 | 0 | 0 | -| | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 592 | 1 | 1 | 0 | -| | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 2 | 0 | 2 | 0 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 592 | 1 | 1 | 0 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 2 | 0 | 2 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 97 | 1 | 0 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 209 | 3 | 1 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 8 | 0 | 8 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index 646744ab4d1ec..46540481ac93d 100644 --- a/api_docs/presentation_panel.mdx +++ b/api_docs/presentation_panel.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationPanel title: "presentationPanel" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationPanel plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationPanel'] --- import presentationPanelObj from './presentation_panel.devdocs.json'; diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 162fc6e74f476..abb00b0722c1d 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 2fd0d31b6befe..fd52d848cfb77 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/profiling_data_access.mdx b/api_docs/profiling_data_access.mdx index 4eb55274641b8..714543f9908e6 100644 --- a/api_docs/profiling_data_access.mdx +++ b/api_docs/profiling_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profilingDataAccess title: "profilingDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the profilingDataAccess plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profilingDataAccess'] --- import profilingDataAccessObj from './profiling_data_access.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index e7b01d7ff7ffe..258a03989a340 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index d9a7e189a17f6..274baa9d793a5 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index 360f1614d991c..1b756b0ff9a7f 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index c5cc8848d1971..f2a13761a6335 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 460641f166d87..4ac74dd9e963e 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 2572dc210c579..02730aadd3849 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index 8a78de16d7341..dc36bb8e633de 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index b789f43069fd5..d6a574b778b48 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index e3ac8a9b1203d..dbaa17f17e246 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 8887542976ce0..01db6b6464d90 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index 408fe1666f918..f0089a84e4e9d 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index aa29491df81f8..c9e00492e93b1 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 986f4f6fb8ca0..d93b19c3caca1 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/search_assistant.mdx b/api_docs/search_assistant.mdx index d204567b135de..d0c41562dbf19 100644 --- a/api_docs/search_assistant.mdx +++ b/api_docs/search_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchAssistant title: "searchAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the searchAssistant plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchAssistant'] --- import searchAssistantObj from './search_assistant.devdocs.json'; diff --git a/api_docs/search_connectors.mdx b/api_docs/search_connectors.mdx index 8ecce79d63de4..02e56667b78b2 100644 --- a/api_docs/search_connectors.mdx +++ b/api_docs/search_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchConnectors title: "searchConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the searchConnectors plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchConnectors'] --- import searchConnectorsObj from './search_connectors.devdocs.json'; diff --git a/api_docs/search_homepage.mdx b/api_docs/search_homepage.mdx index e984afce0f94a..da1e7c20cf32d 100644 --- a/api_docs/search_homepage.mdx +++ b/api_docs/search_homepage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchHomepage title: "searchHomepage" image: https://source.unsplash.com/400x175/?github description: API docs for the searchHomepage plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchHomepage'] --- import searchHomepageObj from './search_homepage.devdocs.json'; diff --git a/api_docs/search_indices.mdx b/api_docs/search_indices.mdx index f9054f79c1e13..110a28629666b 100644 --- a/api_docs/search_indices.mdx +++ b/api_docs/search_indices.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchIndices title: "searchIndices" image: https://source.unsplash.com/400x175/?github description: API docs for the searchIndices plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchIndices'] --- import searchIndicesObj from './search_indices.devdocs.json'; diff --git a/api_docs/search_inference_endpoints.mdx b/api_docs/search_inference_endpoints.mdx index 2dff31fcd1cf8..42b60fc223951 100644 --- a/api_docs/search_inference_endpoints.mdx +++ b/api_docs/search_inference_endpoints.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchInferenceEndpoints title: "searchInferenceEndpoints" image: https://source.unsplash.com/400x175/?github description: API docs for the searchInferenceEndpoints plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchInferenceEndpoints'] --- import searchInferenceEndpointsObj from './search_inference_endpoints.devdocs.json'; diff --git a/api_docs/search_notebooks.mdx b/api_docs/search_notebooks.mdx index e2dc610985b9a..2f1fda40bb0c7 100644 --- a/api_docs/search_notebooks.mdx +++ b/api_docs/search_notebooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchNotebooks title: "searchNotebooks" image: https://source.unsplash.com/400x175/?github description: API docs for the searchNotebooks plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchNotebooks'] --- import searchNotebooksObj from './search_notebooks.devdocs.json'; diff --git a/api_docs/search_playground.devdocs.json b/api_docs/search_playground.devdocs.json index e5f8ac16bd1a3..d72547a8ff2d6 100644 --- a/api_docs/search_playground.devdocs.json +++ b/api_docs/search_playground.devdocs.json @@ -277,6 +277,54 @@ "initialIsOpen": false } ], - "objects": [] + "objects": [ + { + "parentPluginId": "searchPlayground", + "id": "def-common.DEFAULT_PAGINATION", + "type": "Object", + "tags": [], + "label": "DEFAULT_PAGINATION", + "description": [], + "path": "x-pack/plugins/search_playground/common/index.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "searchPlayground", + "id": "def-common.DEFAULT_PAGINATION.from", + "type": "number", + "tags": [], + "label": "from", + "description": [], + "path": "x-pack/plugins/search_playground/common/index.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "searchPlayground", + "id": "def-common.DEFAULT_PAGINATION.size", + "type": "number", + "tags": [], + "label": "size", + "description": [], + "path": "x-pack/plugins/search_playground/common/index.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "searchPlayground", + "id": "def-common.DEFAULT_PAGINATION.total", + "type": "number", + "tags": [], + "label": "total", + "description": [], + "path": "x-pack/plugins/search_playground/common/index.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ] } } \ No newline at end of file diff --git a/api_docs/search_playground.mdx b/api_docs/search_playground.mdx index 9bbc096d212d1..17a5889c0b041 100644 --- a/api_docs/search_playground.mdx +++ b/api_docs/search_playground.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/searchPlayground title: "searchPlayground" image: https://source.unsplash.com/400x175/?github description: API docs for the searchPlayground plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'searchPlayground'] --- import searchPlaygroundObj from './search_playground.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-ki | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 17 | 0 | 11 | 1 | +| 21 | 0 | 15 | 1 | ## Client @@ -41,6 +41,9 @@ Contact [@elastic/search-kibana](https://github.com/orgs/elastic/teams/search-ki ## Common +### Objects + + ### Consts, variables and types diff --git a/api_docs/security.devdocs.json b/api_docs/security.devdocs.json index 907b33cf37b97..5944ca9374215 100644 --- a/api_docs/security.devdocs.json +++ b/api_docs/security.devdocs.json @@ -5914,23 +5914,23 @@ }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts" + "path": "x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts" + "path": "x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/lib/auth/api_key/api_key.ts" + "path": "x-pack/plugins/entity_manager/server/lib/auth/api_key/api_key.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/enable.ts" + "path": "x-pack/plugins/entity_manager/server/routes/enablement/enable.ts" }, { "plugin": "entityManager", - "path": "x-pack/plugins/observability_solution/entity_manager/server/routes/enablement/disable.ts" + "path": "x-pack/plugins/entity_manager/server/routes/enablement/disable.ts" }, { "plugin": "serverlessSearch", diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 550367e4ff248..64cf5ea06fa2e 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 9d4957972ff47..e9a4783e5dfb0 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -485,7 +485,7 @@ "\nExperimental flag needed to enable the link" ], "signature": [ - "\"assistantKnowledgeBaseByDefault\" | \"assistantModelEvaluation\" | \"assistantBedrockChat\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionUploadEnabled\" | \"automatedProcessActionsEnabled\" | \"responseActionsSentinelOneV1Enabled\" | \"responseActionsSentinelOneV2Enabled\" | \"responseActionsSentinelOneGetFileEnabled\" | \"responseActionsSentinelOneKillProcessEnabled\" | \"responseActionsSentinelOneProcessesEnabled\" | \"responseActionsCrowdstrikeManualHostIsolationEnabled\" | \"securitySolutionNotesEnabled\" | \"entityAlertPreviewDisabled\" | \"newUserDetailsFlyoutManagedUser\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"crowdstrikeDataInAnalyzerEnabled\" | \"jamfDataInAnalyzerEnabled\" | \"timelineEsqlTabDisabled\" | \"unifiedComponentsInTimelineDisabled\" | \"analyzerDatePickersAndSourcererDisabled\" | \"prebuiltRulesCustomizationEnabled\" | \"malwareOnWriteScanOptionAvailable\" | \"unifiedManifestEnabled\" | \"valueListItemsModalEnabled\" | \"manualRuleRunEnabled\" | \"filterProcessDescendantsForEventFiltersEnabled\" | \"dataIngestionHubEnabled\" | undefined" + "\"assistantKnowledgeBaseByDefault\" | \"assistantModelEvaluation\" | \"assistantBedrockChat\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionUploadEnabled\" | \"automatedProcessActionsEnabled\" | \"responseActionsSentinelOneV1Enabled\" | \"responseActionsSentinelOneV2Enabled\" | \"responseActionsSentinelOneGetFileEnabled\" | \"responseActionsSentinelOneKillProcessEnabled\" | \"responseActionsSentinelOneProcessesEnabled\" | \"responseActionsCrowdstrikeManualHostIsolationEnabled\" | \"securitySolutionNotesEnabled\" | \"entityAlertPreviewDisabled\" | \"newUserDetailsFlyoutManagedUser\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"crowdstrikeDataInAnalyzerEnabled\" | \"jamfDataInAnalyzerEnabled\" | \"timelineEsqlTabDisabled\" | \"unifiedComponentsInTimelineDisabled\" | \"analyzerDatePickersAndSourcererDisabled\" | \"prebuiltRulesCustomizationEnabled\" | \"malwareOnWriteScanOptionAvailable\" | \"unifiedManifestEnabled\" | \"valueListItemsModalEnabled\" | \"manualRuleRunEnabled\" | \"filterProcessDescendantsForEventFiltersEnabled\" | \"dataIngestionHubEnabled\" | \"entityStoreEnabled\" | undefined" ], "path": "x-pack/plugins/security_solution/public/common/links/types.ts", "deprecated": false, @@ -565,7 +565,7 @@ "\nExperimental flag needed to disable the link. Opposite of experimentalKey" ], "signature": [ - "\"assistantKnowledgeBaseByDefault\" | \"assistantModelEvaluation\" | \"assistantBedrockChat\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionUploadEnabled\" | \"automatedProcessActionsEnabled\" | \"responseActionsSentinelOneV1Enabled\" | \"responseActionsSentinelOneV2Enabled\" | \"responseActionsSentinelOneGetFileEnabled\" | \"responseActionsSentinelOneKillProcessEnabled\" | \"responseActionsSentinelOneProcessesEnabled\" | \"responseActionsCrowdstrikeManualHostIsolationEnabled\" | \"securitySolutionNotesEnabled\" | \"entityAlertPreviewDisabled\" | \"newUserDetailsFlyoutManagedUser\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"crowdstrikeDataInAnalyzerEnabled\" | \"jamfDataInAnalyzerEnabled\" | \"timelineEsqlTabDisabled\" | \"unifiedComponentsInTimelineDisabled\" | \"analyzerDatePickersAndSourcererDisabled\" | \"prebuiltRulesCustomizationEnabled\" | \"malwareOnWriteScanOptionAvailable\" | \"unifiedManifestEnabled\" | \"valueListItemsModalEnabled\" | \"manualRuleRunEnabled\" | \"filterProcessDescendantsForEventFiltersEnabled\" | \"dataIngestionHubEnabled\" | undefined" + "\"assistantKnowledgeBaseByDefault\" | \"assistantModelEvaluation\" | \"assistantBedrockChat\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionUploadEnabled\" | \"automatedProcessActionsEnabled\" | \"responseActionsSentinelOneV1Enabled\" | \"responseActionsSentinelOneV2Enabled\" | \"responseActionsSentinelOneGetFileEnabled\" | \"responseActionsSentinelOneKillProcessEnabled\" | \"responseActionsSentinelOneProcessesEnabled\" | \"responseActionsCrowdstrikeManualHostIsolationEnabled\" | \"securitySolutionNotesEnabled\" | \"entityAlertPreviewDisabled\" | \"newUserDetailsFlyoutManagedUser\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | \"riskEnginePrivilegesRouteEnabled\" | \"sentinelOneDataInAnalyzerEnabled\" | \"sentinelOneManualHostActionsEnabled\" | \"crowdstrikeDataInAnalyzerEnabled\" | \"jamfDataInAnalyzerEnabled\" | \"timelineEsqlTabDisabled\" | \"unifiedComponentsInTimelineDisabled\" | \"analyzerDatePickersAndSourcererDisabled\" | \"prebuiltRulesCustomizationEnabled\" | \"malwareOnWriteScanOptionAvailable\" | \"unifiedManifestEnabled\" | \"valueListItemsModalEnabled\" | \"manualRuleRunEnabled\" | \"filterProcessDescendantsForEventFiltersEnabled\" | \"dataIngestionHubEnabled\" | \"entityStoreEnabled\" | undefined" ], "path": "x-pack/plugins/security_solution/public/common/links/types.ts", "deprecated": false, @@ -1931,7 +1931,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly automatedProcessActionsEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly responseActionsSentinelOneV2Enabled: boolean; readonly responseActionsSentinelOneGetFileEnabled: boolean; readonly responseActionsSentinelOneKillProcessEnabled: boolean; readonly responseActionsSentinelOneProcessesEnabled: boolean; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: boolean; readonly securitySolutionNotesEnabled: boolean; readonly entityAlertPreviewDisabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantKnowledgeBaseByDefault: boolean; readonly assistantBedrockChat: boolean; readonly newUserDetailsFlyoutManagedUser: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly crowdstrikeDataInAnalyzerEnabled: boolean; readonly jamfDataInAnalyzerEnabled: boolean; readonly timelineEsqlTabDisabled: boolean; readonly unifiedComponentsInTimelineDisabled: boolean; readonly analyzerDatePickersAndSourcererDisabled: boolean; readonly prebuiltRulesCustomizationEnabled: boolean; readonly malwareOnWriteScanOptionAvailable: boolean; readonly unifiedManifestEnabled: boolean; readonly valueListItemsModalEnabled: boolean; readonly manualRuleRunEnabled: boolean; readonly filterProcessDescendantsForEventFiltersEnabled: boolean; readonly dataIngestionHubEnabled: boolean; }" + "{ readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly automatedProcessActionsEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly responseActionsSentinelOneV2Enabled: boolean; readonly responseActionsSentinelOneGetFileEnabled: boolean; readonly responseActionsSentinelOneKillProcessEnabled: boolean; readonly responseActionsSentinelOneProcessesEnabled: boolean; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: boolean; readonly securitySolutionNotesEnabled: boolean; readonly entityAlertPreviewDisabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantKnowledgeBaseByDefault: boolean; readonly assistantBedrockChat: boolean; readonly newUserDetailsFlyoutManagedUser: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly crowdstrikeDataInAnalyzerEnabled: boolean; readonly jamfDataInAnalyzerEnabled: boolean; readonly timelineEsqlTabDisabled: boolean; readonly unifiedComponentsInTimelineDisabled: boolean; readonly analyzerDatePickersAndSourcererDisabled: boolean; readonly prebuiltRulesCustomizationEnabled: boolean; readonly malwareOnWriteScanOptionAvailable: boolean; readonly unifiedManifestEnabled: boolean; readonly valueListItemsModalEnabled: boolean; readonly manualRuleRunEnabled: boolean; readonly filterProcessDescendantsForEventFiltersEnabled: boolean; readonly dataIngestionHubEnabled: boolean; readonly entityStoreEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/types.ts", "deprecated": false, @@ -2992,6 +2992,23 @@ "trackAdoption": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-server.SecuritySolutionApiRequestHandlerContext.getEntityStoreDataClient", + "type": "Function", + "tags": [], + "label": "getEntityStoreDataClient", + "description": [], + "signature": [ + "() => ", + "EntityStoreDataClient" + ], + "path": "x-pack/plugins/security_solution/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false @@ -3082,7 +3099,7 @@ "\nThe security solution generic experimental features" ], "signature": [ - "{ readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly automatedProcessActionsEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly responseActionsSentinelOneV2Enabled: boolean; readonly responseActionsSentinelOneGetFileEnabled: boolean; readonly responseActionsSentinelOneKillProcessEnabled: boolean; readonly responseActionsSentinelOneProcessesEnabled: boolean; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: boolean; readonly securitySolutionNotesEnabled: boolean; readonly entityAlertPreviewDisabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantKnowledgeBaseByDefault: boolean; readonly assistantBedrockChat: boolean; readonly newUserDetailsFlyoutManagedUser: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly crowdstrikeDataInAnalyzerEnabled: boolean; readonly jamfDataInAnalyzerEnabled: boolean; readonly timelineEsqlTabDisabled: boolean; readonly unifiedComponentsInTimelineDisabled: boolean; readonly analyzerDatePickersAndSourcererDisabled: boolean; readonly prebuiltRulesCustomizationEnabled: boolean; readonly malwareOnWriteScanOptionAvailable: boolean; readonly unifiedManifestEnabled: boolean; readonly valueListItemsModalEnabled: boolean; readonly manualRuleRunEnabled: boolean; readonly filterProcessDescendantsForEventFiltersEnabled: boolean; readonly dataIngestionHubEnabled: boolean; }" + "{ readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly automatedProcessActionsEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly responseActionsSentinelOneV2Enabled: boolean; readonly responseActionsSentinelOneGetFileEnabled: boolean; readonly responseActionsSentinelOneKillProcessEnabled: boolean; readonly responseActionsSentinelOneProcessesEnabled: boolean; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: boolean; readonly securitySolutionNotesEnabled: boolean; readonly entityAlertPreviewDisabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantKnowledgeBaseByDefault: boolean; readonly assistantBedrockChat: boolean; readonly newUserDetailsFlyoutManagedUser: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly crowdstrikeDataInAnalyzerEnabled: boolean; readonly jamfDataInAnalyzerEnabled: boolean; readonly timelineEsqlTabDisabled: boolean; readonly unifiedComponentsInTimelineDisabled: boolean; readonly analyzerDatePickersAndSourcererDisabled: boolean; readonly prebuiltRulesCustomizationEnabled: boolean; readonly malwareOnWriteScanOptionAvailable: boolean; readonly unifiedManifestEnabled: boolean; readonly valueListItemsModalEnabled: boolean; readonly manualRuleRunEnabled: boolean; readonly filterProcessDescendantsForEventFiltersEnabled: boolean; readonly dataIngestionHubEnabled: boolean; readonly entityStoreEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/server/plugin_contract.ts", "deprecated": false, @@ -3258,7 +3275,7 @@ "label": "ExperimentalFeatures", "description": [], "signature": [ - "{ readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly automatedProcessActionsEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly responseActionsSentinelOneV2Enabled: boolean; readonly responseActionsSentinelOneGetFileEnabled: boolean; readonly responseActionsSentinelOneKillProcessEnabled: boolean; readonly responseActionsSentinelOneProcessesEnabled: boolean; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: boolean; readonly securitySolutionNotesEnabled: boolean; readonly entityAlertPreviewDisabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantKnowledgeBaseByDefault: boolean; readonly assistantBedrockChat: boolean; readonly newUserDetailsFlyoutManagedUser: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly crowdstrikeDataInAnalyzerEnabled: boolean; readonly jamfDataInAnalyzerEnabled: boolean; readonly timelineEsqlTabDisabled: boolean; readonly unifiedComponentsInTimelineDisabled: boolean; readonly analyzerDatePickersAndSourcererDisabled: boolean; readonly prebuiltRulesCustomizationEnabled: boolean; readonly malwareOnWriteScanOptionAvailable: boolean; readonly unifiedManifestEnabled: boolean; readonly valueListItemsModalEnabled: boolean; readonly manualRuleRunEnabled: boolean; readonly filterProcessDescendantsForEventFiltersEnabled: boolean; readonly dataIngestionHubEnabled: boolean; }" + "{ readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly automatedProcessActionsEnabled: boolean; readonly responseActionsSentinelOneV1Enabled: boolean; readonly responseActionsSentinelOneV2Enabled: boolean; readonly responseActionsSentinelOneGetFileEnabled: boolean; readonly responseActionsSentinelOneKillProcessEnabled: boolean; readonly responseActionsSentinelOneProcessesEnabled: boolean; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: boolean; readonly securitySolutionNotesEnabled: boolean; readonly entityAlertPreviewDisabled: boolean; readonly assistantModelEvaluation: boolean; readonly assistantKnowledgeBaseByDefault: boolean; readonly assistantBedrockChat: boolean; readonly newUserDetailsFlyoutManagedUser: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; readonly riskEnginePrivilegesRouteEnabled: boolean; readonly sentinelOneDataInAnalyzerEnabled: boolean; readonly sentinelOneManualHostActionsEnabled: boolean; readonly crowdstrikeDataInAnalyzerEnabled: boolean; readonly jamfDataInAnalyzerEnabled: boolean; readonly timelineEsqlTabDisabled: boolean; readonly unifiedComponentsInTimelineDisabled: boolean; readonly analyzerDatePickersAndSourcererDisabled: boolean; readonly prebuiltRulesCustomizationEnabled: boolean; readonly malwareOnWriteScanOptionAvailable: boolean; readonly unifiedManifestEnabled: boolean; readonly valueListItemsModalEnabled: boolean; readonly manualRuleRunEnabled: boolean; readonly filterProcessDescendantsForEventFiltersEnabled: boolean; readonly dataIngestionHubEnabled: boolean; readonly entityStoreEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/common/experimental_features.ts", "deprecated": false, @@ -3324,7 +3341,7 @@ "\nA list of allowed values that can be used in `xpack.securitySolution.enableExperimental`.\nThis object is then used to validate and parse the value entered." ], "signature": [ - "{ readonly excludePoliciesInFilterEnabled: false; readonly kubernetesEnabled: true; readonly donutChartEmbeddablesEnabled: false; readonly previewTelemetryUrlEnabled: false; readonly extendedRuleExecutionLoggingEnabled: false; readonly socTrendsEnabled: false; readonly responseActionUploadEnabled: true; readonly automatedProcessActionsEnabled: true; readonly responseActionsSentinelOneV1Enabled: true; readonly responseActionsSentinelOneV2Enabled: true; readonly responseActionsSentinelOneGetFileEnabled: true; readonly responseActionsSentinelOneKillProcessEnabled: true; readonly responseActionsSentinelOneProcessesEnabled: true; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: true; readonly securitySolutionNotesEnabled: false; readonly entityAlertPreviewDisabled: false; readonly assistantModelEvaluation: false; readonly assistantKnowledgeBaseByDefault: false; readonly assistantBedrockChat: true; readonly newUserDetailsFlyoutManagedUser: false; readonly riskScoringPersistence: true; readonly riskScoringRoutesEnabled: true; readonly esqlRulesDisabled: false; readonly protectionUpdatesEnabled: true; readonly disableTimelineSaveTour: false; readonly riskEnginePrivilegesRouteEnabled: true; readonly sentinelOneDataInAnalyzerEnabled: true; readonly sentinelOneManualHostActionsEnabled: true; readonly crowdstrikeDataInAnalyzerEnabled: true; readonly jamfDataInAnalyzerEnabled: true; readonly timelineEsqlTabDisabled: false; readonly unifiedComponentsInTimelineDisabled: false; readonly analyzerDatePickersAndSourcererDisabled: false; readonly prebuiltRulesCustomizationEnabled: false; readonly malwareOnWriteScanOptionAvailable: true; readonly unifiedManifestEnabled: true; readonly valueListItemsModalEnabled: true; readonly manualRuleRunEnabled: false; readonly filterProcessDescendantsForEventFiltersEnabled: true; readonly dataIngestionHubEnabled: false; }" + "{ readonly excludePoliciesInFilterEnabled: false; readonly kubernetesEnabled: true; readonly donutChartEmbeddablesEnabled: false; readonly previewTelemetryUrlEnabled: false; readonly extendedRuleExecutionLoggingEnabled: false; readonly socTrendsEnabled: false; readonly responseActionUploadEnabled: true; readonly automatedProcessActionsEnabled: true; readonly responseActionsSentinelOneV1Enabled: true; readonly responseActionsSentinelOneV2Enabled: true; readonly responseActionsSentinelOneGetFileEnabled: true; readonly responseActionsSentinelOneKillProcessEnabled: true; readonly responseActionsSentinelOneProcessesEnabled: true; readonly responseActionsCrowdstrikeManualHostIsolationEnabled: true; readonly securitySolutionNotesEnabled: false; readonly entityAlertPreviewDisabled: false; readonly assistantModelEvaluation: false; readonly assistantKnowledgeBaseByDefault: false; readonly assistantBedrockChat: true; readonly newUserDetailsFlyoutManagedUser: false; readonly riskScoringPersistence: true; readonly riskScoringRoutesEnabled: true; readonly esqlRulesDisabled: false; readonly protectionUpdatesEnabled: true; readonly disableTimelineSaveTour: false; readonly riskEnginePrivilegesRouteEnabled: true; readonly sentinelOneDataInAnalyzerEnabled: true; readonly sentinelOneManualHostActionsEnabled: true; readonly crowdstrikeDataInAnalyzerEnabled: true; readonly jamfDataInAnalyzerEnabled: true; readonly timelineEsqlTabDisabled: false; readonly unifiedComponentsInTimelineDisabled: false; readonly analyzerDatePickersAndSourcererDisabled: false; readonly prebuiltRulesCustomizationEnabled: false; readonly malwareOnWriteScanOptionAvailable: true; readonly unifiedManifestEnabled: true; readonly valueListItemsModalEnabled: true; readonly manualRuleRunEnabled: false; readonly filterProcessDescendantsForEventFiltersEnabled: true; readonly dataIngestionHubEnabled: false; readonly entityStoreEnabled: false; }" ], "path": "x-pack/plugins/security_solution/common/experimental_features.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 53aa3877df819..f29726dbd34d6 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-solution](https://github.com/orgs/elastic/teams/secur | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 192 | 0 | 123 | 33 | +| 193 | 0 | 124 | 34 | ## Client diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index b093fd4d765c6..fe61cadf09229 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index a3eefbf9ccaee..ad11730eb31a5 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 52cffee88bcda..5cd6f453f8d5c 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index a323bc4580c74..578371d7001e1 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index 4428b3ceb59f5..aa7267091038c 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 43d2bec876682..0847e226105af 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 30b36cb134adf..598576f1cdfa0 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/slo.mdx b/api_docs/slo.mdx index 00c58dbf57ab5..b70c1e747ae0a 100644 --- a/api_docs/slo.mdx +++ b/api_docs/slo.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/slo title: "slo" image: https://source.unsplash.com/400x175/?github description: API docs for the slo plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'slo'] --- import sloObj from './slo.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 8e5e9891ebfec..d269c1b3af1d7 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index e584521cc85e1..33371f4f47945 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 7ee09695b7b2e..790efbf5374a3 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 3f8f7fc803c10..0561581697b11 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 7fbb7287d12ce..76019c9805427 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index e18eced7d7869..d43884b52534f 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 19b4d115bbe1f..acb89edaf4c99 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 39719302115f0..2a5427624cb9d 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 683518ca6a6ab..0417b055fcd03 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 1f9daa3d86635..6a58208b1e2b5 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 814bead03c066..0e31fced23c06 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 6d1102fd341f6..8273f11dae0f9 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 1980e77cfbfcc..f91da5fa700f2 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index b46f49ea8eb7f..8c6eacb0136b8 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index e40877f315f9b..097664846a4e9 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_doc_viewer.mdx b/api_docs/unified_doc_viewer.mdx index f118ba9c56651..a7b859205f5c5 100644 --- a/api_docs/unified_doc_viewer.mdx +++ b/api_docs/unified_doc_viewer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedDocViewer title: "unifiedDocViewer" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedDocViewer plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index af8f458b3a92b..85ea81bfdb46c 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index e398c6e2bce6e..d688d3c96d162 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 9a96a2613f452..0b757037ecba3 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index 8342013b10fca..82d7b41e0f45f 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 056f6c0440ee2..398bb21d351d5 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 4ec27a6c500c2..3b0cc19f36650 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 00136d67d47bf..f45a3b40ee698 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 33ef7cd83adf8..c6663cf7e98b7 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 41e7074607ed0..54ff5e7a8f8b6 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index c9616af6ad168..96492325a9f78 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index fb65c6216e1fb..84fadb67cec98 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index ff76e8dc2ba54..d7eb28809f855 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index 397ec16eb82a4..700eb7e011b23 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index 0c0202f8f4e3b..b2beddb119e10 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index b4f4ec879bd5b..0f33a50876e2c 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 8cc44e5783455..02229b8bf582a 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 4d9f3085c22b9..b07d6eb7bc5fb 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 123e96ab36e08..e8a1b8437756e 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2024-09-16 +date: 2024-09-17 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From d5b1fdf49af8eb23210e3b15a20fe1f9b660eea8 Mon Sep 17 00:00:00 2001 From: Robert Jaszczurek <92210485+rbrtj@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:53:32 +0200 Subject: [PATCH 055/139] [ML] Anomaly Explorer: Display markers for scheduled events in distribution type anomaly charts (#192377) ## Summary Fix for [#129304](https://github.com/elastic/kibana/issues/129304) Previously, for distribution type charts, we displayed calendar event markers only for anomalous data points. The changes improve the display of event markers for such chart types, including showing calendar event markers even when there is no underlying data point. | Scenario | Before | After | | :---: | :---: | :---: | | Rare chart | ![image](https://github.com/user-attachments/assets/c3e186c0-0ec8-434f-a845-3f9e703431dd) | ![image](https://github.com/user-attachments/assets/3dd51cd1-6972-4343-bbc8-8e5f38d7c6bd) | | Population chart | ![Zrzut ekranu 2024-09-9 o 16 16 01](https://github.com/user-attachments/assets/df22dc40-3c8b-46fe-9a5a-02a41278245c) | ![image](https://github.com/user-attachments/assets/c198e75e-14c8-4194-9d71-2358d25f21d5) | | Single metric chart (no difference) | ![image](https://github.com/user-attachments/assets/d0546ba0-46b1-4d2e-9976-fe49bcd4d2da) | ![image](https://github.com/user-attachments/assets/c11ec696-b1f4-4ddf-9542-037b8dd2d31f) | --- x-pack/plugins/ml/common/constants/charts.ts | 2 ++ .../explorer_chart_distribution.js | 32 ++++++++++++++++--- .../models/results_service/anomaly_charts.ts | 16 ++++++++-- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/ml/common/constants/charts.ts b/x-pack/plugins/ml/common/constants/charts.ts index 046504a44177a..b2e9a8493b56f 100644 --- a/x-pack/plugins/ml/common/constants/charts.ts +++ b/x-pack/plugins/ml/common/constants/charts.ts @@ -13,3 +13,5 @@ export const CHART_TYPE = { } as const; export type ChartType = (typeof CHART_TYPE)[keyof typeof CHART_TYPE]; + +export const SCHEDULE_EVENT_MARKER_ENTITY = 'schedule_event_marker_entity'; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js index 58052f5f35a65..79e8bd449876e 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_chart_distribution.js @@ -40,6 +40,7 @@ import { CHART_TYPE } from '../explorer_constants'; import { CHART_HEIGHT, TRANSPARENT_BACKGROUND } from './constants'; import { filter } from 'rxjs'; import { drawCursor } from './utils/draw_anomaly_explorer_charts_cursor'; +import { SCHEDULE_EVENT_MARKER_ENTITY } from '../../../../common/constants/charts'; const CONTENT_WRAPPER_HEIGHT = 215; const SCHEDULED_EVENT_MARKER_HEIGHT = 5; @@ -158,12 +159,29 @@ export class ExplorerChartDistribution extends React.Component { .key((d) => d.entity) .entries(chartData) .sort((a, b) => { + // To display calendar event markers we populate the chart with fake data points. + // If a category has fake data points, it should be sorted to the end. + const aHasFakeData = a.values.some((d) => d.entity === SCHEDULE_EVENT_MARKER_ENTITY); + const bHasFakeData = b.values.some((d) => d.entity === SCHEDULE_EVENT_MARKER_ENTITY); + + if (aHasFakeData && !bHasFakeData) { + return 1; + } + + if (bHasFakeData && !aHasFakeData) { + return -1; + } + return b.values.length - a.values.length; }) .filter((d, i) => { // only filter for rare charts if (chartType === CHART_TYPE.EVENT_DISTRIBUTION) { - return i < categoryLimit || d.key === highlight; + return ( + i < categoryLimit || + d.key === highlight || + d.values.some((d) => d.entity === SCHEDULE_EVENT_MARKER_ENTITY) + ); } return true; }) @@ -373,7 +391,8 @@ export class ExplorerChartDistribution extends React.Component { .orient('left') .innerTickSize(0) .outerTickSize(0) - .tickPadding(10); + .tickPadding(10) + .tickFormat((d) => (d === SCHEDULE_EVENT_MARKER_ENTITY ? null : d)); if (fieldFormat !== undefined) { yAxis.tickFormat((d) => fieldFormat.convert(d, 'text')); @@ -518,7 +537,8 @@ export class ExplorerChartDistribution extends React.Component { const tooltipData = [{ label: formattedDate }]; const seriesKey = config.detectorLabel; - if (marker.entity !== undefined) { + // Hide entity for scheduled events with mocked value. + if (marker.entity !== undefined && marker.entity !== SCHEDULE_EVENT_MARKER_ENTITY) { tooltipData.push({ label: i18n.translate('xpack.ml.explorer.distributionChart.entityLabel', { defaultMessage: 'entity', @@ -590,7 +610,11 @@ export class ExplorerChartDistribution extends React.Component { }); } } - } else if (chartType !== CHART_TYPE.EVENT_DISTRIBUTION) { + } else if ( + chartType !== CHART_TYPE.EVENT_DISTRIBUTION && + // Hide value for scheduled events with mocked value. + marker.entity !== SCHEDULE_EVENT_MARKER_ENTITY + ) { tooltipData.push({ label: i18n.translate( 'xpack.ml.explorer.distributionChart.valueWithoutAnomalyScoreLabel', diff --git a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts index 8d14417a1d383..7e551b0624261 100644 --- a/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts +++ b/x-pack/plugins/ml/server/models/results_service/anomaly_charts.ts @@ -53,7 +53,7 @@ import { parseInterval } from '../../../common/util/parse_interval'; import { getDatafeedAggregations } from '../../../common/util/datafeed_utils'; import { findAggField } from '../../../common/util/validation_utils'; import type { ChartType } from '../../../common/constants/charts'; -import { CHART_TYPE } from '../../../common/constants/charts'; +import { CHART_TYPE, SCHEDULE_EVENT_MARKER_ENTITY } from '../../../common/constants/charts'; import { getChartType } from '../../../common/util/chart_utils'; import type { MlJob } from '../..'; @@ -1124,9 +1124,19 @@ export function anomalyChartsDataProvider(mlClient: MlClient, client: IScopedClu each(scheduledEvents, (events, time) => { const chartPoint = findChartPointForTime(chartDataForPointSearch, Number(time)); if (chartPoint !== undefined) { - // Note if the scheduled event coincides with an absence of the underlying metric data, - // we don't worry about plotting the event. chartPoint.scheduledEvents = events; + // We do not want to create additional points for single metric charts + // as it could break the chart. + } else if (chartType !== CHART_TYPE.SINGLE_METRIC) { + // If there's no underlying metric data point for the scheduled event, + // create a new chart point with a value of 0. + const eventChartPoint: ChartPoint = { + date: Number(time), + value: 0, + entity: SCHEDULE_EVENT_MARKER_ENTITY, + scheduledEvents: events, + }; + chartData.push(eventChartPoint); } }); } From 1ae7548c655c47f045923b8671ff8c61b04ca154 Mon Sep 17 00:00:00 2001 From: Tomasz Ciecierski Date: Tue, 17 Sep 2024 10:00:38 +0200 Subject: [PATCH 056/139] [EDR Workflows] Crowdstrike - Add more routes and responses to mocked server (#192881) --- .../emulator_plugins/crowdstrike/mocks.ts | 148 ++++--- .../routes/batch_init_rtr_route.ts | 99 +++++ .../routes/batch_refresh_rtr_session_route.ts | 56 +++ .../routes/batch_rtr_command_route.ts | 169 +++++++ .../routes/get_agent_details_route.ts | 23 + .../routes/get_rtr_command_details_route.ts | 61 +++ .../routes/get_scripts_details_route.ts | 80 ++++ .../routes/get_scripts_ids_route.ts | 36 ++ .../crowdstrike/routes/get_token_route.ts | 13 +- .../crowdstrike/routes/host_actions_route.ts | 26 +- .../crowdstrike/routes/index.ts | 20 + .../crowdstrike/routes/init_rtr_route.ts | 413 ++++++++++++++++++ .../routes/refresh_rtr_session_route.ts | 392 +++++++++++++++++ .../crowdstrike/routes/rtr_admin_route.ts | 264 +++++++++++ .../crowdstrike/routes/rtr_command_route.ts | 137 ++++++ .../crowdstrike/routes/utils.ts | 7 + 16 files changed, 1875 insertions(+), 69 deletions(-) create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_init_rtr_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_refresh_rtr_session_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_rtr_command_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_rtr_command_details_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_details_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_ids_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/init_rtr_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/refresh_rtr_session_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_admin_route.ts create mode 100644 x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_command_route.ts diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/mocks.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/mocks.ts index e915a16c250b0..d79d683877524 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/mocks.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/mocks.ts @@ -10,6 +10,7 @@ import type { CrowdstrikeGetAgentsResponse, } from '@kbn/stack-connectors-plugin/common/crowdstrike/types'; import { merge } from 'lodash'; +import { TEST_AGENT_ID, TEST_CID_ID } from './routes/utils'; export const createCrowdstrikeGetAgentsApiResponseMock = ( data: CrowdstrikeBaseApiResponse['resources'][number] @@ -18,55 +19,66 @@ export const createCrowdstrikeGetAgentsApiResponseMock = ( meta: { query_time: 0.001831479, powered_by: 'device-api', - trace_id: '4567898765-432423432432-42342342', + trace_id: 'xxx', }, errors: null, resources: data, }; }; +export const createCrowdstrikeErrorResponseMock = (error: object) => { + return { + meta: { + query_time: 0.001831479, + powered_by: 'device-api', + trace_id: 'xxx', + }, + errors: [error], + }; +}; + export const createCrowdstrikeAgentDetailsMock = ( overrides: Partial = {} ): CrowdstrikeGetAgentsResponse['resources'][number] => { return merge( { - device_id: '5f4ed7ec2690431f8fa79213268779cb', - cid: '234567890', + device_id: TEST_AGENT_ID, + cid: TEST_CID_ID, agent_load_flags: '0', - agent_local_time: '2024-03-18T22:21:00.173Z', - agent_version: '7.07.16206.0', - bios_manufacturer: 'Amazon EC2', - bios_version: '1.0', - config_id_base: '65994753', - config_id_build: '16206', - config_id_platform: '8', - cpu_signature: '8392466', - cpu_vendor: '1', - external_ip: '18.157.150.216', - mac_address: '03-f4-f4-f4-f4', - instance_id: 'i-456789', - service_provider: 'AWS_EC2_V2', - service_provider_account_id: '23456789', - hostname: 'Crowdstrike-1460', - first_seen: '2024-03-15T13:18:56Z', - last_login_timestamp: '2024-03-15T22:11:47Z', - last_login_user: 'testuser', - last_login_uid: '1002', - last_seen: '2024-03-20T07:19:01Z', - local_ip: '172.31.200.45', - major_version: '5', - minor_version: '14', - os_version: 'RHEL 9.3', + agent_local_time: '2024-09-08T06:07:00.326Z', + agent_version: '7.18.17106.0', + bios_manufacturer: 'EFI Development Kit II / OVMF', + bios_version: '0.0.0', + config_id_base: '65994763', + config_id_build: '17106', + config_id_platform: '128', + cpu_signature: '4294967295', + cpu_vendor: '3', + external_ip: '79.184.246.19', + mac_address: '52-54-00-09-42-a6', + hostname: 'cs-falcon', + filesystem_containment_status: 'normal', + first_login_timestamp: '2024-08-19T08:37:15Z', + first_login_user: 'ubuntu', + first_seen: '2024-08-19T08:37:17Z', + last_login_timestamp: '2024-08-19T08:37:15Z', + last_login_user: 'ubuntu', + last_login_uid: '1000', + last_seen: '2024-09-10T09:32:58Z', + local_ip: '192.168.80.7', + major_version: '6', + minor_version: '8', + os_version: 'Ubuntu 24.04', platform_id: '3', platform_name: 'Linux', policies: [ { policy_type: 'prevention', - policy_id: '234234234234', + policy_id: 'test_prevention_policy_id', applied: true, - settings_hash: 'f0e04444', - assigned_date: '2024-03-15T13:20:02.25821602Z', - applied_date: '2024-03-15T13:20:16.804783955Z', + settings_hash: 'test2984', + assigned_date: '2024-08-19T08:40:24.454802663Z', + applied_date: '2024-08-19T08:46:46.169115065Z', rule_groups: [], }, ], @@ -74,61 +86,67 @@ export const createCrowdstrikeAgentDetailsMock = ( device_policies: { prevention: { policy_type: 'prevention', - policy_id: '234234234234', + policy_id: 'test_prevention_policy_id', applied: true, - settings_hash: 'f0e04444', - assigned_date: '2024-03-15T13:20:02.25821602Z', - applied_date: '2024-03-15T13:20:16.804783955Z', + settings_hash: 'test2984', + assigned_date: '2024-08-19T08:40:24.454802663Z', + applied_date: '2024-08-19T08:46:46.169115065Z', rule_groups: [], }, sensor_update: { policy_type: 'sensor-update', - policy_id: '234234234234', + policy_id: 'test_sensor_update_policy_id', applied: true, - settings_hash: 'tagged|5;', - assigned_date: '2024-03-15T13:20:02.258765734Z', - applied_date: '2024-03-15T13:23:53.773752711Z', + settings_hash: 'test3a5bb', + assigned_date: '2024-08-19T08:40:24.406563043Z', + applied_date: '2024-08-19T08:44:54.277815271Z', uninstall_protection: 'UNKNOWN', }, global_config: { policy_type: 'globalconfig', - policy_id: '234234234234', + policy_id: 'test_global_config_policy_id', applied: true, - settings_hash: 'f0e04444', - assigned_date: '2024-03-18T22:21:01.50638371Z', - applied_date: '2024-03-18T22:21:30.565040189Z', + settings_hash: 'testa5bc', + assigned_date: '2024-09-08T04:54:07.410501178Z', + applied_date: '2024-09-08T04:55:06.81648557Z', }, remote_response: { policy_type: 'remote-response', - policy_id: '234234234234', + policy_id: 'test_remote_response_policy_id', + applied: true, + settings_hash: 'test205c', + assigned_date: '2024-08-19T08:48:00.144480664Z', + applied_date: '2024-08-19T08:55:01.036602542Z', + }, + 'host-retention': { + policy_type: 'host-retention', + policy_id: 'test_host-retention_policy_id', applied: true, - settings_hash: 'f0e04444', - assigned_date: '2024-03-15T13:20:02.258285018Z', - applied_date: '2024-03-15T13:20:17.016591803Z', + settings_hash: 'testfghjk', + assigned_date: '2024-08-19T08:40:24.444810716Z', + applied_date: '2024-08-19T08:44:54.577562462Z', }, }, - groups: [], - group_hash: '45678909876545678', + groups: ['test123', 'test456'], + group_hash: 'test123', product_type_desc: 'Server', - provision_status: 'NotProvisioned', - serial_number: '345678765-35d6-e704-1723-423423432', - status: 'containment_pending', - system_manufacturer: 'Amazon EC2', - system_product_name: 't3a.medium', + provision_status: 'Provisioned', + status: 'normal', + system_manufacturer: 'QEMU', + system_product_name: 'QEMU Virtual Machine', tags: [], - modified_timestamp: '2024-03-20T07:19:45Z', + modified_timestamp: '2024-09-10T09:33:21Z', meta: { - version: '484', - version_string: '9:33384301139', + version: '552', + version_string: '1:1815077394', }, - zone_group: 'eu-central-1a', - kernel_version: '5.14.0-234234el9_3.x86_64', + kernel_version: '6.8.0-41-generic', chassis_type: '1', chassis_type_desc: 'Other', - connection_ip: '172.31.200.45', - default_gateway_ip: '172.31.200.1', - connection_mac_address: '02-e8-f1-0e-b7-c4', - linux_sensor_mode: 'Kernel Mode', + connection_ip: '192.168.80.7', + default_gateway_ip: '192.168.80.1', + connection_mac_address: '52-54-00-09-42-a6', + linux_sensor_mode: 'User Mode', deployment_type: 'Standard', }, overrides @@ -140,8 +158,10 @@ export const createCrowdstrikeGetAgentOnlineStatusDetailsMock: ( ) => CrowdstrikeGetAgentOnlineStatusResponse['resources'][number] = (overrides) => { return merge( { + id: TEST_AGENT_ID, + cid: TEST_CID_ID, + last_seen: '2024-09-10T09:59:56Z', state: 'online', - id: '5f4ed7ec2690431f8fa79213268779cb', }, overrides ); diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_init_rtr_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_init_rtr_route.ts new file mode 100644 index 0000000000000..940ad4d127d4e --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_init_rtr_route.ts @@ -0,0 +1,99 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_AGENT_ID, TEST_BATCH_ID, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const batchInitRTRSessionRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/combined/batch-init-session/v1'), + method: 'POST', + handler: batchInitSessionSuccessHandler, + }; +}; +// @ts-expect-error - example of error response +const initSessionWrongHostIdError = async () => { + return { + meta: { + query_time: 0.244284399, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + batch_id: '', + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 500, + message: `uuid: incorrect UUID length 47 in string ${TEST_AGENT_ID}`, + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + errors: [ + { + code: 404, + message: 'no successful hosts initialized on RTR', + }, + ], + }; +}; +// @ts-expect-error - example of error response +const initSessionMissingIdsError = async () => { + return { + meta: { + query_time: 0.00034664, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + batch_id: '', + resources: {}, + errors: [ + { + code: 400, + message: + 'Invalid number of hosts in request: 0. Must be an integer greater than 0 and less than or equal to 10000', + }, + ], + }; +}; + +const batchInitSessionSuccessHandler: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 1.067267552, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + batch_id: TEST_BATCH_ID, + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '/', + stderr: '', + base_command: 'pwd', + aid: TEST_AGENT_ID, + errors: [], + query_time: 0, + offline_queued: false, + }, + }, + errors: [], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_refresh_rtr_session_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_refresh_rtr_session_route.ts new file mode 100644 index 0000000000000..0b7ae5b6f4e19 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_refresh_rtr_session_route.ts @@ -0,0 +1,56 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_AGENT_ID, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const batchRTRRefreshSessionRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/combined/batch-refresh-session/v1'), + method: 'POST', + handler: batchRTRRefreshSessionHandler, + }; +}; + +// @ts-expect-error - example of error response +const batchRTRRefreshSessionInvalidSessionError = async () => { + return { + meta: { + query_time: 0.001031577, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: {}, + errors: [ + { + code: 400, + message: 'no hosts in this batch session', + }, + ], + }; +}; + +const batchRTRRefreshSessionHandler: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 0.068379923, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: { + [TEST_AGENT_ID]: { + aid: TEST_AGENT_ID, + session_id: TEST_SESSION_ID, + errors: [], + }, + }, + errors: [], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_rtr_command_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_rtr_command_route.ts new file mode 100644 index 0000000000000..07f5ad927b3d4 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/batch_rtr_command_route.ts @@ -0,0 +1,169 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_AGENT_ID, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const batchRTRCommandRoute = (): EmulatorServerRouteDefinition => { + return { + // we use `combined` api - which returns just one complete response, otherwise it would be coming in batches + path: buildCrowdstrikeRoutePath('/real-time-response/combined/batch-command/v1'), + method: 'POST', + handler: batchRTRCommandSuccessHandler, + }; +}; + +// @ts-expect-error - example of missing file error +const batchCommandResponseWithError = async () => { + return { + meta: { + query_time: 0.913513625, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '', + stderr: 'cat: test.xt: No such file or directory', + base_command: 'cat', + aid: TEST_AGENT_ID, + errors: [], + query_time: 0.912058582, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// @ts-expect-error - example of error response +const batchCommandResponseInvalidCommandError = async () => { + return { + meta: { + query_time: 0.101208469, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 40007, + message: 'Command not found', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// @ts-expect-error - example of error response +const batchCommandInvalidSessionError = async () => { + return { + meta: { + query_time: 0.02078217, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 50007, + message: 'could not get session', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; +// @ts-expect-error - example of error response +const batchCommandCommandIsNotValidError = async () => { + return { + meta: { + query_time: 0.122372386, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 40006, + message: 'Command is not valid', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +const batchRTRCommandSuccessHandler: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 0.888750872, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: + 'bin\nbin.usr-is-merged\nboot\ndev\netc\nhome\nlib\nlib.usr-is-merged\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsbin.usr-is-merged\nsnap\nsrv\nsys\ntmp\nusr\nvar', + stderr: '', + base_command: 'ls', + aid: TEST_AGENT_ID, + errors: [], + query_time: 0.887764377, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_agent_details_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_agent_details_route.ts index 84e5f42783f3a..1734cda7e745e 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_agent_details_route.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_agent_details_route.ts @@ -21,6 +21,29 @@ export const getAgentDetailsRouteDefinition = (): EmulatorServerRouteDefinition }; }; +// @ts-expect-error - example of missing file error +const getAgentDetailsMissingIdsError = async () => { + return { + errors: [ + { + code: 400, + message: "The 'ids' parameter must be present at least once.", + }, + ], + }; +}; +// @ts-expect-error - example of missing file error +const getAgentDetailsInvalidIdsError = async () => { + return { + errors: [ + { + code: 400, + message: 'invalid device id [asdasd]', + }, + ], + }; +}; + const getAgentDetailsHandler: ExternalEdrServerEmulatorRouteHandlerMethod<{}> = async () => { return createCrowdstrikeGetAgentsApiResponseMock([createCrowdstrikeAgentDetailsMock({})]); }; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_rtr_command_details_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_rtr_command_details_route.ts new file mode 100644 index 0000000000000..3028d2910c7c4 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_rtr_command_details_route.ts @@ -0,0 +1,61 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const getRTRCommandDetailsRoute = (): EmulatorServerRouteDefinition => { + return { + // PARAMS /v1?cloud_request_id=test-cloud-request1&sequence_id=0 + path: buildCrowdstrikeRoutePath('/real-time-response/entities/command/v1'), + method: 'GET', + handler: getRTRCommandDetailsSuccessHandler, + }; +}; + +// @ts-expect-error - example of missing file error +const commandDetailsMissingCloudIdError = async () => { + return { + meta: { + query_time: 0.000238205, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [], + errors: [ + { + code: 400, + message: 'cloud_request_id must be a uuid string', + }, + ], + }; +}; + +const getRTRCommandDetailsSuccessHandler: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 0.307542055, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [ + { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: + 'archive\nbackup\nbin\nboot\ndev\necho\netc\nhome\nlib\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsnap\nsrv\nstuff.exe\nsys\ntest.sh\ntestPush.exe\ntmp\nusr\nvar\n', + stderr: '', + base_command: 'ls', + }, + ], + errors: [], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_details_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_details_route.ts new file mode 100644 index 0000000000000..38f57e1f7b0a8 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_details_route.ts @@ -0,0 +1,80 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const getCustomScriptsDetailsRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/entities/scripts/v1'), + method: 'GET', + handler: getCustomScriptsDetailsSuccessHandler, + }; +}; + +// @ts-expect-error - example of missing file error +const getScriptsIdEmptyResponse = async () => { + return { + meta: { + query_time: 0.025758121, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [], + }; +}; + +const getCustomScriptsDetailsSuccessHandler: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 0.531831172, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [ + { + id: 'test-id-1', + name: 'AnyDesk Remediation', + file_type: 'script', + platform: ['windows'], + size: 1979, + content: 'echo "AnyDesk Remediation"', + created_by: 'testuser@test.com', + created_by_uuid: '34d10-a0f7e5dc98a8', + created_timestamp: '2023-08-01T05:20:10.695182885Z', + modified_by: 'testuser@test.com', + modified_timestamp: '2023-08-01T05:20:10.695183074Z', + sha256: 'test58f74e15e56815d71b29450f077df2f6070630184b9d', + permission_type: 'public', + run_attempt_count: 67, + run_success_count: 0, + write_access: true, + }, + { + id: 'test-id-2', + name: 'Gather AnyDesk Artifacts', + file_type: 'script', + platform: ['windows'], + size: 1184, + content: 'echo Gather Anydesk Artifacts', + created_by: 'testuser@test.com', + created_by_uuid: '34d0610-a0f7e5dc98a8', + created_timestamp: '2023-08-17T07:08:00.839412392Z', + modified_by: 'testuser@test.com', + modified_timestamp: '2023-08-17T07:08:00.839412727Z', + sha256: 'teste8dfbb7cfb782c11484b47d336a93fdae80cffa77039c5', + permission_type: 'public', + run_attempt_count: 4, + run_success_count: 0, + write_access: true, + }, + ], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_ids_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_ids_route.ts new file mode 100644 index 0000000000000..71a6caf257ad0 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_scripts_ids_route.ts @@ -0,0 +1,36 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const getCustomScriptsIdsRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/queries/scripts/v1'), + method: 'GET', + handler: getCustomScriptsIdsHandler, + }; +}; + +const getCustomScriptsIdsHandler: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 0.030241162, + pagination: { + offset: 0, + limit: 100, + total: 11, + }, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: ['test-id-1', 'test-id-2'], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_token_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_token_route.ts index 6629c33974b04..8bc50860beb2a 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_token_route.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/get_token_route.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { createCrowdstrikeErrorResponseMock } from '../mocks'; import { buildCrowdstrikeRoutePath } from './utils'; import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; @@ -16,14 +17,18 @@ export const getTokenRouteDefinition = (): EmulatorServerRouteDefinition => { }; }; +// @ts-expect-error - example of missing token error +const getTokenError = async () => { + return createCrowdstrikeErrorResponseMock({ + code: 401, + message: 'access denied, invalid bearer token', + }); +}; + const getTokenHandler: ExternalEdrServerEmulatorRouteHandlerMethod<{}> = async () => { return { access_token: 'testtoken', expires_in: 123, token_type: 'bearer', - id_token: 'test', - issued_token_type: 'test', - refresh_token: 'test', - scope: 'test', }; }; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/host_actions_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/host_actions_route.ts index 2c648213a3f09..273285d519ded 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/host_actions_route.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/host_actions_route.ts @@ -17,6 +17,30 @@ export const hostActionsRouteDefinition = (): EmulatorServerRouteDefinition => { }; }; +// @ts-expect-error - example of missing action parameter error +const hostActionsMissingActionParameterError = async () => { + return { + errors: [ + { + code: 400, + message: "Provided data does not match expected 'Action Parameter' format", + }, + ], + }; +}; + +// @ts-expect-error - example of missing agent id error +const hostActionsInvalidAgentIdError = async () => { + return { + errors: [ + { + code: 404, + message: 'No matching device found for ID wrongAgentId', + }, + ], + }; +}; + const hostActionsHandler: ExternalEdrServerEmulatorRouteHandlerMethod< {}, CrowdstrikeHostActionsParams @@ -24,7 +48,7 @@ const hostActionsHandler: ExternalEdrServerEmulatorRouteHandlerMethod< return { resources: [ { - id: 'test', + id: 'test_id', path: 'test', }, ], diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/index.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/index.ts index 1da4f435aae4c..3be3fe20a2819 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/index.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/index.ts @@ -5,11 +5,21 @@ * 2.0. */ +import { rtrCommandRoute } from './rtr_command_route'; +import { batchRTRRefreshSessionRoute } from './batch_refresh_rtr_session_route'; +import { rtrAdminCommandRoute } from './rtr_admin_route'; +import { refreshRTRSessionRoute } from './refresh_rtr_session_route'; +import { getCustomScriptsDetailsRoute } from './get_scripts_details_route'; +import { initRTRSessionRoute } from './init_rtr_route'; +import { getRTRCommandDetailsRoute } from './get_rtr_command_details_route'; +import { batchRTRCommandRoute } from './batch_rtr_command_route'; +import { batchInitRTRSessionRoute } from './batch_init_rtr_route'; import { getTokenRouteDefinition } from './get_token_route'; import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; import { hostActionsRouteDefinition } from './host_actions_route'; import { getAgentDetailsRouteDefinition } from './get_agent_details_route'; import { getAgentOnlineStatusRouteDefinition } from './get_agent_online_status_route'; +import { getCustomScriptsIdsRoute } from './get_scripts_ids_route'; export const getCrowdstrikeRouteDefinitions = (): EmulatorServerRouteDefinition[] => { return [ @@ -17,5 +27,15 @@ export const getCrowdstrikeRouteDefinitions = (): EmulatorServerRouteDefinition[ hostActionsRouteDefinition(), getAgentDetailsRouteDefinition(), getAgentOnlineStatusRouteDefinition(), + batchInitRTRSessionRoute(), + batchRTRCommandRoute(), + getRTRCommandDetailsRoute(), + getCustomScriptsIdsRoute(), + getCustomScriptsDetailsRoute(), + initRTRSessionRoute(), + refreshRTRSessionRoute(), + rtrAdminCommandRoute(), + batchRTRRefreshSessionRoute(), + rtrCommandRoute(), ]; }; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/init_rtr_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/init_rtr_route.ts new file mode 100644 index 0000000000000..f16f166551356 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/init_rtr_route.ts @@ -0,0 +1,413 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_AGENT_ID, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const initRTRSessionRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/entities/sessions/v1'), + method: 'POST', + handler: initRTRSessionHandler, + }; +}; +// requestBody: +// { +// "device_id": "xxxxxx", +// "queue_offline": false +// } + +// @ts-expect-error - example of invalid agent id error +const initRTRSessionInvalidAgentIdError = async () => { + return { + meta: { + query_time: 0.244284399, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + batch_id: '', + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 500, + message: 'uuid: incorrect UUID length 47 in string "wrongAgentId"', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + errors: [ + { + code: 404, + message: 'no successful hosts initialized on RTR', + }, + ], + }; +}; + +// @ts-expect-error - example of missing agent id error +const initRTRSessionMissingAgentIdError = async () => { + return { + meta: { + query_time: 0.00034664, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + batch_id: '', + resources: {}, + errors: [ + { + code: 400, + message: + 'Invalid number of hosts in request: 0. Must be an integer greater than 0 and less than or equal to 10000', + }, + ], + }; +}; + +const initRTRSessionHandler: ExternalEdrServerEmulatorRouteHandlerMethod<{}, {}> = async () => { + return { + meta: { + query_time: 1.776937422, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [ + { + session_id: TEST_SESSION_ID, + scripts: [ + { + command: 'cat', + description: 'Read a file from disk and display as ASCII', + examples: 'cat foo.txt\r\ncat -n foo.txt\r\ncat -t foo.txt\r\ncat -t -n foo.txt', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 671, + created_at: '2020-09-22T00:54:20Z', + updated_at: '2020-09-22T00:54:20Z', + script_id: 94, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'path to cat', + default_value: '', + required: true, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 672, + created_at: '2020-09-22T00:54:20Z', + updated_at: '2020-09-22T00:54:20Z', + script_id: 94, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'n', + description: 'Number the output lines starting from 1', + default_value: '', + required: false, + sequence: 2, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 673, + created_at: '2020-09-22T00:54:20Z', + updated_at: '2020-09-22T00:54:20Z', + script_id: 94, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 't', + description: "Display non-printing characters, and display tab characters as `^I'.", + default_value: '', + required: false, + sequence: 3, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'cd', + description: 'Change the current working directory', + examples: '', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 674, + created_at: '2020-09-22T00:54:07Z', + updated_at: '2020-09-22T00:54:07Z', + script_id: 95, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'path', + default_value: '', + required: true, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'env', + description: 'Print out the environment', + examples: 'env', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'filehash', + description: 'Generate the MD5, SHA1, and SHA256 hashes of a file', + examples: 'filehash /tmp/test', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 680, + created_at: '2020-09-22T00:53:36Z', + updated_at: '2020-09-22T00:53:36Z', + script_id: 100, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'File to hash', + default_value: '', + required: true, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'ifconfig', + description: 'Show network configuration information', + examples: 'ifconfig', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'ls', + description: 'Display the contents of the specified path', + examples: + 'ls\r\nls -l\r\nls -L\r\nls -t\r\nls -l -@\r\nls -R\r\nls -l -R\r\nls -l -t -R -L', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 684, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'Path', + default_value: '.', + required: false, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 685, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'l', + description: 'List in long format.', + default_value: '', + required: false, + sequence: 2, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 686, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'L', + description: + 'Follow all symbolic links to final target and list the file or directory the link references rather than the link itself.', + default_value: '', + required: false, + sequence: 3, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 687, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'R', + description: 'Recursively list subdirectories encountered.', + default_value: '', + required: false, + sequence: 4, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 688, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 't', + description: + 'Sort by time modified (most recently modified first) before sorting the operands by lexicographical order.', + default_value: '', + required: false, + sequence: 5, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'mount', + description: 'List or mount filesystem volumes', + examples: + 'Executable by all RTR roles:\r\nmount\r\nExecutable by privileged RTR users only:\r\nmount -t=nfs "host:/exports/filesystem" "/mnt/filesystem"\r\n Mount the NFS filesystem located at "/exports/filesystem" on "host" to the local destination "/mnt/filesystem"\r\nmount -t=smbfs "//user:password@host/filesystem" "/mnt/mountpoint"\r\n Mount the SMB "/filesystem" on "host" as "user" with "password" to "/mnt/mountpoint"\r\nmount -t=smbfs -o=nobrowse "//user:password@host/filesystem" "/mnt/mountpoint"\r\n Mount the SMB "/filesystem" with option "nobrowse" on "host" as "user" with "password" to "/mnt/mountpoint"', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'netstat', + description: 'Display routing information or network connections', + examples: 'netstat\r\nnetstat -nr', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 699, + created_at: '2020-09-22T00:52:52Z', + updated_at: '2020-09-22T00:52:52Z', + script_id: 108, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'nr', + description: 'Flag to show routing information', + default_value: '', + required: false, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'ps', + description: 'Display process information', + examples: 'ps', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'pwd', + description: 'Prints present working directory', + examples: '', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'users', + description: 'Get details about local users', + examples: + 'users\r\n List details about all local users\r\nusers foo\r\n List details about local user "foo"', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 719, + created_at: '2023-03-15T00:28:54Z', + updated_at: '2023-03-15T00:28:54Z', + script_id: 117, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'UserName', + description: 'Username to filter results', + default_value: '', + required: false, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + ], + existing_aid_sessions: 1, + created_at: '2024-09-12T07:22:55.684322249Z', + pwd: '/', + offline_queued: false, + }, + ], + errors: null, + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/refresh_rtr_session_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/refresh_rtr_session_route.ts new file mode 100644 index 0000000000000..77908faf55246 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/refresh_rtr_session_route.ts @@ -0,0 +1,392 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_AGENT_ID, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const refreshRTRSessionRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/entities/refresh-session/v1'), + method: 'POST', + handler: refreshRTRSessionHandler, + }; +}; +// requestBody: +// { +// "device_id": "xxxxxx", +// "queue_offline": false +// } + +// @ts-expect-error - example of invalid agent id error +const refreshRTRSessionInvalidAgentIdError = async () => { + return { + meta: { + query_time: 0.244284399, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + batch_id: '', + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 500, + message: 'uuid: incorrect UUID length 47 in string "wrongAgentId"', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + errors: [ + { + code: 404, + message: 'no successful hosts initialized on RTR', + }, + ], + }; +}; + +const refreshRTRSessionHandler: ExternalEdrServerEmulatorRouteHandlerMethod<{}, {}> = async () => { + return { + meta: { + query_time: 0.098432609, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [ + { + session_id: TEST_SESSION_ID, + scripts: [ + { + command: 'cat', + description: 'Read a file from disk and display as ASCII', + examples: 'cat foo.txt\r\ncat -n foo.txt\r\ncat -t foo.txt\r\ncat -t -n foo.txt', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 671, + created_at: '2020-09-22T00:54:20Z', + updated_at: '2020-09-22T00:54:20Z', + script_id: 94, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'path to cat', + default_value: '', + required: true, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 672, + created_at: '2020-09-22T00:54:20Z', + updated_at: '2020-09-22T00:54:20Z', + script_id: 94, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'n', + description: 'Number the output lines starting from 1', + default_value: '', + required: false, + sequence: 2, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 673, + created_at: '2020-09-22T00:54:20Z', + updated_at: '2020-09-22T00:54:20Z', + script_id: 94, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 't', + description: "Display non-printing characters, and display tab characters as `^I'.", + default_value: '', + required: false, + sequence: 3, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'cd', + description: 'Change the current working directory', + examples: '', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 674, + created_at: '2020-09-22T00:54:07Z', + updated_at: '2020-09-22T00:54:07Z', + script_id: 95, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'path', + default_value: '', + required: true, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'env', + description: 'Print out the environment', + examples: 'env', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'filehash', + description: 'Generate the MD5, SHA1, and SHA256 hashes of a file', + examples: 'filehash /tmp/test', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 680, + created_at: '2020-09-22T00:53:36Z', + updated_at: '2020-09-22T00:53:36Z', + script_id: 100, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'File to hash', + default_value: '', + required: true, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'ifconfig', + description: 'Show network configuration information', + examples: 'ifconfig', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'ls', + description: 'Display the contents of the specified path', + examples: + 'ls\r\nls -l\r\nls -L\r\nls -t\r\nls -l -@\r\nls -R\r\nls -l -R\r\nls -l -t -R -L', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 684, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'Path', + description: 'Path', + default_value: '.', + required: false, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 685, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'l', + description: 'List in long format.', + default_value: '', + required: false, + sequence: 2, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 686, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'L', + description: + 'Follow all symbolic links to final target and list the file or directory the link references rather than the link itself.', + default_value: '', + required: false, + sequence: 3, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 687, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'R', + description: 'Recursively list subdirectories encountered.', + default_value: '', + required: false, + sequence: 4, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + { + id: 688, + created_at: '2020-09-22T00:53:14Z', + updated_at: '2020-09-22T00:53:14Z', + script_id: 104, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 't', + description: + 'Sort by time modified (most recently modified first) before sorting the operands by lexicographical order.', + default_value: '', + required: false, + sequence: 5, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'mount', + description: 'List or mount filesystem volumes', + examples: + 'Executable by all RTR roles:\r\nmount\r\nExecutable by privileged RTR users only:\r\nmount -t=nfs "host:/exports/filesystem" "/mnt/filesystem"\r\n Mount the NFS filesystem located at "/exports/filesystem" on "host" to the local destination "/mnt/filesystem"\r\nmount -t=smbfs "//user:password@host/filesystem" "/mnt/mountpoint"\r\n Mount the SMB "/filesystem" on "host" as "user" with "password" to "/mnt/mountpoint"\r\nmount -t=smbfs -o=nobrowse "//user:password@host/filesystem" "/mnt/mountpoint"\r\n Mount the SMB "/filesystem" with option "nobrowse" on "host" as "user" with "password" to "/mnt/mountpoint"', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'netstat', + description: 'Display routing information or network connections', + examples: 'netstat\r\nnetstat -nr', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 699, + created_at: '2020-09-22T00:52:52Z', + updated_at: '2020-09-22T00:52:52Z', + script_id: 108, + arg_type: 'flag', + data_type: 'string', + requires_value: false, + arg_name: 'nr', + description: 'Flag to show routing information', + default_value: '', + required: false, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + { + command: 'ps', + description: 'Display process information', + examples: 'ps', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'pwd', + description: 'Prints present working directory', + examples: '', + internal_only: false, + runnable: true, + sub_commands: [], + args: [], + }, + { + command: 'users', + description: 'Get details about local users', + examples: + 'users\r\n List details about all local users\r\nusers foo\r\n List details about local user "foo"', + internal_only: false, + runnable: true, + sub_commands: [], + args: [ + { + id: 719, + created_at: '2023-03-15T00:28:54Z', + updated_at: '2023-03-15T00:28:54Z', + script_id: 117, + arg_type: 'arg', + data_type: 'string', + requires_value: false, + arg_name: 'UserName', + description: 'Username to filter results', + default_value: '', + required: false, + sequence: 1, + options: null, + encoding: '', + command_level: 'non-destructive', + }, + ], + }, + ], + existing_aid_sessions: 1, + created_at: '2024-09-13T08:52:22.671935129Z', + offline_queued: false, + }, + ], + errors: [], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_admin_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_admin_route.ts new file mode 100644 index 0000000000000..373c6b960948e --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_admin_route.ts @@ -0,0 +1,264 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { buildCrowdstrikeRoutePath, TEST_AGENT_ID, TEST_SESSION_ID } from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const rtrAdminCommandRoute = (): EmulatorServerRouteDefinition => { + return { + // we use admin command to run run `runscript` and access `cloudFiles` and `custom scripts` + path: buildCrowdstrikeRoutePath('/real-time-response/combined/batch-admin-command/v1'), + method: 'POST', + handler: rtrAdminCommandHandler, + }; +}; + +// @ts-expect-error - example of error while executing cat command +const rtrAdminCommandExampleError = async () => { + return { + meta: { + query_time: 0.913513625, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '', + stderr: 'cat: test.xt: No such file or directory', + base_command: 'cat', + aid: TEST_AGENT_ID, + errors: [], + query_time: 0.912058582, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// @ts-expect-error - example of inactive rtr session error +const rtrAdminCommandInactiveSessionError = async () => { + return { + meta: { + query_time: 0.02078217, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 50007, + message: 'could not get session', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// "command_string": "runscript -CloudFile=\"your_script_name\"", - file not existing +// @ts-expect-error - example of wrong cloud file error +const rtrAdminCommandWrongCloudFileExampleError = async () => { + return { + meta: { + query_time: 0.034585269, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 40412, + message: 'The file your_script_name could not be found', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// wrong command eg. asd "command_string": "runscript -Raw=```asd```", +// @ts-expect-error - example of invalid command error +const rtrAdminCommandInvalidCommandError: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 1.959748222, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '', + stderr: '/bin/bash: line 1: asd: command not found', + base_command: 'runscript', + aid: TEST_AGENT_ID, + errors: [], + query_time: 1.95571987, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +const rtrAdminCommandHandler: ExternalEdrServerEmulatorRouteHandlerMethod<{}, {}> = async () => { + return { + meta: { + query_time: 0.945570286, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: + 'archive\nbackup\nbin\nboot\ndev\netc\nhome\nlib\nlost+found\nmedia\nmnt\nopt\nproc\nroot\nrun\nsbin\nsnap\nsrv\nsys\ntmp\nusr\nvar', + stderr: '', + base_command: 'runscript', + aid: TEST_AGENT_ID, + errors: [], + query_time: 0.941080011, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; +// runscript -CloudFile='test1' (customScript name) - when script is not accessible - eg. private +// @ts-expect-error - example of private script error +const rtrAdminCommandCustomScriptNotFoundError: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 0.01495486, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 40412, + message: 'The file test1 could not be found', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; +// @ts-expect-error - example of error while executing put on a file that already exists on host +const rtrCommandPutFileAlreadyExistError: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 7.897133656, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '', + stderr: 'put: Destination already exists.', + base_command: 'DOWNLOAD_RENAME', + aid: TEST_AGENT_ID, + errors: [], + query_time: 7.8957342520000005, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// @ts-expect-error - example of success response while executing put on a file +const rtrAdminCommandPutSuccessResponse: ExternalEdrServerEmulatorRouteHandlerMethod< + {}, + {} +> = async () => { + return { + meta: { + query_time: 5.497466448, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '', + stderr: '', + base_command: 'DOWNLOAD_RENAME', + aid: TEST_AGENT_ID, + errors: [], + query_time: 5.496508269, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_command_route.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_command_route.ts new file mode 100644 index 0000000000000..60f3c7dd19ca0 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/rtr_command_route.ts @@ -0,0 +1,137 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + buildCrowdstrikeRoutePath, + TEST_AGENT_ID, + TEST_CLOUD_REQUEST_ID, + TEST_SESSION_ID, +} from './utils'; +import type { ExternalEdrServerEmulatorRouteHandlerMethod } from '../../../external_edr_server_emulator.types'; +import type { EmulatorServerRouteDefinition } from '../../../lib/emulator_server.types'; + +export const rtrCommandRoute = (): EmulatorServerRouteDefinition => { + return { + path: buildCrowdstrikeRoutePath('/real-time-response/entities/command/v1'), + method: 'POST', + handler: rtrCommandHandler, + }; +}; +// { +// "base_command": "ls", +// "command_string": "ls", +// "session_id": TEST_SESSION_ID, +// "device_id": TEST_AGENT_ID, +// "persist": true +// } + +// @ts-expect-error - example of error response while executing cat command +const rtrCommandExampleError = async () => { + return { + meta: { + query_time: 0.913513625, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: TEST_SESSION_ID, + task_id: 'xxx', + complete: true, + stdout: '', + stderr: 'cat: test.xt: No such file or directory', + base_command: 'cat', + aid: TEST_AGENT_ID, + errors: [], + query_time: 0.912058582, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// @ts-expect-error - invalid command +const rtrCommandInvalidCommandError = async () => { + return { + meta: { + query_time: 0.101208469, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 40007, + message: 'Command not found', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +// @ts-expect-error - invalid session +const rtrCommandInvalidSessionError = async () => { + return { + meta: { + query_time: 0.02078217, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + combined: { + resources: { + [TEST_AGENT_ID]: { + session_id: '', + complete: false, + stdout: '', + stderr: '', + aid: TEST_AGENT_ID, + errors: [ + { + code: 50007, + message: 'could not get session', + }, + ], + query_time: 0, + offline_queued: false, + }, + }, + }, + errors: [], + }; +}; + +const rtrCommandHandler: ExternalEdrServerEmulatorRouteHandlerMethod<{}, {}> = async () => { + return { + meta: { + query_time: 0.274908106, + powered_by: 'empower-api', + trace_id: 'xxx', + }, + resources: [ + { + session_id: TEST_SESSION_ID, + cloud_request_id: TEST_CLOUD_REQUEST_ID, + queued_command_offline: false, + }, + ], + errors: null, + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/utils.ts b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/utils.ts index ab8ed1ecd57b6..cdaeb004e213b 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/utils.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/api_emulator/emulator_plugins/crowdstrike/routes/utils.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + export const buildCrowdstrikeRoutePath = (path: string): string => { if (!path.startsWith('/')) { throw new Error(`'path' must start with '/'!`); @@ -11,3 +12,9 @@ export const buildCrowdstrikeRoutePath = (path: string): string => { return path; }; + +export const TEST_CID_ID = 'test-cid-id-123456789'; +export const TEST_AGENT_ID = 'test-agent-id-123456789'; +export const TEST_SESSION_ID = 'test-session-id-123456789'; +export const TEST_BATCH_ID = 'test-batch-id-123456789'; +export const TEST_CLOUD_REQUEST_ID = 'test-cloud-request-id-123456789'; From cfcb6e8f4ddf078ccdcec2a03788e39c6e4dfdef Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Tue, 17 Sep 2024 10:18:09 +0200 Subject: [PATCH 057/139] [EDR Workflows][Osquery] Fix last results pack value (#192678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The “Last Results” tab in the active pack details is displaying incorrect date-time values. This is due to a mismatch in data format. The component responsible for formatting the date-time values expects a string, but it is currently receiving an array with a single string inside. Before: ![Screenshot 2024-09-12 at 10 33 39](https://github.com/user-attachments/assets/844fd699-a086-44d8-aa0b-a06e65e5aa60) After: ![Screenshot 2024-09-12 at 12 40 04](https://github.com/user-attachments/assets/bcce9b69-58b8-438d-89e8-c78a3922845c) --- .../packs/pack_queries_status_table.tsx | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx b/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx index 53d55aef7475c..d43721a61b6d2 100644 --- a/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx +++ b/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx @@ -187,7 +187,7 @@ const ViewResultsInLensActionComponent: React.FC { + (event: React.MouseEvent) => { event.preventDefault(); if (logsDataView?.id) { @@ -372,33 +372,31 @@ const ScheduledQueryLastResults: React.FC = ({ interval, }); + const timestamp = useMemo(() => { + const dateTime = lastResultsData?.['@timestamp']; + if (!dateTime) return undefined; + + return Array.isArray(dateTime) ? dateTime[0] : dateTime; + }, [lastResultsData]); + if (isLoading) { return ; } - if (!lastResultsData) { - return <>{'-'}; - } - return ( - {lastResultsData?.['@timestamp'] ? ( + {timestamp ? ( - {' '} - + {' '} + } >
- +
) : ( @@ -584,7 +582,7 @@ const PackQueriesStatusTableComponent: React.FC = ( Record> >({}); - const renderQueryColumn = useCallback((query: string, item: any) => { + const renderQueryColumn = useCallback((query: string, item: PackQueryFormData) => { const singleLine = removeMultilines(query); const content = singleLine.length > 55 ? `${singleLine.substring(0, 55)}...` : singleLine; @@ -618,7 +616,7 @@ const PackQueriesStatusTableComponent: React.FC = ( ); const renderLastResultsColumn = useCallback( - (item: any) => ( + (item: PackQueryFormData) => ( = ( [packName] ); const renderDocsColumn = useCallback( - (item: any) => ( + (item: PackQueryFormData) => ( ), [packName] ); const renderAgentsColumn = useCallback( - (item: any) => ( + (item: PackQueryFormData) => ( ), [packName] ); const renderErrorsColumn = useCallback( - (item: any) => ( + (item: PackQueryFormData) => ( = ( ); const renderDiscoverResultsAction = useCallback( - (item: any) => , + (item: PackQueryFormData) => , [packName] ); const renderLensResultsAction = useCallback( - (item: any) => , + (item: PackQueryFormData) => , [packName] ); From 73fa7a7d8071a7b54e177646294987bff9b6eafb Mon Sep 17 00:00:00 2001 From: Liam Thompson <32779855+leemthompo@users.noreply.github.com> Date: Tue, 17 Sep 2024 09:37:42 +0100 Subject: [PATCH 058/139] [ES3] Update serverless console doclink (#193116) - **404**: https://www.elastic.co/docs/current/serverless/elasticsearch/dev-tools-console - **Correct URL**: https://www.elastic.co/docs/current/serverless/devtools/run-api-requests-in-the-console --- packages/kbn-doc-links/src/get_doc_links.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index 3ad5d271bde47..84005ce3cf492 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -90,7 +90,7 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D }, console: { guide: `${KIBANA_DOCS}console-kibana.html`, - serverlessGuide: `${SERVERLESS_ELASTICSEARCH_DOCS}dev-tools-console`, + serverlessGuide: `${SERVERLESS_DOCS}devtools/run-api-requests-in-the-console`, }, dashboard: { guide: `${KIBANA_DOCS}dashboard.html`, From 9c3561d97fcb7f12248bad9b18969dec9dbb819f Mon Sep 17 00:00:00 2001 From: Richa Talwar <102972658+ritalwar@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:25:57 +0530 Subject: [PATCH 059/139] Update autodetect.sh to detect additional integrations in a generic way. (#191383) ## Summary Relates: https://github.com/elastic/observability-dev/issues/3826 Update `detect_known_integrations()` in `auto_detect.sh` for generic detection using `integrations.conf` and added more integrations for auto detect. --- .../auto_detect/auto_detect_panel.tsx | 17 +- .../auto_detect/use_onboarding_flow.tsx | 9 + .../public/application/shared/logo_icon.tsx | 16 + .../public/assets/apache_tomcat.svg | 107 ++++++ .../public/assets/auto_detect.sh | 308 ++++++++++-------- .../public/assets/haproxy.svg | 197 +++++++++++ .../public/assets/integrations.conf | 86 +++++ .../public/assets/kafka.svg | 3 + .../public/assets/mongodb.svg | 10 + .../public/assets/mysql.svg | 6 + .../public/assets/postgresql.svg | 8 + .../public/assets/rabbitmq.svg | 3 + .../public/assets/redis.svg | 1 + 13 files changed, 628 insertions(+), 143 deletions(-) create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/apache_tomcat.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/haproxy.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/integrations.conf create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/kafka.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/mongodb.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/mysql.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/postgresql.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/rabbitmq.svg create mode 100644 x-pack/plugins/observability_solution/observability_onboarding/public/assets/redis.svg diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/auto_detect_panel.tsx b/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/auto_detect_panel.tsx index c0bdb89609412..d7070c0d945dd 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/auto_detect_panel.tsx +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/auto_detect_panel.tsx @@ -93,7 +93,22 @@ export const AutoDetectPanel: FunctionComponent = () => { - {['Apache', 'Docker', 'Nginx', 'System', 'Custom .log files'].map((item) => ( + {[ + 'Apache', + 'Docker', + 'Nginx', + 'System', + 'MySQL', + 'PostgreSQL', + 'Redis', + 'HAProxy', + 'Kafka', + 'RabbitMQ', + 'Prometheus', + 'Tomcat', + 'MongoDB', + 'Custom .log files', + ].map((item) => ( {item} diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/use_onboarding_flow.tsx b/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/use_onboarding_flow.tsx index 9a2c88517cffd..7824e8ddd59a2 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/use_onboarding_flow.tsx +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/application/quickstart_flows/auto_detect/use_onboarding_flow.tsx @@ -19,6 +19,15 @@ export const DASHBOARDS = { 'docker-AV4REOpp5NkDleZmzKkE': { type: 'metrics' }, 'nginx-55a9e6e0-a29e-11e7-928f-5dbe6f6f5519': { type: 'logs' }, 'system-79ffd6e0-faa0-11e6-947f-177f697178b8': { type: 'metrics' }, + 'mysql-Logs-MySQL-Dashboard': { type: 'logs' }, + 'postgresql-158be870-87f4-11e7-ad9c-db80de0bf8d3': { type: 'logs' }, + 'redis-7fea2930-478e-11e7-b1f0-cb29bac6bf8b': { type: 'logs' }, + 'haproxy-3560d580-aa34-11e8-9c06-877f0445e3e0': { type: 'logs' }, + 'rabbitmq-AV4YobKIge1VCbKU_qVo': { type: 'metrics' }, + 'kafka-943caca0-87ee-11e7-ad9c-db80de0bf8d3': { type: 'logs' }, + 'apache_tomcat-8fd54a20-1f0d-11ee-9d6b-bb41d08322c8': { type: 'logs' }, + 'mongodb-abcf35b0-0a82-11e8-bffe-ff7d4f68cf94': { type: 'logs' }, + 'prometheus-c181a040-3d96-11ed-b624-b12467b8df74': { type: 'metrics' }, }; export function useOnboardingFlow() { diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/application/shared/logo_icon.tsx b/x-pack/plugins/observability_solution/observability_onboarding/public/application/shared/logo_icon.tsx index 0b49eebb1f94f..f498996f53d20 100644 --- a/x-pack/plugins/observability_solution/observability_onboarding/public/application/shared/logo_icon.tsx +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/application/shared/logo_icon.tsx @@ -24,6 +24,14 @@ export type SupportedLogo = | 'apache' | 'system' | 'opentelemetry' + | 'mysql' + | 'postgresql' + | 'redis' + | 'haproxy' + | 'rabbitmq' + | 'kafka' + | 'mongodb' + | 'apache_tomcat' | 'firehose'; export function isSupportedLogo(logo: string): logo is SupportedLogo { @@ -41,6 +49,14 @@ export function isSupportedLogo(logo: string): logo is SupportedLogo { 'system', 'apache', 'opentelemetry', + 'mysql', + 'postgresql', + 'redis', + 'haproxy', + 'rabbitmq', + 'kafka', + 'mongodb', + 'apache_tomcat', ].includes(logo); } diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/apache_tomcat.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/apache_tomcat.svg new file mode 100644 index 0000000000000..410a468872e17 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/apache_tomcat.svg @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/auto_detect.sh b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/auto_detect.sh index 8218ab77b9be0..30d093cf515df 100755 --- a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/auto_detect.sh +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/auto_detect.sh @@ -10,15 +10,15 @@ if [ -z "${BASH_VERSION:-}" ]; then fi if ! command -v curl >/dev/null 2>&1; then - fail "curl is required to run this script" + fail "curl is required to run this script" fi # Check if the `lsof` command exists in PATH, if not use `/usr/sbin/lsof` if possible LSOF_PATH="" if command -v lsof >/dev/null 2>&1; then - LSOF_PATH=$(command -v lsof) + LSOF_PATH=$(command -v lsof) elif command -v /usr/sbin/lsof >/dev/null 2>&1; then - LSOF_PATH="/usr/sbin/lsof" + LSOF_PATH="/usr/sbin/lsof" fi install_api_key_encoded="" @@ -28,60 +28,60 @@ onboarding_flow_id="" elastic_agent_version="" help() { - echo "Usage: sudo ./auto-detect.sh " - echo "" - echo "Arguments:" - echo " --install-key= Base64 Encoded API key that has priviledges to install integrations." - echo " --ingest-key= Base64 Encoded API key that has priviledges to ingest data." - echo " --kibana-url= Kibana API endpoint." - echo " --id= Onboarding flow ID." - echo " --ea-version= Elastic Agent version." - exit 1 + echo "Usage: sudo ./auto-detect.sh " + echo "" + echo "Arguments:" + echo " --install-key= Base64 Encoded API key that has priviledges to install integrations." + echo " --ingest-key= Base64 Encoded API key that has priviledges to ingest data." + echo " --kibana-url= Kibana API endpoint." + echo " --id= Onboarding flow ID." + echo " --ea-version= Elastic Agent version." + exit 1 } ensure_argument() { - if [ -z "$1" ]; then - echo "Error: Missing value for $2." - help - fi + if [ -z "$1" ]; then + echo "Error: Missing value for $2." + help + fi } if [ "$EUID" -ne 0 ]; then - echo "Error: This script must be run as root." - help + echo "Error: This script must be run as root." + help fi # Parse command line arguments for i in "$@"; do - case $i in - --install-key=*) - shift - install_api_key_encoded="${i#*=}" - ;; - --ingest-key=*) - shift - ingest_api_key_encoded="${i#*=}" - ;; - --kibana-url=*) - shift - kibana_api_endpoint="${i#*=}" - ;; - --id=*) - shift - onboarding_flow_id="${i#*=}" - ;; - --ea-version=*) - shift - elastic_agent_version="${i#*=}" - ;; - --help) - help - ;; - *) - echo "Unknown option: $i" - help - ;; - esac + case $i in + --install-key=*) + shift + install_api_key_encoded="${i#*=}" + ;; + --ingest-key=*) + shift + ingest_api_key_encoded="${i#*=}" + ;; + --kibana-url=*) + shift + kibana_api_endpoint="${i#*=}" + ;; + --id=*) + shift + onboarding_flow_id="${i#*=}" + ;; + --ea-version=*) + shift + elastic_agent_version="${i#*=}" + ;; + --help) + help + ;; + *) + echo "Unknown option: $i" + help + ;; + esac done ensure_argument "$install_api_key_encoded" "--install-key" @@ -92,6 +92,7 @@ ensure_argument "$elastic_agent_version" "--ea-version" known_integrations_list_string="" selected_known_integrations_array=() +detected_patterns=() selected_known_integrations_tsv_string="" unknown_log_file_path_list_string="" unknown_log_file_pattern_list_string="" @@ -102,6 +103,8 @@ custom_log_file_path_list_tsv_string="" elastic_agent_artifact_name="" elastic_agent_config_path="/opt/Elastic/Agent/elastic-agent.yml" elastic_agent_tmp_config_path="/tmp/elastic-agent-config.tar" +integration_names=() +integration_titles=() OS="$(uname)" ARCH="$(uname -m)" @@ -173,7 +176,7 @@ extract_elastic_agent() { } install_elastic_agent() { - "./${elastic_agent_artifact_name}/elastic-agent" install -f -n > /dev/null + "./${elastic_agent_artifact_name}/elastic-agent" install -f -n >/dev/null if [ "$?" -eq 0 ]; then printf "\e[1;32m✓\e[0m %s\n" "Elastic Agent installed to $(dirname "$elastic_agent_config_path")" @@ -187,11 +190,11 @@ install_elastic_agent() { wait_for_elastic_agent_status() { local MAX_RETRIES=10 local i=0 - elastic-agent status > /dev/null 2>&1 + elastic-agent status >/dev/null 2>&1 local ELASTIC_AGENT_STATUS_EXIT_CODE="$?" while [ "$ELASTIC_AGENT_STATUS_EXIT_CODE" -ne 0 ] && [ $i -le $MAX_RETRIES ]; do sleep 1 - elastic-agent status > /dev/null 2>&1 + elastic-agent status >/dev/null 2>&1 ELASTIC_AGENT_STATUS_EXIT_CODE="$?" ((i++)) done @@ -221,7 +224,7 @@ ensure_elastic_agent_healthy() { backup_elastic_agent_config() { if [ -f "$elastic_agent_config_path" ]; then - echo -e "\nExisting config found at $elastic_agent_config_path"; + echo -e "\nExisting config found at $elastic_agent_config_path" printf "\n\e[1;36m?\e[0m \e[1m%s\e[0m \e[2m%s\e[0m" "Create backup and continue installation?" "[Y/n] (default: Yes): " read confirmation_reply @@ -286,13 +289,13 @@ apply_elastic_agent_config() { local decoded_ingest_api_key=$(echo "$ingest_api_key_encoded" | base64 -d) # Verify that the downloaded archive contains the expected `elastic-agent.yml` file - tar --list --file "$elastic_agent_tmp_config_path" --include 'elastic-agent.yml' > /dev/null && \ - # Remove existing config file including `inputs.d` directory - rm -rf "$elastic_agent_config_path" "$(dirname "$elastic_agent_config_path")/inputs.d" && \ - # Extract new config files from downloaded archive - tar --extract --file "$elastic_agent_tmp_config_path" --include 'elastic-agent.yml' --include 'inputs.d/*.yml' --directory "$(dirname "$elastic_agent_config_path")" && \ - # Replace placeholder with the Ingest API key - sed -i '' "s/\${API_KEY}/$decoded_ingest_api_key/" "$elastic_agent_config_path" + tar --list --file "$elastic_agent_tmp_config_path" --include 'elastic-agent.yml' >/dev/null && + # Remove existing config file including `inputs.d` directory + rm -rf "$elastic_agent_config_path" "$(dirname "$elastic_agent_config_path")/inputs.d" && + # Extract new config files from downloaded archive + tar --extract --file "$elastic_agent_tmp_config_path" --include 'elastic-agent.yml' --include 'inputs.d/*.yml' --directory "$(dirname "$elastic_agent_config_path")" && + # Replace placeholder with the Ingest API key + sed -i '' "s/\${API_KEY}/$decoded_ingest_api_key/" "$elastic_agent_config_path" if [ "$?" -eq 0 ]; then printf "\e[1;32m✓\e[0m %s\n" "Config written to:" tar --list --file "$elastic_agent_tmp_config_path" --include 'elastic-agent.yml' --include 'inputs.d/*.yml' | while read -r file; do @@ -313,30 +316,29 @@ read_open_log_file_list() { "^\/Users\/.+?\/Library\/Containers" "^\/Users\/.+?\/Library\/Caches" "^\/private" - # Excluding all patterns that correspond to known integrations - # that we are detecting separately - "^\/var\/log\/nginx" - "^\/var\/log\/apache2" - "^\/var\/log\/httpd" - "^\/var\/lib\/docker\/containers" - "^\/var\/log\/syslog" - "^\/var\/log\/auth.log" - "^\/var\/log\/system.log" - "^\/var\/log\/messages" - "^\/var\/log\/secure" + # Exclude previous installation logs "\/opt\/Elastic\/Agent\/" "\/Library\/Elastic\/Agent\/" ) + # Excluding all patterns that correspond to known integrations + # that we are detecting separately + for pattern in "${detected_patterns[@]}"; do + exclude_patterns+=("$pattern") + done + local list=$("$LSOF_PATH" -Fn / | grep "^n.*\.log$" | cut -c2- | sort -u) # Filtering by the exclude patterns while IFS= read -r line; do - if ! grep -qE "$(IFS="|"; echo "${exclude_patterns[*]}")" <<< "$line"; then - unknown_log_file_path_list_string+="$line\n" + if ! grep -qE "$( + IFS="|" + echo "${exclude_patterns[*]}" + )" <<<"$line"; then + unknown_log_file_path_list_string+="$line\n" fi - done <<< "$list" + done <<<"$list" } detect_known_integrations() { @@ -344,60 +346,82 @@ detect_known_integrations() { # Even when there is no system logs on the host, # System integration will still be able to to collect metrics. known_integrations_list_string+="system"$'\n' + integrations_config_url="${kibana_api_endpoint}/plugins/observabilityOnboarding/assets/integrations.conf" - local nginx_patterns=( - "/var/log/nginx/access.log*" - "/var/log/nginx/error.log*" - ) + integrations_config=$(curl "${integrations_config_url}" --silent --fail) + local integration="" + local patterns=() + + # Debug: Check if the config file exists + if [[ -z "$integrations_config" ]]; then + echo "Failed to retrieve config file" + exit 1 + fi - for pattern in "${nginx_patterns[@]}"; do - if compgen -G "$pattern" > /dev/null; then - known_integrations_list_string+="nginx"$'\n' - break + while IFS= read -r line; do + + # Skip comments and empty lines + if [[ $line =~ ^\s*# || -z $line ]]; then + continue fi - done - local apache_patterns=( - "/var/log/apache2/access.log*" - "/var/log/apache2/other_vhosts_access.log*" - "/var/log/apache2/error.log*" - "/var/log/httpd/access_log*" - "/var/log/httpd/error_log*" - ) + # Process section headers + if [[ $line =~ ^\[([a-zA-Z0-9_]+)\] ]]; then + # If we were processing a previous section, check patterns for the previous integration + if [[ -n "$integration" && ${#patterns[@]} -gt 0 ]]; then + for pattern in "${patterns[@]}"; do + pattern=$(echo "$pattern" | xargs) # Trim leading/trailing spaces + if compgen -G "$pattern" >/dev/null; then + known_integrations_list_string+="$integration"$'\n' + detected_patterns+=("${patterns[@]}") + break + fi + done + fi - for pattern in "${apache_patterns[@]}"; do - if compgen -G "$pattern" > /dev/null; then - known_integrations_list_string+="apache"$'\n' - break + # Start a new section + integration="${BASH_REMATCH[1]}" + patterns=() + continue fi - done - if [ -S /var/run/docker.sock ]; then - known_integrations_list_string+="docker"$'\n' - elif compgen -G "/var/lib/docker/containers/*/*-json.log" > /dev/null; then - known_integrations_list_string+="docker"$'\n' + # Process patterns + if [[ $line =~ ^patterns= ]]; then + # Capture patterns by trimming spaces and handling multi-line patterns + IFS=$'\n' read -r -d '' -a patterns <<<"${line#patterns=}" + patterns=($(echo "${patterns[@]}" | xargs)) # Trim leading/trailing spaces + elif [[ $line =~ ^title=.*$ ]]; then + # Capture titles + integration_titles+=("${line#title=}") + integration_names+=("$integration") + elif [[ -n "$integration" && -n "$line" ]]; then + # Capture multi-line patterns if not directly following "patterns=" + patterns+=("$(echo "$line" | xargs)") # Trim leading/trailing spaces + fi + done <<< "$integrations_config" + + # Check patterns for the last section + if [[ -n "$integration" && ${#patterns[@]} -gt 0 ]]; then + for pattern in "${patterns[@]}"; do + pattern=$(echo "$pattern" | xargs) # Trim leading/trailing spaces + if compgen -G "$pattern" >/dev/null; then + known_integrations_list_string+="$integration"$'\n' + detected_patterns+=("${patterns[@]}") + break + fi + done fi } known_integration_title() { local integration=$1 - case $integration in - "nginx") - echo "Nginx Logs" - ;; - "apache") - echo "Apache Logs" - ;; - "docker") - echo "Docker Container Logs" - ;; - "system") - echo "System Logs And Metrics" - ;; - *) - echo "Unknown" - ;; - esac + for i in "${!integration_names[@]}"; do + if [[ "${integration_names[$i]}" == "$integration" ]]; then + echo "${integration_titles[$i]}" + return + fi + done + echo "Unknown" } build_unknown_log_file_patterns() { @@ -407,7 +431,7 @@ build_unknown_log_file_patterns() { fi unknown_log_file_pattern_list_string+="$(dirname "$log_file_path")/*.log\n" - done <<< "$(echo -e "$unknown_log_file_path_list_string")" + done <<<"$(echo -e "$unknown_log_file_path_list_string")" unknown_log_file_pattern_list_string=$(echo -e "$unknown_log_file_pattern_list_string" | sort -u) } @@ -421,14 +445,14 @@ function select_list() { continue fi known_integrations_options+=("$line") - done <<< "$known_integrations_list_string" + done <<<"$known_integrations_list_string" while IFS= read -r line; do if [[ -z "$line" ]]; then continue fi unknown_logs_options+=("$line") - done <<< "$unknown_log_file_pattern_list_string" + done <<<"$unknown_log_file_pattern_list_string" local options=("${known_integrations_options[@]}" "${unknown_logs_options[@]}") @@ -448,13 +472,13 @@ function select_list() { printf "\n\e[1;36m?\e[0m \e[1m%s\e[0m \e[2m%s\e[0m\n" "Exclude logs by listing their index numbers" "(e.g. 1, 2, 3). Press Enter to skip." read exclude_index_list_string - IFS=', ' read -r -a exclude_index_list_array <<< "$exclude_index_list_string" + IFS=', ' read -r -a exclude_index_list_array <<<"$exclude_index_list_string" for index in "${!options[@]}"; do local is_excluded=0 for excluded_index in "${exclude_index_list_array[@]}"; do if [[ "$index" -eq "$((excluded_index - 1))" ]]; then - is_excluded=1 + is_excluded=1 fi done @@ -481,7 +505,7 @@ function select_list() { printf "\e[1;36m?\e[0m \e[1m%s\e[0m \e[2m%s\e[0m\n" "List any additional logs you'd like to ingest" "(e.g. /path1/*.log, /path2/*.log). Press Enter to skip." read custom_log_file_path_list_string - IFS=', ' read -r -a custom_log_file_path_list_array <<< "$custom_log_file_path_list_string" + IFS=', ' read -r -a custom_log_file_path_list_array <<<"$custom_log_file_path_list_string" echo -e "\nYou've selected these logs for ingestion:" for item in "${selected_known_integrations_array[@]}"; do @@ -506,30 +530,30 @@ function select_list() { } generate_custom_integration_name() { - local path_pattern="$1" - local dir_path - local name_parts=() - local name + local path_pattern="$1" + local dir_path + local name_parts=() + local name - dir_path=$(dirname "$path_pattern") - IFS='/' read -r -a dir_array <<< "$dir_path" + dir_path=$(dirname "$path_pattern") + IFS='/' read -r -a dir_array <<<"$dir_path" - # Get the last up to 4 parts of the path - for (( i=${#dir_array[@]}-1, count=0; i>=0 && count<4; i--, count++ )); do - name_parts=("${dir_array[$i]}" "${name_parts[@]}") - done + # Get the last up to 4 parts of the path + for ((i = ${#dir_array[@]} - 1, count = 0; i >= 0 && count < 4; i--, count++)); do + name_parts=("${dir_array[$i]}" "${name_parts[@]}") + done - # Join the parts into a single string with underscores - name=$(printf "%s_" "${name_parts[@]}") - name="${name#_}" # Remove leading underscore - name="${name%_}" # Remove trailing underscore + # Join the parts into a single string with underscores + name=$(printf "%s_" "${name_parts[@]}") + name="${name#_}" # Remove leading underscore + name="${name%_}" # Remove trailing underscore - # Replace special characters with underscores - name="${name// /_}" - name="${name//-/_}" - name="${name//./_}" + # Replace special characters with underscores + name="${name// /_}" + name="${name//-/_}" + name="${name//./_}" - echo "$name" + echo "$name" } printf "\e[1m%s\e[0m\n" "Looking for log files..." @@ -538,10 +562,10 @@ detect_known_integrations # Check if LSOF_PATH is executable if [ -x "$LSOF_PATH" ]; then - read_open_log_file_list - build_unknown_log_file_patterns + read_open_log_file_list + build_unknown_log_file_patterns else - echo -e "\nlsof is required to detect custom log files. Looking for known integrations only." + echo -e "\nlsof is required to detect custom log files. Looking for known integrations only." fi update_step_progress "logs-detect" "complete" diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/haproxy.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/haproxy.svg new file mode 100644 index 0000000000000..f45c35d3434af --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/haproxy.svg @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/integrations.conf b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/integrations.conf new file mode 100644 index 0000000000000..e6455a9170c86 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/integrations.conf @@ -0,0 +1,86 @@ +[system] +title=System Logs And Metrics + +[nginx] +title=Nginx Logs +patterns= + /var/log/nginx/access.log* + /var/log/nginx/error.log* + +[apache] +title=Apache Logs +patterns= + /var/log/apache2/access.log* + /var/log/apache2/other_vhosts_access.log* + /var/log/apache2/error.log* + /var/log/httpd/access_log* + /var/log/httpd/error_log* + +[docker] +title=Docker Container Logs +patterns= + /var/lib/docker/containers/*/*-json.log + /var/run/docker.sock + +[mysql] +title=MySQL Logs +patterns= + /var/log/mysql/*error.log* + /var/log/mysqld.log* + /var/log/mysql/*-slow.log* + /var/lib/mysql/*-slow.log* + +[postgresql] +title=PostgreSQL Logs +patterns= + /var/log/postgresql/postgresql-*-*.log* + /*/postgresql-logs/*.log + /etc/postgresql/*/main/postgresql.conf + /var/log/postgresql/postgresql-*-*.csv* + +[redis] +title=Redis Logs +patterns= + /var/log/redis/redis-server.log* + /etc/redis/redis.conf + +[haproxy] +title=HAProxy Logs +patterns= + /var/log/haproxy.log + /etc/haproxy/haproxy.cfg + +[rabbitmq] +title=RabbitMQ Logs +patterns= + /var/log/rabbitmq/rabbit@*.log + /etc/rabbitmq/rabbitmq.conf + /etc/rabbitmq/rabbitmq.config + +[kafka] +title=Kafka Logs +patterns= + /var/log/kafka/server.log + /etc/kafka/server.properties + /*/logs/controller.log* + /*/logs/server.log* + /*/logs/state-change.log* + /*/logs/kafka-*.log* + +[mongodb] +title=MongoDB Logs +patterns= + /var/log/mongodb/mongod.log + +[apache_tomcat] +title=Apache Tomcat Logs +patterns= + /opt/tomcat/logs/localhost_access_log.*.txt + /opt/tomcat/logs/catalina.*.log + /opt/tomcat/logs/localhost.*.log + +[prometheus] +title=Prometheus Server overview +patterns= + /var/log/prometheus/prometheus.log + /etc/prometheus/prometheus.yml \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/kafka.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/kafka.svg new file mode 100644 index 0000000000000..e88f77cb55b41 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/kafka.svg @@ -0,0 +1,3 @@ + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/mongodb.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/mongodb.svg new file mode 100644 index 0000000000000..1727f81d2f6c9 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/mongodb.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/mysql.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/mysql.svg new file mode 100644 index 0000000000000..cfe6cbb664e7f --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/mysql.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/postgresql.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/postgresql.svg new file mode 100644 index 0000000000000..0306131fcd395 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/postgresql.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/rabbitmq.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/rabbitmq.svg new file mode 100644 index 0000000000000..dabd2a5744cb4 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/rabbitmq.svg @@ -0,0 +1,3 @@ + + + diff --git a/x-pack/plugins/observability_solution/observability_onboarding/public/assets/redis.svg b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/redis.svg new file mode 100644 index 0000000000000..1163d1ea52f44 --- /dev/null +++ b/x-pack/plugins/observability_solution/observability_onboarding/public/assets/redis.svg @@ -0,0 +1 @@ + From 7939f60f563af7c3f5402fcc70a7bb3578644e62 Mon Sep 17 00:00:00 2001 From: Jeramy Soucy Date: Tue, 17 Sep 2024 11:03:26 +0200 Subject: [PATCH 060/139] =?UTF-8?q?Upgrade=20express=204.19.2=E2=86=924.21?= =?UTF-8?q?.0=20(#192862)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Upgrades `express` from v4.19.2 to v4.21.0, and `@types/express` from v4.17.13 to v4.17.21. This PR also moves the dev-only dependency `@mswjs/http-middleware` into the `devDependencies` section. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- package.json | 6 +-- yarn.lock | 148 +++++++++++++++++++++++++++------------------------ 2 files changed, 81 insertions(+), 73 deletions(-) diff --git a/package.json b/package.json index 5b9e8fac1fb31..1a420b7cae9ea 100644 --- a/package.json +++ b/package.json @@ -996,7 +996,6 @@ "@mapbox/mapbox-gl-rtl-text": "0.2.3", "@mapbox/mapbox-gl-supported": "2.0.1", "@mapbox/vector-tile": "1.3.1", - "@mswjs/http-middleware": "^0.10.1", "@opentelemetry/api": "^1.1.0", "@opentelemetry/api-metrics": "^0.31.0", "@opentelemetry/exporter-metrics-otlp-grpc": "^0.34.0", @@ -1464,6 +1463,7 @@ "@kbn/whereis-pkg-cli": "link:packages/kbn-whereis-pkg-cli", "@kbn/yarn-lock-validator": "link:packages/kbn-yarn-lock-validator", "@mapbox/vector-tile": "1.3.1", + "@mswjs/http-middleware": "^0.10.1", "@octokit/rest": "^17.11.2", "@parcel/watcher": "^2.1.0", "@playwright/test": "=1.46.0", @@ -1525,7 +1525,7 @@ "@types/enzyme": "^3.10.12", "@types/eslint": "^8.44.2", "@types/event-stream": "^4.0.5", - "@types/express": "^4.17.13", + "@types/express": "^4.17.21", "@types/extract-zip": "^1.6.2", "@types/faker": "^5.1.5", "@types/fetch-mock": "^7.3.1", @@ -1700,7 +1700,7 @@ "exit-hook": "^2.2.0", "expect": "^29.7.0", "expose-loader": "^0.7.5", - "express": "^4.19.2", + "express": "^4.21.0", "faker": "^5.1.0", "fetch-mock": "^7.3.9", "file-loader": "^4.2.0", diff --git a/yarn.lock b/yarn.lock index 408d93ad5ee99..9b0438134fd4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10358,22 +10358,23 @@ resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.28" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" - integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.19.5" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz#218064e321126fcf9048d1ca25dd2465da55d9c6" + integrity sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" + "@types/send" "*" -"@types/express@*", "@types/express@^4.17.13": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== +"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.21": + version "4.17.21" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" + "@types/express-serve-static-core" "^4.17.33" "@types/qs" "*" "@types/serve-static" "*" @@ -11279,6 +11280,14 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== +"@types/send@*": + version "0.17.4" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + "@types/serve-index@^1.9.1": version "1.9.1" resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" @@ -13409,10 +13418,10 @@ bn.js@^5.0.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.2: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== +body-parser@1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== dependencies: bytes "3.1.2" content-type "~1.0.5" @@ -13422,7 +13431,7 @@ body-parser@1.20.2: http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.11.0" + qs "6.13.0" raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -16729,6 +16738,11 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1, end-of-stream@^1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -17765,37 +17779,37 @@ expr-eval@^2.0.2: resolved "https://registry.yarnpkg.com/expr-eval/-/expr-eval-2.0.2.tgz#fa6f044a7b0c93fde830954eb9c5b0f7fbc7e201" integrity sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg== -express@^4.17.1, express@^4.17.3, express@^4.18.2, express@^4.19.2: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== +express@^4.17.1, express@^4.17.3, express@^4.18.2, express@^4.21.0: + version "4.21.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" + integrity sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.2" + body-parser "1.20.3" content-disposition "0.5.4" content-type "~1.0.4" cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" + finalhandler "1.3.1" fresh "0.5.2" http-errors "2.0.0" - merge-descriptors "1.0.1" + merge-descriptors "1.0.3" methods "~1.1.2" on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "0.1.10" proxy-addr "~2.0.7" - qs "6.11.0" + qs "6.13.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "0.19.0" + serve-static "1.16.2" setprototypeof "1.2.0" statuses "2.0.1" type-is "~1.6.18" @@ -18152,13 +18166,13 @@ fill-range@^7.1.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" on-finished "2.4.1" parseurl "~1.3.3" @@ -18714,7 +18728,7 @@ get-east-asian-width@^1.0.0: resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e" integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== @@ -23082,10 +23096,10 @@ meow@^9.0.0: type-fest "^0.18.0" yargs-parser "^20.2.3" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-source-map@1.0.4: version "1.0.4" @@ -24436,7 +24450,7 @@ object-identity-map@^1.0.2: dependencies: object.entries "^1.1.0" -object-inspect@^1.13.1, object-inspect@^1.6.0, object-inspect@^1.7.0, object-inspect@^1.9.0: +object-inspect@^1.13.1, object-inspect@^1.6.0, object-inspect@^1.7.0: version "1.13.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== @@ -25164,10 +25178,10 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== path-to-regexp@^1.7.0: version "1.9.0" @@ -26292,19 +26306,12 @@ qs@6.10.4: dependencies: side-channel "^1.0.4" -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== +qs@6.13.0, qs@^6.10.0, qs@^6.11.0, qs@^6.7.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: - side-channel "^1.0.4" - -qs@^6.10.0, qs@^6.11.0, qs@^6.7.0: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" query-string@^6.13.2: version "6.13.2" @@ -28412,10 +28419,10 @@ semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.5.0, semve resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" @@ -28483,15 +28490,15 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" + send "0.19.0" set-blocking@^2.0.0: version "2.0.0" @@ -28691,14 +28698,15 @@ should@^13.2.1: should-type-adaptors "^1.0.1" should-util "^1.0.0" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" From 6b24114b4298266d7c4d73186983f9b73704a7a2 Mon Sep 17 00:00:00 2001 From: Cristina Amico Date: Tue, 17 Sep 2024 11:35:00 +0200 Subject: [PATCH 061/139] [Fleet] Remove deprecated Symantec package from install_all_packages_job (#193029) ## Summary [Job](https://buildkite.com/elastic/kibana-fleet-packages/builds/1022) `install_all_packages` is been failing for several days because of `symantec-0.1.3` being deprecated. Querying ``` GET kbn:/api/fleet/epm/packages?prerelease=true ``` it returns: ``` "name": "symantec", "title": "Symantec", "version": "0.1.3", "release": "experimental", "description": "Deprecated. Use a specific Symantec package instead.", ``` I'm not sure when this deprecation was announced but I'm skipping this package from the script so the job should hopefully return green. EDIT: package got deprecated back in 2022: https://github.com/elastic/package-storage/pull/3254 however last week we merged a [change](https://github.com/elastic/kibana/pull/192040/files#diff-292c3f307d3d0d341a361d12416d04609a3f525be268242c2a06be06fd8d5810R188) to temporarily remove kibana version checks when querying EPR, so this package started appearing. In fact in previous successful runs we didn't attempt installing this package at all. Co-authored-by: Elastic Machine --- x-pack/test/fleet_packages/tests/install_all.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/x-pack/test/fleet_packages/tests/install_all.ts b/x-pack/test/fleet_packages/tests/install_all.ts index d58c9a0333b84..e835f200ed490 100644 --- a/x-pack/test/fleet_packages/tests/install_all.ts +++ b/x-pack/test/fleet_packages/tests/install_all.ts @@ -14,6 +14,11 @@ import { FtrProviderContext } from '../../api_integration/ftr_provider_context'; +const DEPRECATED_PACKAGES = [ + 'zscaler', // deprecated: https://github.com/elastic/integrations/issues/4947 + 'symantec', +]; + export default function (providerContext: FtrProviderContext) { const { getService } = providerContext; const supertest = getService('supertest'); @@ -69,8 +74,9 @@ export default function (providerContext: FtrProviderContext) { .expect(200); const allResults = []; for (const pkg of packages) { - // skip deprecated failing package https://github.com/elastic/integrations/issues/4947 - if (pkg.name === 'zscaler') continue; + // skip deprecated failing packages + if (DEPRECATED_PACKAGES.includes(pkg.name)) continue; + const res = await installPackage(pkg.name, pkg.version); allResults.push(res); if (res.success) { From 808212e97e413216655aaa9e755c671656decb46 Mon Sep 17 00:00:00 2001 From: Bena Kansara <69037875+benakansara@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:50:09 +0200 Subject: [PATCH 062/139] [RCA] [Recent events] Create API endpoint to get events (#192947) Closes https://github.com/elastic/observability-dev/issues/3924 Closes https://github.com/elastic/observability-dev/issues/3927 This PR introduces an events API (`/api/observability/events`) that will fetch - - All the "point in time" annotations from` observability-annotations` index. This includes both manual and auto (e.g. service deployment) annotations - The annotations will be filtered with supported source fields (host.name, service.name, slo.id, slo.instanceId) when specified as `filter` - Alerts that newly triggered on same source in given time range. The source needs to be specified as `filter`, when no filter is specified all alerts triggered in given time range will be returned ### Testing - Create annotations (APM service deployment annotations and annotations using Observability UI) - Generate some alerts - API call should return annotations and alerts, example API requests - `http://localhost:5601/kibana/api/observability/events?rangeFrom=2024-09-01T19:53:20.243Z&rangeTo=2024-09-19T19:53:20.243Z&filter={"annotation.type":"deployment"}` - `http://localhost:5601/kibana/api/observability/events?rangeFrom=2024-09-01T19:53:20.243Z&rangeTo=2024-09-19T19:53:20.243Z&filter={"slo.id":"*"}` - `http://localhost:5601/kibana/api/observability/events?rangeFrom=2024-09-01T19:53:20.243Z&rangeTo=2024-09-19T19:53:20.243Z&filter={"host.name":"host-0"}` - `http://localhost:5601/kibana/api/observability/events?rangeFrom=2024-09-01T19:53:20.243Z&rangeTo=2024-09-19T19:53:20.243Z` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../src/rest_specs/event.ts | 18 +++ .../src/rest_specs/get_events.ts | 31 +++++ .../src/rest_specs/index.ts | 4 + .../src/schema/event.ts | 51 ++++++++ .../src/schema/index.ts | 1 + .../investigate_app/kibana.jsonc | 3 + ...investigate_app_server_route_repository.ts | 32 +++++ .../investigate_app/server/routes/types.ts | 2 + .../server/services/get_alerts_client.ts | 49 +++++++ .../server/services/get_events.ts | 123 ++++++++++++++++++ .../investigate_app/server/types.ts | 15 ++- .../investigate_app/tsconfig.json | 3 + .../observability/common/annotations.ts | 2 + .../annotations/create_annotations_client.ts | 45 ++++--- 14 files changed, 359 insertions(+), 20 deletions(-) create mode 100644 packages/kbn-investigation-shared/src/rest_specs/event.ts create mode 100644 packages/kbn-investigation-shared/src/rest_specs/get_events.ts create mode 100644 packages/kbn-investigation-shared/src/schema/event.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts create mode 100644 x-pack/plugins/observability_solution/investigate_app/server/services/get_events.ts diff --git a/packages/kbn-investigation-shared/src/rest_specs/event.ts b/packages/kbn-investigation-shared/src/rest_specs/event.ts new file mode 100644 index 0000000000000..df2f3941ad332 --- /dev/null +++ b/packages/kbn-investigation-shared/src/rest_specs/event.ts @@ -0,0 +1,18 @@ +/* + * 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 { z } from '@kbn/zod'; +import { eventSchema } from '../schema'; + +const eventResponseSchema = eventSchema; + +type EventResponse = z.output; + +export { eventResponseSchema }; +export type { EventResponse }; diff --git a/packages/kbn-investigation-shared/src/rest_specs/get_events.ts b/packages/kbn-investigation-shared/src/rest_specs/get_events.ts new file mode 100644 index 0000000000000..064a75fab1562 --- /dev/null +++ b/packages/kbn-investigation-shared/src/rest_specs/get_events.ts @@ -0,0 +1,31 @@ +/* + * 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 { z } from '@kbn/zod'; +import { eventResponseSchema } from './event'; + +const getEventsParamsSchema = z + .object({ + query: z + .object({ + rangeFrom: z.string(), + rangeTo: z.string(), + filter: z.string(), + }) + .partial(), + }) + .partial(); + +const getEventsResponseSchema = z.array(eventResponseSchema); + +type GetEventsParams = z.infer; +type GetEventsResponse = z.output; + +export { getEventsParamsSchema, getEventsResponseSchema }; +export type { GetEventsParams, GetEventsResponse }; diff --git a/packages/kbn-investigation-shared/src/rest_specs/index.ts b/packages/kbn-investigation-shared/src/rest_specs/index.ts index c00ec5035765e..42bec32041af4 100644 --- a/packages/kbn-investigation-shared/src/rest_specs/index.ts +++ b/packages/kbn-investigation-shared/src/rest_specs/index.ts @@ -25,6 +25,8 @@ export type * from './investigation_note'; export type * from './update'; export type * from './update_item'; export type * from './update_note'; +export type * from './event'; +export type * from './get_events'; export * from './create'; export * from './create_item'; @@ -44,3 +46,5 @@ export * from './investigation_note'; export * from './update'; export * from './update_item'; export * from './update_note'; +export * from './event'; +export * from './get_events'; diff --git a/packages/kbn-investigation-shared/src/schema/event.ts b/packages/kbn-investigation-shared/src/schema/event.ts new file mode 100644 index 0000000000000..c954a0de13fb3 --- /dev/null +++ b/packages/kbn-investigation-shared/src/schema/event.ts @@ -0,0 +1,51 @@ +/* + * 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 { z } from '@kbn/zod'; + +const eventTypeSchema = z.union([ + z.literal('annotation'), + z.literal('alert'), + z.literal('error_rate'), + z.literal('latency'), + z.literal('anomaly'), +]); + +const annotationEventSchema = z.object({ + eventType: z.literal('annotation'), + annotationType: z.string().optional(), +}); + +const alertStatusSchema = z.union([ + z.literal('active'), + z.literal('flapping'), + z.literal('recovered'), + z.literal('untracked'), +]); + +const alertEventSchema = z.object({ + eventType: z.literal('alert'), + alertStatus: alertStatusSchema, +}); + +const sourceSchema = z.record(z.string(), z.any()); + +const eventSchema = z.intersection( + z.object({ + id: z.string(), + title: z.string(), + description: z.string(), + timestamp: z.number(), + eventType: eventTypeSchema, + source: sourceSchema.optional(), + }), + z.discriminatedUnion('eventType', [annotationEventSchema, alertEventSchema]) +); + +export { eventSchema }; diff --git a/packages/kbn-investigation-shared/src/schema/index.ts b/packages/kbn-investigation-shared/src/schema/index.ts index 7491ecce76cc2..f65fe9baf1f6f 100644 --- a/packages/kbn-investigation-shared/src/schema/index.ts +++ b/packages/kbn-investigation-shared/src/schema/index.ts @@ -11,5 +11,6 @@ export * from './investigation'; export * from './investigation_item'; export * from './investigation_note'; export * from './origin'; +export * from './event'; export type * from './investigation'; diff --git a/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc b/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc index ecfe77b5a0584..2cc904dafac05 100644 --- a/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc +++ b/x-pack/plugins/observability_solution/investigate_app/kibana.jsonc @@ -19,6 +19,9 @@ "datasetQuality", "unifiedSearch", "security", + "observability", + "licensing", + "ruleRegistry" ], "requiredBundles": [ "esql", diff --git a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts index b0ecd89275914..195fbdb234360 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/routes/get_global_investigate_app_server_route_repository.ts @@ -21,7 +21,10 @@ import { updateInvestigationItemParamsSchema, updateInvestigationNoteParamsSchema, updateInvestigationParamsSchema, + getEventsParamsSchema, + GetEventsResponse, } from '@kbn/investigation-shared'; +import { ScopedAnnotationsClient } from '@kbn/observability-plugin/server'; import { createInvestigation } from '../services/create_investigation'; import { createInvestigationItem } from '../services/create_investigation_item'; import { createInvestigationNote } from '../services/create_investigation_note'; @@ -35,6 +38,8 @@ import { getInvestigationItems } from '../services/get_investigation_items'; import { getInvestigationNotes } from '../services/get_investigation_notes'; import { investigationRepositoryFactory } from '../services/investigation_repository'; import { updateInvestigation } from '../services/update_investigation'; +import { getAlertEvents, getAnnotationEvents } from '../services/get_events'; +import { AlertsClient, getAlertsClient } from '../services/get_alerts_client'; import { updateInvestigationItem } from '../services/update_investigation_item'; import { updateInvestigationNote } from '../services/update_investigation_note'; import { createInvestigateAppServerRoute } from './create_investigate_app_server_route'; @@ -313,6 +318,32 @@ const deleteInvestigationItemRoute = createInvestigateAppServerRoute({ }, }); +const getEventsRoute = createInvestigateAppServerRoute({ + endpoint: 'GET /api/observability/events 2023-10-31', + options: { + tags: [], + }, + params: getEventsParamsSchema, + handler: async ({ params, context, request, plugins }) => { + const annotationsClient: ScopedAnnotationsClient | undefined = + await plugins.observability.setup.getScopedAnnotationsClient(context, request); + const alertsClient: AlertsClient = await getAlertsClient({ plugins, request }); + const events: GetEventsResponse = []; + + if (annotationsClient) { + const annotationEvents = await getAnnotationEvents(params?.query ?? {}, annotationsClient); + events.push(...annotationEvents); + } + + if (alertsClient) { + const alertEvents = await getAlertEvents(params?.query ?? {}, alertsClient); + events.push(...alertEvents); + } + + return events; + }, +}); + export function getGlobalInvestigateAppServerRouteRepository() { return { ...createInvestigationRoute, @@ -328,6 +359,7 @@ export function getGlobalInvestigateAppServerRouteRepository() { ...deleteInvestigationItemRoute, ...updateInvestigationItemRoute, ...getInvestigationItemsRoute, + ...getEventsRoute, ...getAllInvestigationStatsRoute, ...getAllInvestigationTagsRoute, }; diff --git a/x-pack/plugins/observability_solution/investigate_app/server/routes/types.ts b/x-pack/plugins/observability_solution/investigate_app/server/routes/types.ts index 2e882296adff0..afb022cdc9b7f 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/routes/types.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/routes/types.ts @@ -14,6 +14,7 @@ import type { SavedObjectsClientContract, } from '@kbn/core/server'; import type { Logger } from '@kbn/logging'; +import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server'; import type { InvestigateAppSetupDependencies, InvestigateAppStartDependencies } from '../types'; export type InvestigateAppRequestHandlerContext = Omit< @@ -33,6 +34,7 @@ export type InvestigateAppRequestHandlerContext = Omit< }; coreStart: CoreStart; }>; + licensing: Promise; }; export interface InvestigateAppRouteHandlerResources { diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts new file mode 100644 index 0000000000000..bf1070307742a --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_alerts_client.ts @@ -0,0 +1,49 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty } from 'lodash'; +import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types'; +import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; +import { InvestigateAppRouteHandlerResources } from '../routes/types'; + +export type AlertsClient = Awaited>; + +export async function getAlertsClient({ + plugins, + request, +}: Pick) { + const ruleRegistryPluginStart = await plugins.ruleRegistry.start(); + const alertsClient = await ruleRegistryPluginStart.getRacClientWithRequest(request); + const alertsIndices = await alertsClient.getAuthorizedAlertsIndices([ + 'logs', + 'infrastructure', + 'apm', + 'slo', + 'uptime', + 'observability', + ]); + + if (!alertsIndices || isEmpty(alertsIndices)) { + throw Error('No alert indices exist'); + } + + type RequiredParams = ESSearchRequest & { + size: number; + track_total_hits: boolean | number; + }; + + return { + search( + searchParams: TParams + ): Promise> { + return alertsClient.find({ + ...searchParams, + index: alertsIndices.join(','), + }) as Promise; + }, + }; +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/services/get_events.ts b/x-pack/plugins/observability_solution/investigate_app/server/services/get_events.ts new file mode 100644 index 0000000000000..52eeea7a4cbcc --- /dev/null +++ b/x-pack/plugins/observability_solution/investigate_app/server/services/get_events.ts @@ -0,0 +1,123 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import datemath from '@elastic/datemath'; +import { estypes } from '@elastic/elasticsearch'; +import { + GetEventsParams, + GetEventsResponse, + getEventsResponseSchema, +} from '@kbn/investigation-shared'; +import { ScopedAnnotationsClient } from '@kbn/observability-plugin/server'; +import { + ALERT_REASON, + ALERT_RULE_CATEGORY, + ALERT_START, + ALERT_STATUS, + ALERT_UUID, +} from '@kbn/rule-data-utils'; +import { AlertsClient } from './get_alerts_client'; + +export function rangeQuery( + start: number, + end: number, + field = '@timestamp' +): estypes.QueryDslQueryContainer[] { + return [ + { + range: { + [field]: { + gte: start, + lte: end, + format: 'epoch_millis', + }, + }, + }, + ]; +} + +export async function getAnnotationEvents( + params: GetEventsParams, + annotationsClient: ScopedAnnotationsClient +): Promise { + const response = await annotationsClient.find({ + start: params?.rangeFrom, + end: params?.rangeTo, + filter: params?.filter, + size: 100, + }); + + // we will return only "point_in_time" annotations + const events = response.items + .filter((item) => !item.event?.end) + .map((item) => { + const hostName = item.host?.name; + const serviceName = item.service?.name; + const serviceVersion = item.service?.version; + const sloId = item.slo?.id; + const sloInstanceId = item.slo?.instanceId; + + return { + id: item.id, + title: item.annotation.title, + description: item.message, + timestamp: new Date(item['@timestamp']).getTime(), + eventType: 'annotation', + annotationType: item.annotation.type, + source: { + ...(hostName ? { 'host.name': hostName } : undefined), + ...(serviceName ? { 'service.name': serviceName } : undefined), + ...(serviceVersion ? { 'service.version': serviceVersion } : undefined), + ...(sloId ? { 'slo.id': sloId } : undefined), + ...(sloInstanceId ? { 'slo.instanceId': sloInstanceId } : undefined), + }, + }; + }); + + return getEventsResponseSchema.parse(events); +} + +export async function getAlertEvents( + params: GetEventsParams, + alertsClient: AlertsClient +): Promise { + const startInMs = datemath.parse(params?.rangeFrom ?? 'now-15m')!.valueOf(); + const endInMs = datemath.parse(params?.rangeTo ?? 'now')!.valueOf(); + const filterJSON = params?.filter ? JSON.parse(params.filter) : {}; + + const body = { + size: 100, + track_total_hits: false, + query: { + bool: { + filter: [ + ...rangeQuery(startInMs, endInMs, ALERT_START), + ...Object.keys(filterJSON).map((filterKey) => ({ + term: { [filterKey]: filterJSON[filterKey] }, + })), + ], + }, + }, + }; + + const response = await alertsClient.search(body); + + const events = response.hits.hits.map((hit) => { + const _source = hit._source; + + return { + id: _source[ALERT_UUID], + title: `${_source[ALERT_RULE_CATEGORY]} breached`, + description: _source[ALERT_REASON], + timestamp: new Date(_source['@timestamp']).getTime(), + eventType: 'alert', + alertStatus: _source[ALERT_STATUS], + }; + }); + + return getEventsResponseSchema.parse(events); +} diff --git a/x-pack/plugins/observability_solution/investigate_app/server/types.ts b/x-pack/plugins/observability_solution/investigate_app/server/types.ts index 6fa1196b23b74..fa4db6ccfcb05 100644 --- a/x-pack/plugins/observability_solution/investigate_app/server/types.ts +++ b/x-pack/plugins/observability_solution/investigate_app/server/types.ts @@ -5,13 +5,24 @@ * 2.0. */ +import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; +import { + RuleRegistryPluginSetupContract, + RuleRegistryPluginStartContract, +} from '@kbn/rule-registry-plugin/server'; + /* eslint-disable @typescript-eslint/no-empty-interface*/ export interface ConfigSchema {} -export interface InvestigateAppSetupDependencies {} +export interface InvestigateAppSetupDependencies { + observability: ObservabilityPluginSetup; + ruleRegistry: RuleRegistryPluginSetupContract; +} -export interface InvestigateAppStartDependencies {} +export interface InvestigateAppStartDependencies { + ruleRegistry: RuleRegistryPluginStartContract; +} export interface InvestigateAppServerSetup {} diff --git a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json index 03651f3530c6d..cd687f2dcfe70 100644 --- a/x-pack/plugins/observability_solution/investigate_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/investigate_app/tsconfig.json @@ -58,5 +58,8 @@ "@kbn/lens-embeddable-utils", "@kbn/i18n-react", "@kbn/zod", + "@kbn/observability-plugin", + "@kbn/licensing-plugin", + "@kbn/rule-data-utils", ], } diff --git a/x-pack/plugins/observability_solution/observability/common/annotations.ts b/x-pack/plugins/observability_solution/observability/common/annotations.ts index 16c6e11b81e86..874234acc6ced 100644 --- a/x-pack/plugins/observability_solution/observability/common/annotations.ts +++ b/x-pack/plugins/observability_solution/observability/common/annotations.ts @@ -96,6 +96,8 @@ export const findAnnotationRt = t.partial({ sloId: t.string, sloInstanceId: t.string, serviceName: t.string, + filter: t.string, + size: t.number, }); export const updateAnnotationRt = t.intersection([ diff --git a/x-pack/plugins/observability_solution/observability/server/lib/annotations/create_annotations_client.ts b/x-pack/plugins/observability_solution/observability/server/lib/annotations/create_annotations_client.ts index 6cf3b63459827..5bd7395c3ca71 100644 --- a/x-pack/plugins/observability_solution/observability/server/lib/annotations/create_annotations_client.ts +++ b/x-pack/plugins/observability_solution/observability/server/lib/annotations/create_annotations_client.ts @@ -202,7 +202,12 @@ export function createAnnotationsClient(params: { }; }), find: ensureGoldLicense(async (findParams: FindAnnotationParams) => { - const { start, end, sloId, sloInstanceId, serviceName } = findParams ?? {}; + const { start, end, sloId, sloInstanceId, serviceName, filter, size } = findParams ?? {}; + const filterJSON = filter ? JSON.parse(filter) : {}; + + const termsFilter = Object.keys(filterJSON).map((filterKey) => ({ + term: { [filterKey]: filterJSON[filterKey] }, + })); const shouldClauses: QueryDslQueryContainer[] = []; if (sloId || sloInstanceId) { @@ -246,7 +251,7 @@ export function createAnnotationsClient(params: { const result = await esClient.search({ index: readIndex, - size: 10000, + size: size ?? 10000, ignore_unavailable: true, query: { bool: { @@ -259,22 +264,26 @@ export function createAnnotationsClient(params: { }, }, }, - { - bool: { - should: [ - ...(serviceName - ? [ - { - term: { - 'service.name': serviceName, - }, - }, - ] - : []), - ...shouldClauses, - ], - }, - }, + ...(Object.keys(filterJSON).length !== 0 + ? termsFilter + : [ + { + bool: { + should: [ + ...(serviceName + ? [ + { + term: { + 'service.name': serviceName, + }, + }, + ] + : []), + ...shouldClauses, + ], + }, + }, + ]), ], }, }, From 4a2dd8a99370ce8d6678de15dd617565e5bfc5ac Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Tue, 17 Sep 2024 12:36:24 +0200 Subject: [PATCH 063/139] [APM] Empty/null service.environment error fix (#192448) fixes [192380](https://github.com/elastic/kibana/issues/192380) ## Summary Revert the `service.environment` comparison change. Using `equals` can be dangerous if the field is null, resulting in errors. The previous version worked fine, so I decided to revert the change that modified the condition. --------- Co-authored-by: Elastic Machine --- .../service_map/fetch_service_paths_from_trace_ids.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/observability_solution/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts b/x-pack/plugins/observability_solution/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts index 70d51a56c6177..5224ed833ff24 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/service_map/fetch_service_paths_from_trace_ids.ts @@ -113,6 +113,10 @@ export async function fetchServicePathsFromTraceIds({ const numDocsPerShardAllowed = calculatedDocs > terminateAfter ? terminateAfter : calculatedDocs; + /* + * Any changes to init_script, map_script, combine_script and reduce_script + * must be replicated on https://github.com/elastic/elasticsearch-serverless/blob/main/distribution/archives/src/serverless-default-settings.yml + */ const serviceMapAggs = { service_map: { scripted_metric: { @@ -224,10 +228,9 @@ export async function fetchServicePathsFromTraceIds({ // if the parent has 'span.destination.service.resource' set, and the service is different, we've discovered a service if (parent['span.destination.service.resource'] != null - && !parent['span.destination.service.resource'].equals("") - && (!parent['service.name'].equals(event['service.name']) - || !parent['service.environment'].equals(event['service.environment']) - ) + && parent['span.destination.service.resource'] != "" + && (parent['service.name'] != event['service.name'] + || parent['service.environment'] != event['service.environment']) ) { def parentDestination = getDestination(parent); context.externalToServiceMap.put(parentDestination, service); From 15c752cdc86c1ca5f7d0c30b3305e477cb14e669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:38:01 +0100 Subject: [PATCH 064/139] [Inventory] Project restructure to show entities grid (#192991) Inventory plugin restructure. Creating server API to fetch entities and initial data grid load on the page. --- .../inventory/common/entities.ts | 30 +++--- .../public/components/entities_grid/index.tsx | 68 +++++++++++++ .../entity_type_list/index.stories.tsx | 88 ----------------- .../components/entity_type_list/index.tsx | 96 ------------------- .../inventory_page_template/index.tsx | 63 ++---------- .../public/pages/inventory_page/index.tsx | 16 ++++ .../inventory/public/routes/config.tsx | 3 +- .../create_entities_es_client.ts | 80 ++++++++++++++++ .../routes/entities/get_latest_entities.ts | 27 ++++++ .../inventory/server/routes/entities/route.ts | 33 +++---- .../inventory/server/utils/with_apm_span.ts | 7 ++ .../inventory/tsconfig.json | 3 +- 12 files changed, 243 insertions(+), 271 deletions(-) create mode 100644 x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx delete mode 100644 x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.stories.tsx delete mode 100644 x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.tsx create mode 100644 x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx create mode 100644 x-pack/plugins/observability_solution/inventory/server/lib/create_es_client/create_entities_es_client.ts create mode 100644 x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts create mode 100644 x-pack/plugins/observability_solution/inventory/server/utils/with_apm_span.ts diff --git a/x-pack/plugins/observability_solution/inventory/common/entities.ts b/x-pack/plugins/observability_solution/inventory/common/entities.ts index af0e5c82b978f..d72fa46969b8a 100644 --- a/x-pack/plugins/observability_solution/inventory/common/entities.ts +++ b/x-pack/plugins/observability_solution/inventory/common/entities.ts @@ -5,16 +5,22 @@ * 2.0. */ -export interface EntityTypeDefinition { - type: string; - label: string; - icon: string; - count: number; -} - -export interface EntityDefinition { - type: string; - field: string; - filter?: string; - index: string[]; +export interface LatestEntity { + agent: { + name: string[]; + }; + data_stream: { + type: string[]; + }; + cloud: { + availability_zone: string[]; + }; + entity: { + firstSeenTimestamp: string; + lastSeenTimestamp: string; + type: string; + displayName: string; + id: string; + identityFields: string[]; + }; } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx new file mode 100644 index 0000000000000..e689063882c40 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/index.tsx @@ -0,0 +1,68 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EuiDataGrid, + EuiDataGridCellValueElementProps, + EuiDataGridColumn, + EuiLoadingSpinner, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useAbortableAsync } from '@kbn/observability-utils/hooks/use_abortable_async'; +import React, { useState } from 'react'; +import { useKibana } from '../../hooks/use_kibana'; + +const columns: EuiDataGridColumn[] = [ + { + id: 'entityName', + displayAsText: 'Entity name', + }, + { + id: 'entityType', + displayAsText: 'Type', + }, +]; + +export function EntitiesGrid() { + const { + services: { inventoryAPIClient }, + } = useKibana(); + const [visibleColumns, setVisibleColumns] = useState(columns.map(({ id }) => id)); + const { value = { entities: [] }, loading } = useAbortableAsync( + ({ signal }) => { + return inventoryAPIClient.fetch('GET /internal/inventory/entities', { + signal, + }); + }, + [inventoryAPIClient] + ); + + if (loading) { + return ; + } + + function CellValue({ rowIndex, columnId, setCellProps }: EuiDataGridCellValueElementProps) { + const data = value.entities[rowIndex]; + if (data === undefined) { + return null; + } + + return <>{data.entity.displayName}; + } + + return ( + + ); +} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.stories.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.stories.tsx deleted file mode 100644 index 570622406c9ae..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.stories.tsx +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Meta, StoryObj } from '@storybook/react'; -import React from 'react'; -import { mergePlainObjects } from '@kbn/investigate-plugin/common'; -import { EntityTypeListBase as Component } from '.'; -import { KibanaReactStorybookDecorator } from '../../../.storybook/storybook_decorator'; - -interface Args { - props: Omit, 'onLockAllClick' | 'onUnlockAllClick'>; -} - -type StoryMeta = Meta; -type Story = StoryObj; - -const meta: StoryMeta = { - component: Component, - title: 'app/Molecules/EntityTypeList', - decorators: [KibanaReactStorybookDecorator], -}; - -export default meta; - -const defaultStory: Story = { - args: { - props: { - definitions: [], - loading: true, - }, - }, - render: function Render(args) { - return ( -
- -
- ); - }, -}; - -export const Default: Story = { - ...defaultStory, - args: { - props: mergePlainObjects(defaultStory.args!.props!, { - loading: false, - definitions: [ - { - icon: 'node', - label: 'Services', - type: 'service', - count: 9, - }, - { - icon: 'pipeNoBreaks', - label: 'Datasets', - type: 'dataset', - count: 11, - }, - ], - }), - }, - name: 'default', -}; - -export const Empty: Story = { - ...defaultStory, - args: { - props: mergePlainObjects(defaultStory.args!.props!, { - definitions: [], - loading: false, - }), - }, - name: 'empty', -}; - -export const Loading: Story = { - ...defaultStory, - args: { - props: mergePlainObjects(defaultStory.args!.props!, { - loading: true, - }), - }, - name: 'loading', -}; diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.tsx deleted file mode 100644 index 47488f23f3252..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/public/components/entity_type_list/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { useAbortableAsync } from '@kbn/observability-utils/hooks/use_abortable_async'; -import { - EuiBadge, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiLink, - EuiLoadingSpinner, - EuiText, -} from '@elastic/eui'; -import { useKibana } from '../../hooks/use_kibana'; -import { EntityTypeDefinition } from '../../../common/entities'; -import { useInventoryRouter } from '../../hooks/use_inventory_router'; - -export function EntityTypeListItem({ - href, - icon, - label, - count, -}: { - href: string; - icon: string; - label: string; - count: number; -}) { - return ( - - - - - - - {label} - - - {count} - - - - ); -} - -export function EntityTypeListBase({ - definitions, - loading, - error, -}: { - loading?: boolean; - definitions?: EntityTypeDefinition[]; - error?: Error; -}) { - const router = useInventoryRouter(); - if (loading) { - return ; - } - - return ( - - {definitions?.map((definition) => { - return ( - - ); - })} - - ); -} - -export function EntityTypeList() { - const { - services: { inventoryAPIClient }, - } = useKibana(); - - const { value, loading, error } = useAbortableAsync( - ({ signal }) => { - return inventoryAPIClient.fetch('GET /internal/inventory/entity_types', { - signal, - }); - }, - [inventoryAPIClient] - ); - - return ; -} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/inventory_page_template/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/inventory_page_template/index.tsx index 386df9a51cae5..4dd8eaf3899ee 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/inventory_page_template/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/inventory_page_template/index.tsx @@ -4,13 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiFlexGroup, EuiPanel, EuiTitle } from '@elastic/eui'; -import { css } from '@emotion/css'; import { i18n } from '@kbn/i18n'; -import { useTheme } from '@kbn/observability-utils/hooks/use_theme'; import React from 'react'; import { useKibana } from '../../hooks/use_kibana'; -import { EntityTypeList } from '../entity_type_list'; export function InventoryPageTemplate({ children }: { children: React.ReactNode }) { const { @@ -19,60 +15,17 @@ export function InventoryPageTemplate({ children }: { children: React.ReactNode }, } = useKibana(); - const { PageTemplate } = observabilityShared.navigation; - - const theme = useTheme(); + const { PageTemplate: ObservabilityPageTemplate } = observabilityShared.navigation; return ( - - - - - -

- {i18n.translate('xpack.inventory.inventoryPageHeaderLabel', { - defaultMessage: 'Inventory', - })} -

-
- - - -
-
- - - {children} - -
-
+ {children} + ); } diff --git a/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx b/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx new file mode 100644 index 0000000000000..9389fdaca3ea0 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/pages/inventory_page/index.tsx @@ -0,0 +1,16 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { EntitiesGrid } from '../../components/entities_grid'; + +export function InventoryPage() { + return ( +
+ +
+ ); +} diff --git a/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx b/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx index 11d9d4836d981..74eeaac220bc2 100644 --- a/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/routes/config.tsx @@ -8,6 +8,7 @@ import * as t from 'io-ts'; import { createRouter, Outlet } from '@kbn/typed-react-router-config'; import React from 'react'; import { InventoryPageTemplate } from '../components/inventory_page_template'; +import { InventoryPage } from '../pages/inventory_page'; /** * The array of route definitions to be used when the application @@ -28,7 +29,7 @@ const inventoryRoutes = { }), }, '/': { - element: <>, + element: , }, }, }, diff --git a/x-pack/plugins/observability_solution/inventory/server/lib/create_es_client/create_entities_es_client.ts b/x-pack/plugins/observability_solution/inventory/server/lib/create_es_client/create_entities_es_client.ts new file mode 100644 index 0000000000000..983a4df3e96af --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/server/lib/create_es_client/create_entities_es_client.ts @@ -0,0 +1,80 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types'; +import type { KibanaRequest } from '@kbn/core/server'; +import { ElasticsearchClient } from '@kbn/core/server'; +import { entitiesAliasPattern, ENTITY_LATEST } from '@kbn/entities-schema'; +import { unwrapEsResponse } from '@kbn/observability-shared-plugin/common/utils/unwrap_es_response'; +// import { withApmSpan } from '../../utils/with_apm_span'; + +const ENTITIES_LATEST_ALIAS = entitiesAliasPattern({ + type: '*', + dataset: ENTITY_LATEST, +}); + +export function cancelEsRequestOnAbort>( + promise: T, + request: KibanaRequest, + controller: AbortController +): T { + const subscription = request.events.aborted$.subscribe(() => { + controller.abort(); + }); + + return promise.finally(() => subscription.unsubscribe()) as T; +} + +export interface EntitiesESClient { + searchLatest( + operationName: string, + searchRequest: TSearchRequest + ): Promise>; +} + +export function createEntitiesESClient({ + request, + esClient, +}: { + request: KibanaRequest; + esClient: ElasticsearchClient; +}) { + function search( + indexName: string, + operationName: string, + searchRequest: TSearchRequest + ): Promise> { + const controller = new AbortController(); + + const promise = // withApmSpan(operationName, () => { + cancelEsRequestOnAbort( + esClient.search( + { ...searchRequest, index: [indexName], ignore_unavailable: true }, + { + signal: controller.signal, + meta: true, + } + ) as unknown as Promise<{ + body: InferSearchResponseOf; + }>, + request, + controller + ); + // }); + // + return unwrapEsResponse(promise); + } + + return { + searchLatest( + operationName: string, + searchRequest: TSearchRequest + ): Promise> { + return search(ENTITIES_LATEST_ALIAS, operationName, searchRequest); + }, + }; +} diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts new file mode 100644 index 0000000000000..4ddcaaf75c9a4 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_latest_entities.ts @@ -0,0 +1,27 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LatestEntity } from '../../../common/entities'; +import { EntitiesESClient } from '../../lib/create_es_client/create_entities_es_client'; + +const MAX_NUMBER_OF_ENTITIES = 500; + +export async function getLatestEntities({ + entitiesESClient, +}: { + entitiesESClient: EntitiesESClient; +}) { + const response = ( + await entitiesESClient.searchLatest('get_latest_entities', { + body: { + size: MAX_NUMBER_OF_ENTITIES, + }, + }) + ).hits.hits.map((hit) => hit._source); + + return response; +} diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts index 0622ed32ac9dc..093e5ff399ed1 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/route.ts @@ -4,31 +4,28 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { i18n } from '@kbn/i18n'; -import type { EntityTypeDefinition } from '../../../common/entities'; import { createInventoryServerRoute } from '../create_inventory_server_route'; +import { createEntitiesESClient } from '../../lib/create_es_client/create_entities_es_client'; +import { getLatestEntities } from './get_latest_entities'; -export const listEntityTypesRoute = createInventoryServerRoute({ - endpoint: 'GET /internal/inventory/entity_types', +export const listLatestEntitiesRoute = createInventoryServerRoute({ + endpoint: 'GET /internal/inventory/entities', options: { tags: ['access:inventory'], }, - handler: async ({ plugins, request }): Promise<{ definitions: EntityTypeDefinition[] }> => { - return { - definitions: [ - { - label: i18n.translate('xpack.inventory.entityTypeLabels.datasets', { - defaultMessage: 'Datasets', - }), - icon: 'pipeNoBreaks', - type: 'dataset', - count: 0, - }, - ], - }; + handler: async ({ plugins, request, context }) => { + const coreContext = await context.core; + const entitiesESClient = createEntitiesESClient({ + esClient: coreContext.elasticsearch.client.asCurrentUser, + request, + }); + + const latestEntities = await getLatestEntities({ entitiesESClient }); + + return { entities: latestEntities }; }, }); export const entitiesRoutes = { - ...listEntityTypesRoute, + ...listLatestEntitiesRoute, }; diff --git a/x-pack/plugins/observability_solution/inventory/server/utils/with_apm_span.ts b/x-pack/plugins/observability_solution/inventory/server/utils/with_apm_span.ts new file mode 100644 index 0000000000000..b9e79df6cb0d7 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/server/utils/with_apm_span.ts @@ -0,0 +1,7 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +// export { withApmSpan } from '@kbn/apm-data-access-plugin/server/utils'; diff --git a/x-pack/plugins/observability_solution/inventory/tsconfig.json b/x-pack/plugins/observability_solution/inventory/tsconfig.json index 89fdd2e8fdf01..c0fc7c2692fde 100644 --- a/x-pack/plugins/observability_solution/inventory/tsconfig.json +++ b/x-pack/plugins/observability_solution/inventory/tsconfig.json @@ -24,7 +24,6 @@ "@kbn/server-route-repository", "@kbn/shared-ux-link-redirect-app", "@kbn/typed-react-router-config", - "@kbn/investigate-plugin", "@kbn/observability-utils", "@kbn/kibana-react-plugin", "@kbn/i18n", @@ -35,5 +34,7 @@ "@kbn/data-views-plugin", "@kbn/server-route-repository-client", "@kbn/react-kibana-context-render", + "@kbn/es-types", + "@kbn/entities-schema" ] } From e66450ea4c75365463698a16f23849bae7c9a0c0 Mon Sep 17 00:00:00 2001 From: Alex Szabo Date: Tue, 17 Sep 2024 12:41:33 +0200 Subject: [PATCH 065/139] [CI] Run PR against chrome-beta (#192257) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary This PR's goal is to enable developers (or automation) to test against chrome-beta with a PR label - to adjust sensitive tests, or to foresee test breakages. ⚠️ Risk: a PR verified/built with the chrome beta setting, would pass the PR tests, but might not pass the on-merge suite in the end. Addresses: https://github.com/elastic/kibana-operations/issues/199 Depends on: https://github.com/elastic/ci-agent-images/pull/907 It highlights the errors visible only on the next versions: https://buildkite.com/elastic/kibana-pull-request/builds/233373 And it doesn't break with non-beta run: https://buildkite.com/elastic/kibana-pull-request/builds/233716 --- .../ci-stats/pick_test_group_run_order.ts | 32 +++++++++++++++++-- .buildkite/scripts/steps/test/ftr_configs.sh | 13 ++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/.buildkite/pipeline-utils/ci-stats/pick_test_group_run_order.ts b/.buildkite/pipeline-utils/ci-stats/pick_test_group_run_order.ts index 1f50bccbf8049..7379ab526321a 100644 --- a/.buildkite/pipeline-utils/ci-stats/pick_test_group_run_order.ts +++ b/.buildkite/pipeline-utils/ci-stats/pick_test_group_run_order.ts @@ -197,6 +197,32 @@ function getEnabledFtrConfigs(patterns?: string[]) { } } +/** + * Collects environment variables from labels on the PR + * TODO: extract this (and other functions from this big file) to a separate module + */ +function collectEnvFromLabels() { + const LABEL_MAPPING: Record> = { + 'ci:use-chrome-beta': { + USE_CHROME_BETA: 'true', + }, + }; + + const envFromlabels: Record = {}; + if (!process.env.GITHUB_PR_LABELS) { + return envFromlabels; + } else { + const labels = process.env.GITHUB_PR_LABELS.split(','); + labels.forEach((label) => { + const env = LABEL_MAPPING[label]; + if (env) { + Object.assign(envFromlabels, env); + } + }); + return envFromlabels; + } +} + export async function pickTestGroupRunOrder() { const bk = new BuildkiteClient(); const ciStats = new CiStatsClient(); @@ -273,9 +299,10 @@ export async function pickTestGroupRunOrder() { .filter(Boolean) : ['build']; - const FTR_EXTRA_ARGS: Record = process.env.FTR_EXTRA_ARGS + const ftrExtraArgs: Record = process.env.FTR_EXTRA_ARGS ? { FTR_EXTRA_ARGS: process.env.FTR_EXTRA_ARGS } : {}; + const envFromlabels: Record = collectEnvFromLabels(); const { defaultQueue, ftrConfigsByQueue } = getEnabledFtrConfigs(FTR_CONFIG_PATTERNS); @@ -514,7 +541,8 @@ export async function pickTestGroupRunOrder() { agents: expandAgentQueue(queue), env: { FTR_CONFIG_GROUP_KEY: key, - ...FTR_EXTRA_ARGS, + ...ftrExtraArgs, + ...envFromlabels, }, retry: { automatic: [ diff --git a/.buildkite/scripts/steps/test/ftr_configs.sh b/.buildkite/scripts/steps/test/ftr_configs.sh index e9500a2244707..67fbfd9c95b20 100755 --- a/.buildkite/scripts/steps/test/ftr_configs.sh +++ b/.buildkite/scripts/steps/test/ftr_configs.sh @@ -57,6 +57,19 @@ while read -r config; do start=$(date +%s) + if [[ "${USE_CHROME_BETA:-}" =~ ^(1|true)$ ]]; then + echo "USE_CHROME_BETA was set - using google-chrome-beta" + export TEST_BROWSER_BINARY_PATH="$(which google-chrome-beta)" + + # download the beta version of chromedriver + export CHROMEDRIVER_VERSION=$(curl https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json -s | jq -r '.channels.Beta.version') + export DETECT_CHROMEDRIVER_VERSION=false + node node_modules/chromedriver/install.js --chromedriver-force-download + + # set annotation on the build + buildkite-agent annotate --style info --context chrome-beta "This build uses Google Chrome Beta @ ${CHROMEDRIVER_VERSION}" + fi + # prevent non-zero exit code from breaking the loop set +e; node ./scripts/functional_tests \ From a87e7e8e6393f8ca5e3f9772d6c8b458229984ef Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 17 Sep 2024 12:20:33 +0100 Subject: [PATCH 066/139] [Logs] Use central log sources setting for logs context resolution in Discover (#192605) ## Summary Closes https://github.com/elastic/logs-dev/issues/171. Most of the noise in the PR is from making methods async and amending test mocks, the core logic changes are in `createLogsContextService`. --- .../kbn-discover-utils/src/__mocks__/index.ts | 1 + .../src/__mocks__/logs_context_service.ts | 14 ++++++++ .../data_types/logs/logs_context_service.ts | 36 ++++++++++++++----- packages/kbn-discover-utils/tsconfig.json | 3 +- src/plugins/discover/kibana.jsonc | 3 +- .../context_awareness/__mocks__/index.tsx | 10 ++++-- .../profile_provider_services.ts | 15 ++++---- .../register_profile_providers.test.ts | 7 ++-- .../register_profile_providers.ts | 9 +++-- src/plugins/discover/public/plugin.tsx | 13 +++---- src/plugins/discover/public/types.ts | 2 ++ src/plugins/discover/tsconfig.json | 3 +- .../logs_data_access/common/constants.ts | 2 +- 13 files changed, 87 insertions(+), 31 deletions(-) create mode 100644 packages/kbn-discover-utils/src/__mocks__/logs_context_service.ts diff --git a/packages/kbn-discover-utils/src/__mocks__/index.ts b/packages/kbn-discover-utils/src/__mocks__/index.ts index 148c9a6323140..9aa3005478051 100644 --- a/packages/kbn-discover-utils/src/__mocks__/index.ts +++ b/packages/kbn-discover-utils/src/__mocks__/index.ts @@ -10,3 +10,4 @@ export * from './data_view'; export * from './es_hits'; export * from './additional_field_groups'; +export * from './logs_context_service'; diff --git a/packages/kbn-discover-utils/src/__mocks__/logs_context_service.ts b/packages/kbn-discover-utils/src/__mocks__/logs_context_service.ts new file mode 100644 index 0000000000000..86655b2275b64 --- /dev/null +++ b/packages/kbn-discover-utils/src/__mocks__/logs_context_service.ts @@ -0,0 +1,14 @@ +/* + * 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 { DEFAULT_ALLOWED_LOGS_BASE_PATTERNS_REGEXP, getLogsContextService } from '../data_types'; + +export const createLogsContextServiceMock = () => { + return getLogsContextService([DEFAULT_ALLOWED_LOGS_BASE_PATTERNS_REGEXP]); +}; diff --git a/packages/kbn-discover-utils/src/data_types/logs/logs_context_service.ts b/packages/kbn-discover-utils/src/data_types/logs/logs_context_service.ts index da858ce310e4e..7af3a723e7b14 100644 --- a/packages/kbn-discover-utils/src/data_types/logs/logs_context_service.ts +++ b/packages/kbn-discover-utils/src/data_types/logs/logs_context_service.ts @@ -8,15 +8,14 @@ */ import { createRegExpPatternFrom, testPatternAgainstAllowedList } from '@kbn/data-view-utils'; +import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public'; export interface LogsContextService { isLogsIndexPattern(indexPattern: unknown): boolean; } -// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface LogsContextServiceDeps { - // We will probably soon add uiSettings as a dependency - // to consume user configured indices + logsDataAccessPlugin?: LogsDataAccessPluginStart; } export const DEFAULT_ALLOWED_LOGS_BASE_PATTERNS = [ @@ -28,15 +27,36 @@ export const DEFAULT_ALLOWED_LOGS_BASE_PATTERNS = [ 'winlogbeat', ]; -export const createLogsContextService = (_deps: LogsContextServiceDeps = {}) => { - // This is initially an hard-coded set of well-known base patterns, - // we can extend this allowed list with any setting coming from uiSettings - const ALLOWED_LOGS_DATA_SOURCES = [createRegExpPatternFrom(DEFAULT_ALLOWED_LOGS_BASE_PATTERNS)]; +export const DEFAULT_ALLOWED_LOGS_BASE_PATTERNS_REGEXP = createRegExpPatternFrom( + DEFAULT_ALLOWED_LOGS_BASE_PATTERNS +); +export const createLogsContextService = async ({ + logsDataAccessPlugin, +}: LogsContextServiceDeps) => { + let logSources: string[] | undefined; + + if (logsDataAccessPlugin) { + const logSourcesService = logsDataAccessPlugin.services.logSourcesService; + logSources = (await logSourcesService.getLogSources()) + .map((logSource) => logSource.indexPattern) + .join(',') // TODO: Will be replaced by helper in: https://github.com/elastic/kibana/pull/192003 + .split(','); + } + + const ALLOWED_LOGS_DATA_SOURCES = [ + DEFAULT_ALLOWED_LOGS_BASE_PATTERNS_REGEXP, + ...(logSources ? logSources : []), + ]; + + return getLogsContextService(ALLOWED_LOGS_DATA_SOURCES); +}; + +export const getLogsContextService = (allowedDataSources: Array) => { const isLogsIndexPattern = (indexPattern: unknown) => { return ( typeof indexPattern === 'string' && - testPatternAgainstAllowedList(ALLOWED_LOGS_DATA_SOURCES)(indexPattern) + testPatternAgainstAllowedList(allowedDataSources)(indexPattern) ); }; diff --git a/packages/kbn-discover-utils/tsconfig.json b/packages/kbn-discover-utils/tsconfig.json index ef9ccaa7ab9b7..724051e5863c4 100644 --- a/packages/kbn-discover-utils/tsconfig.json +++ b/packages/kbn-discover-utils/tsconfig.json @@ -26,6 +26,7 @@ "@kbn/i18n", "@kbn/core-ui-settings-browser", "@kbn/ui-theme", - "@kbn/expressions-plugin" + "@kbn/expressions-plugin", + "@kbn/logs-data-access-plugin" ] } diff --git a/src/plugins/discover/kibana.jsonc b/src/plugins/discover/kibana.jsonc index e2e836ec528ee..1f5e25229df02 100644 --- a/src/plugins/discover/kibana.jsonc +++ b/src/plugins/discover/kibana.jsonc @@ -41,7 +41,8 @@ "globalSearch", "observabilityAIAssistant", "aiops", - "fieldsMetadata" + "fieldsMetadata", + "logsDataAccess" ], "requiredBundles": ["kibanaUtils", "kibanaReact", "unifiedSearch", "savedObjects"], "extraPublicDirs": ["common"] diff --git a/src/plugins/discover/public/context_awareness/__mocks__/index.tsx b/src/plugins/discover/public/context_awareness/__mocks__/index.tsx index 9c3c3d668b889..cd8ab77875afb 100644 --- a/src/plugins/discover/public/context_awareness/__mocks__/index.tsx +++ b/src/plugins/discover/public/context_awareness/__mocks__/index.tsx @@ -21,8 +21,8 @@ import { RootProfileService, SolutionType, } from '../profiles'; -import { createProfileProviderServices } from '../profile_providers/profile_provider_services'; import { ProfilesManager } from '../profiles_manager'; +import { createLogsContextServiceMock } from '@kbn/discover-utils/src/__mocks__'; export const createContextAwarenessMocks = ({ shouldRegisterProviders = true, @@ -156,7 +156,7 @@ export const createContextAwarenessMocks = ({ documentProfileServiceMock ); - const profileProviderServices = createProfileProviderServices(); + const profileProviderServices = createProfileProviderServicesMock(); return { rootProfileProviderMock, @@ -171,3 +171,9 @@ export const createContextAwarenessMocks = ({ profileProviderServices, }; }; + +const createProfileProviderServicesMock = () => { + return { + logsContextService: createLogsContextServiceMock(), + }; +}; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/profile_provider_services.ts b/src/plugins/discover/public/context_awareness/profile_providers/profile_provider_services.ts index 7abca8d6d8520..a757f24308173 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/profile_provider_services.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/profile_provider_services.ts @@ -8,14 +8,13 @@ */ import { createLogsContextService, LogsContextService } from '@kbn/discover-utils'; +import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public'; /** * Dependencies required by profile provider implementations */ -// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ProfileProviderDeps { - // We will probably soon add uiSettings as a dependency - // to consume user configured indices + logsDataAccessPlugin?: LogsDataAccessPluginStart; } /** @@ -33,10 +32,12 @@ export interface ProfileProviderServices { * @param _deps Profile provider dependencies * @returns Profile provider services */ -export const createProfileProviderServices = ( - _deps: ProfileProviderDeps = {} -): ProfileProviderServices => { +export const createProfileProviderServices = async ( + deps: ProfileProviderDeps = {} +): Promise => { return { - logsContextService: createLogsContextService(), + logsContextService: await createLogsContextService({ + logsDataAccessPlugin: deps.logsDataAccessPlugin, + }), }; }; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts b/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts index 6b0c22a3d0d08..1269441df2f21 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts @@ -8,6 +8,7 @@ */ import { createEsqlDataSource } from '../../../common/data_sources'; +import { DiscoverStartPlugins } from '../../types'; import { createContextAwarenessMocks } from '../__mocks__'; import { createExampleRootProfileProvider } from './example/example_root_pofile'; import { createExampleDataSourceProfileProvider } from './example/example_data_source_profile/profile'; @@ -73,7 +74,8 @@ describe('registerProfileProviders', () => { createContextAwarenessMocks({ shouldRegisterProviders: false, }); - registerProfileProviders({ + await registerProfileProviders({ + plugins: {} as DiscoverStartPlugins, rootProfileService: rootProfileServiceMock, dataSourceProfileService: dataSourceProfileServiceMock, documentProfileService: documentProfileServiceMock, @@ -108,7 +110,8 @@ describe('registerProfileProviders', () => { createContextAwarenessMocks({ shouldRegisterProviders: false, }); - registerProfileProviders({ + await registerProfileProviders({ + plugins: {} as DiscoverStartPlugins, rootProfileService: rootProfileServiceMock, dataSourceProfileService: dataSourceProfileServiceMock, documentProfileService: documentProfileServiceMock, diff --git a/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.ts b/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.ts index 9cd65320ac140..3bd7ee9926f2d 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.ts @@ -23,17 +23,20 @@ import { createProfileProviderServices, ProfileProviderServices, } from './profile_provider_services'; +import type { DiscoverStartPlugins } from '../../types'; /** * Register profile providers for root, data source, and document contexts to the profile profile services * @param options Register profile provider options */ -export const registerProfileProviders = ({ +export const registerProfileProviders = async ({ + plugins, rootProfileService, dataSourceProfileService, documentProfileService, enabledExperimentalProfileIds, }: { + plugins: DiscoverStartPlugins; /** * Root profile service */ @@ -51,7 +54,9 @@ export const registerProfileProviders = ({ */ enabledExperimentalProfileIds: string[]; }) => { - const providerServices = createProfileProviderServices(); + const providerServices = await createProfileProviderServices({ + logsDataAccessPlugin: plugins.logsDataAccess, + }); const rootProfileProviders = createRootProfileProviders(providerServices); const dataSourceProfileProviders = createDataSourceProfileProviders(providerServices); const documentProfileProviders = createDocumentProfileProviders(providerServices); diff --git a/src/plugins/discover/public/plugin.tsx b/src/plugins/discover/public/plugin.tsx index 5139e2342c988..a4e94205be7f4 100644 --- a/src/plugins/discover/public/plugin.tsx +++ b/src/plugins/discover/public/plugin.tsx @@ -183,7 +183,7 @@ export class DiscoverPlugin history: this.historyService.getHistory(), scopedHistory: this.scopedHistory, urlTracker: this.urlTracker!, - profilesManager: await this.createProfilesManager(), + profilesManager: await this.createProfilesManager({ plugins: discoverStartPlugins }), setHeaderActionMenu: params.setHeaderActionMenu, }); @@ -302,14 +302,15 @@ export class DiscoverPlugin } } - private createProfileServices = once(async () => { + private createProfileServices = once(async ({ plugins }: { plugins: DiscoverStartPlugins }) => { const { registerProfileProviders } = await import('./context_awareness/profile_providers'); const rootProfileService = new RootProfileService(); const dataSourceProfileService = new DataSourceProfileService(); const documentProfileService = new DocumentProfileService(); const enabledExperimentalProfileIds = this.experimentalFeatures.enabledProfiles ?? []; - registerProfileProviders({ + await registerProfileProviders({ + plugins, rootProfileService, dataSourceProfileService, documentProfileService, @@ -319,9 +320,9 @@ export class DiscoverPlugin return { rootProfileService, dataSourceProfileService, documentProfileService }; }); - private async createProfilesManager() { + private async createProfilesManager({ plugins }: { plugins: DiscoverStartPlugins }) { const { rootProfileService, dataSourceProfileService, documentProfileService } = - await this.createProfileServices(); + await this.createProfileServices({ plugins }); return new ProfilesManager( rootProfileService, @@ -367,7 +368,7 @@ export class DiscoverPlugin const getDiscoverServicesInternal = async () => { const [coreStart, deps] = await core.getStartServices(); - const profilesManager = await this.createProfilesManager(); + const profilesManager = await this.createProfilesManager({ plugins: deps }); return this.getDiscoverServices(coreStart, deps, profilesManager); }; diff --git a/src/plugins/discover/public/types.ts b/src/plugins/discover/public/types.ts index 2b6f70f74529a..916833bdce1d5 100644 --- a/src/plugins/discover/public/types.ts +++ b/src/plugins/discover/public/types.ts @@ -41,6 +41,7 @@ import type { import type { AiopsPluginStart } from '@kbn/aiops-plugin/public'; import type { DataVisualizerPluginStart } from '@kbn/data-visualizer-plugin/public'; import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public'; +import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public'; import { DiscoverAppLocator } from '../common'; import { DiscoverCustomizationContext } from './customizations'; import { type DiscoverContainerProps } from './components/discover_container'; @@ -170,4 +171,5 @@ export interface DiscoverStartPlugins { urlForwarding: UrlForwardingStart; usageCollection?: UsageCollectionSetup; fieldsMetadata: FieldsMetadataPublicStart; + logsDataAccess?: LogsDataAccessPluginStart; } diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index a363981a5d731..51e797b179952 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -95,7 +95,8 @@ "@kbn/presentation-containers", "@kbn/observability-ai-assistant-plugin", "@kbn/fields-metadata-plugin", - "@kbn/security-solution-common" + "@kbn/security-solution-common", + "@kbn/logs-data-access-plugin" ], "exclude": [ "target/**/*" diff --git a/x-pack/plugins/observability_solution/logs_data_access/common/constants.ts b/x-pack/plugins/observability_solution/logs_data_access/common/constants.ts index c0caaa846f56e..ffe5a83f245e8 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/common/constants.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/common/constants.ts @@ -5,4 +5,4 @@ * 2.0. */ -export const DEFAULT_LOG_SOURCES = ['logs-*-*,logs-*,filebeat-*,kibana_sample_data_logs*']; +export const DEFAULT_LOG_SOURCES = ['logs-*-*', 'logs-*', 'filebeat-*', 'kibana_sample_data_logs*']; From 5c5897966ab0d6caaba64d943d91d0485dde16f2 Mon Sep 17 00:00:00 2001 From: natasha-moore-elastic <137783811+natasha-moore-elastic@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:24:07 +0100 Subject: [PATCH 067/139] Improves Lists API docs content (#192504) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Resolves https://github.com/elastic/security-docs-internal/issues/32 by improving the Lists API docs content. Adds missing and improves existing operation summaries and operation descriptions to adhere to our [OAS standards](https://elasticco.atlassian.net/wiki/spaces/DOC/pages/450494532/API+reference+docs). Note: Couldn’t add description for the GET /api/lists/privileges operation, since it's not documented in [ESS API docs](https://www.elastic.co/guide/en/security/8.15/security-apis.html). --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../api/create_list/create_list.schema.yaml | 3 +- .../create_list_index.schema.yaml | 3 +- .../create_list_item.schema.yaml | 8 +- .../api/delete_list/delete_list.schema.yaml | 6 +- .../delete_list_index.schema.yaml | 3 +- .../delete_list_item.schema.yaml | 3 +- .../export_list_items.schema.yaml | 4 +- .../find_list_items.schema.yaml | 3 +- .../api/find_lists/find_lists.schema.yaml | 3 +- .../import_list_items.schema.yaml | 4 +- .../api/patch_list/patch_list.schema.yaml | 3 +- .../patch_list_item.schema.yaml | 3 +- .../api/quickstart_client.gen.ts | 63 +++++++++++++- .../api/read_list/read_list.schema.yaml | 3 +- .../read_list_index.schema.yaml | 3 +- .../read_list_item/read_list_item.schema.yaml | 3 +- .../read_list_privileges.schema.yaml | 2 +- .../api/update_list/update_list.schema.yaml | 6 +- .../update_list_item.schema.yaml | 6 +- ...n_lists_api_2023_10_31.bundled.schema.yaml | 83 ++++++++++++++----- ...n_lists_api_2023_10_31.bundled.schema.yaml | 83 ++++++++++++++----- .../security_solution_lists_api.gen.ts | 63 +++++++++++++- 22 files changed, 295 insertions(+), 66 deletions(-) diff --git a/packages/kbn-securitysolution-lists-common/api/create_list/create_list.schema.yaml b/packages/kbn-securitysolution-lists-common/api/create_list/create_list.schema.yaml index bae6565b0f1e0..191e973beba61 100644 --- a/packages/kbn-securitysolution-lists-common/api/create_list/create_list.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/create_list/create_list.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: CreateList x-codegen-enabled: true - summary: Creates a list + summary: Create a list + description: Create a new list. requestBody: description: List's properties required: true diff --git a/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.schema.yaml b/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.schema.yaml index dcb1baa3ee3d8..c775a9c7d873f 100644 --- a/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/create_list_index/create_list_index.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: CreateListIndex x-codegen-enabled: true - summary: Creates necessary list data streams + summary: Create list data streams + description: Create `.lists` and `.items` data streams in the relevant space. responses: 200: description: Successful response diff --git a/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.schema.yaml b/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.schema.yaml index 10fef88e7a042..01121d0143925 100644 --- a/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/create_list_item/create_list_item.schema.yaml @@ -8,7 +8,13 @@ paths: x-labels: [serverless, ess] operationId: CreateListItem x-codegen-enabled: true - summary: Creates a list item + summary: Create a list item + description: | + Create a list item and associate it with the specified list. + + All list items in the same list must be the same type. For example, each list item in an `ip` list must define a specific IP address. + > info + > Before creating a list item, you must create a list. requestBody: description: List item's properties required: true diff --git a/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.schema.yaml b/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.schema.yaml index 4a5974003918e..7098753636379 100644 --- a/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/delete_list/delete_list.schema.yaml @@ -8,7 +8,11 @@ paths: x-labels: [serverless, ess] operationId: DeleteList x-codegen-enabled: true - summary: Deletes a list + summary: Delete a list + description: | + Delete a list using the list ID. + > info + > When you delete a list, all of its list items are also deleted. parameters: - name: id in: query diff --git a/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.schema.yaml b/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.schema.yaml index 34dcf91f548d0..4f4b0f00e8817 100644 --- a/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/delete_list_index/delete_list_index.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: DeleteListIndex x-codegen-enabled: true - summary: Deletes list data streams + summary: Delete list data streams + description: Delete the `.lists` and `.items` data streams. responses: 200: description: Successful response diff --git a/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.schema.yaml b/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.schema.yaml index 413c85b55dd3b..28913259387dd 100644 --- a/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/delete_list_item/delete_list_item.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: DeleteListItem x-codegen-enabled: true - summary: Deletes a list item + summary: Delete a list item + description: Delete a list item using its `id`, or its `list_id` and `value` fields. parameters: - name: id in: query diff --git a/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.schema.yaml b/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.schema.yaml index 06eda41d042fb..8d185a23b64c9 100644 --- a/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/export_list_items/export_list_items.schema.yaml @@ -8,8 +8,8 @@ paths: x-labels: [serverless, ess] operationId: ExportListItems x-codegen-enabled: true - summary: Exports list items - description: Exports list item values from the specified list + summary: Export list items + description: Export list item values from the specified list. parameters: - name: list_id in: query diff --git a/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.schema.yaml b/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.schema.yaml index b08e7b4719374..21cf4ffd61841 100644 --- a/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/find_list_items/find_list_items.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: FindListItems x-codegen-enabled: true - summary: Finds list items + summary: Get list items + description: Get all list items in the specified list. parameters: - name: list_id in: query diff --git a/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.schema.yaml b/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.schema.yaml index 071dba08254ec..3bb55decacff6 100644 --- a/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/find_lists/find_lists.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: FindLists x-codegen-enabled: true - summary: Finds lists + summary: Get lists + description: Get a paginated subset of lists. By default, the first page is returned, with 20 results per page. parameters: - name: page in: query diff --git a/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.schema.yaml b/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.schema.yaml index 895e222c05207..520213e949c1d 100644 --- a/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/import_list_items/import_list_items.schema.yaml @@ -8,9 +8,9 @@ paths: x-labels: [serverless, ess] operationId: ImportListItems x-codegen-enabled: true - summary: Imports list items + summary: Import list items description: | - Imports a list of items from a `.txt` or `.csv` file. The maximum file size is 9 million bytes. + Import list items from a TXT or CSV file. The maximum file size is 9 million bytes. You can import items to a new or existing list. requestBody: diff --git a/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.schema.yaml b/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.schema.yaml index 1ca568acb2bbc..b98b34e6347eb 100644 --- a/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/patch_list/patch_list.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: PatchList x-codegen-enabled: true - summary: Patches a list + summary: Patch a list + description: Update specific fields of an existing list using the list ID. requestBody: description: List's properties required: true diff --git a/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.schema.yaml b/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.schema.yaml index a17982db14452..f79efc4691dde 100644 --- a/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/patch_list_item/patch_list_item.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: PatchListItem x-codegen-enabled: true - summary: Patches a list item + summary: Patch a list item + description: Update specific fields of an existing list item using the list item ID. requestBody: description: List item's properties required: true diff --git a/packages/kbn-securitysolution-lists-common/api/quickstart_client.gen.ts b/packages/kbn-securitysolution-lists-common/api/quickstart_client.gen.ts index a6e314cd5d717..7bf343d935f2c 100644 --- a/packages/kbn-securitysolution-lists-common/api/quickstart_client.gen.ts +++ b/packages/kbn-securitysolution-lists-common/api/quickstart_client.gen.ts @@ -77,6 +77,9 @@ export class Client { this.kbnClient = options.kbnClient; this.log = options.log; } + /** + * Create a new list. + */ async createList(props: CreateListProps) { this.log.info(`${new Date().toISOString()} Calling API CreateList`); return this.kbnClient @@ -90,6 +93,9 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Create `.lists` and `.items` data streams in the relevant space. + */ async createListIndex() { this.log.info(`${new Date().toISOString()} Calling API CreateListIndex`); return this.kbnClient @@ -102,6 +108,14 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Create a list item and associate it with the specified list. + +All list items in the same list must be the same type. For example, each list item in an `ip` list must define a specific IP address. +> info +> Before creating a list item, you must create a list. + + */ async createListItem(props: CreateListItemProps) { this.log.info(`${new Date().toISOString()} Calling API CreateListItem`); return this.kbnClient @@ -115,6 +129,12 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Delete a list using the list ID. +> info +> When you delete a list, all of its list items are also deleted. + + */ async deleteList(props: DeleteListProps) { this.log.info(`${new Date().toISOString()} Calling API DeleteList`); return this.kbnClient @@ -129,6 +149,9 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Delete the `.lists` and `.items` data streams. + */ async deleteListIndex() { this.log.info(`${new Date().toISOString()} Calling API DeleteListIndex`); return this.kbnClient @@ -141,6 +164,9 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Delete a list item using its `id`, or its `list_id` and `value` fields. + */ async deleteListItem(props: DeleteListItemProps) { this.log.info(`${new Date().toISOString()} Calling API DeleteListItem`); return this.kbnClient @@ -156,7 +182,7 @@ export class Client { .catch(catchAxiosErrorFormatAndThrow); } /** - * Exports list item values from the specified list + * Export list item values from the specified list. */ async exportListItems(props: ExportListItemsProps) { this.log.info(`${new Date().toISOString()} Calling API ExportListItems`); @@ -172,6 +198,9 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Get all list items in the specified list. + */ async findListItems(props: FindListItemsProps) { this.log.info(`${new Date().toISOString()} Calling API FindListItems`); return this.kbnClient @@ -186,6 +215,9 @@ export class Client { }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Get a paginated subset of lists. By default, the first page is returned, with 20 results per page. + */ async findLists(props: FindListsProps) { this.log.info(`${new Date().toISOString()} Calling API FindLists`); return this.kbnClient @@ -201,7 +233,7 @@ export class Client { .catch(catchAxiosErrorFormatAndThrow); } /** - * Imports a list of items from a `.txt` or `.csv` file. The maximum file size is 9 million bytes. + * Import list items from a TXT or CSV file. The maximum file size is 9 million bytes. You can import items to a new or existing list. @@ -220,6 +252,9 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Update specific fields of an existing list using the list ID. + */ async patchList(props: PatchListProps) { this.log.info(`${new Date().toISOString()} Calling API PatchList`); return this.kbnClient @@ -233,6 +268,9 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Update specific fields of an existing list item using the list item ID. + */ async patchListItem(props: PatchListItemProps) { this.log.info(`${new Date().toISOString()} Calling API PatchListItem`); return this.kbnClient @@ -246,6 +284,9 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Get the details of a list using the list ID. + */ async readList(props: ReadListProps) { this.log.info(`${new Date().toISOString()} Calling API ReadList`); return this.kbnClient @@ -260,6 +301,9 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Verify that `.lists` and `.items` data streams exist. + */ async readListIndex() { this.log.info(`${new Date().toISOString()} Calling API ReadListIndex`); return this.kbnClient @@ -272,6 +316,9 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Get the details of a list item. + */ async readListItem(props: ReadListItemProps) { this.log.info(`${new Date().toISOString()} Calling API ReadListItem`); return this.kbnClient @@ -298,6 +345,12 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Update a list using the list ID. The original list is replaced, and all unspecified fields are deleted. +> info +> You cannot modify the `id` value. + + */ async updateList(props: UpdateListProps) { this.log.info(`${new Date().toISOString()} Calling API UpdateList`); return this.kbnClient @@ -311,6 +364,12 @@ You can import items to a new or existing list. }) .catch(catchAxiosErrorFormatAndThrow); } + /** + * Update a list item using the list item ID. The original list item is replaced, and all unspecified fields are deleted. +> info +> You cannot modify the `id` value. + + */ async updateListItem(props: UpdateListItemProps) { this.log.info(`${new Date().toISOString()} Calling API UpdateListItem`); return this.kbnClient diff --git a/packages/kbn-securitysolution-lists-common/api/read_list/read_list.schema.yaml b/packages/kbn-securitysolution-lists-common/api/read_list/read_list.schema.yaml index 770c6fa8a9e7d..d932e16f528a5 100644 --- a/packages/kbn-securitysolution-lists-common/api/read_list/read_list.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/read_list/read_list.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: ReadList x-codegen-enabled: true - summary: Retrieves a list using its id field + summary: Get list details + description: Get the details of a list using the list ID. parameters: - name: id in: query diff --git a/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.schema.yaml b/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.schema.yaml index 3706563c008ce..b675264600157 100644 --- a/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/read_list_index/read_list_index.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: ReadListIndex x-codegen-enabled: true - summary: Get list data stream existence status + summary: Get status of list data streams + description: Verify that `.lists` and `.items` data streams exist. responses: 200: description: Successful response diff --git a/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.schema.yaml b/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.schema.yaml index fe4a6046f012c..4d686f5452e0c 100644 --- a/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/read_list_item/read_list_item.schema.yaml @@ -8,7 +8,8 @@ paths: x-labels: [serverless, ess] operationId: ReadListItem x-codegen-enabled: true - summary: Gets a list item + summary: Get a list item + description: Get the details of a list item. parameters: - name: id in: query diff --git a/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.schema.yaml b/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.schema.yaml index fd22321c9ed29..ec8604e80694e 100644 --- a/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/read_list_privileges/read_list_privileges.schema.yaml @@ -8,7 +8,7 @@ paths: x-labels: [serverless, ess] operationId: ReadListPrivileges x-codegen-enabled: true - summary: Gets list privileges + summary: Get list privileges responses: 200: description: Successful response diff --git a/packages/kbn-securitysolution-lists-common/api/update_list/update_list.schema.yaml b/packages/kbn-securitysolution-lists-common/api/update_list/update_list.schema.yaml index b31bea393c91b..c41b52427b63d 100644 --- a/packages/kbn-securitysolution-lists-common/api/update_list/update_list.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/update_list/update_list.schema.yaml @@ -8,7 +8,11 @@ paths: x-labels: [serverless, ess] operationId: UpdateList x-codegen-enabled: true - summary: Updates a list + summary: Update a list + description: | + Update a list using the list ID. The original list is replaced, and all unspecified fields are deleted. + > info + > You cannot modify the `id` value. requestBody: description: List's properties required: true diff --git a/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.schema.yaml b/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.schema.yaml index 95a4df349ff93..6b05e01f35aab 100644 --- a/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/api/update_list_item/update_list_item.schema.yaml @@ -8,7 +8,11 @@ paths: x-labels: [serverless, ess] operationId: UpdateListItem x-codegen-enabled: true - summary: Updates a list item + summary: Update a list item + description: | + Update a list item using the list item ID. The original list item is replaced, and all unspecified fields are deleted. + > info + > You cannot modify the `id` value. requestBody: description: List item's properties required: true diff --git a/packages/kbn-securitysolution-lists-common/docs/openapi/ess/security_solution_lists_api_2023_10_31.bundled.schema.yaml b/packages/kbn-securitysolution-lists-common/docs/openapi/ess/security_solution_lists_api_2023_10_31.bundled.schema.yaml index 7fdb215489101..2db10e5afbcec 100644 --- a/packages/kbn-securitysolution-lists-common/docs/openapi/ess/security_solution_lists_api_2023_10_31.bundled.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/docs/openapi/ess/security_solution_lists_api_2023_10_31.bundled.schema.yaml @@ -13,6 +13,10 @@ servers: paths: /api/lists: delete: + description: | + Delete a list using the list ID. + > info + > When you delete a list, all of its list items are also deleted. operationId: DeleteList parameters: - description: List's `id` value @@ -72,10 +76,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Deletes a list + summary: Delete a list tags: - Security Solution Lists API get: + description: Get the details of a list using the list ID. operationId: ReadList parameters: - description: List's `id` value @@ -123,10 +128,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Retrieves a list using its id field + summary: Get list details tags: - Security Solution Lists API patch: + description: Update specific fields of an existing list using the list ID. operationId: PatchList requestBody: content: @@ -190,10 +196,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Patches a list + summary: Patch a list tags: - Security Solution Lists API post: + description: Create a new list. operationId: CreateList requestBody: content: @@ -264,10 +271,17 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Creates a list + summary: Create a list tags: - Security Solution Lists API put: + description: > + Update a list using the list ID. The original list is replaced, and all + unspecified fields are deleted. + + > info + + > You cannot modify the `id` value. operationId: UpdateList requestBody: content: @@ -333,11 +347,14 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Updates a list + summary: Update a list tags: - Security Solution Lists API /api/lists/_find: get: + description: >- + Get a paginated subset of lists. By default, the first page is returned, + with 20 results per page. operationId: FindLists parameters: - description: The page number to return @@ -446,11 +463,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Finds lists + summary: Get lists tags: - Security Solution Lists API /api/lists/index: delete: + description: Delete the `.lists` and `.items` data streams. operationId: DeleteListIndex responses: '200': @@ -496,10 +514,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Deletes list data streams + summary: Delete list data streams tags: - Security Solution Lists API get: + description: Verify that `.lists` and `.items` data streams exist. operationId: ReadListIndex responses: '200': @@ -548,10 +567,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Get list data stream existence status + summary: Get status of list data streams tags: - Security Solution Lists API post: + description: Create `.lists` and `.items` data streams in the relevant space. operationId: CreateListIndex responses: '200': @@ -597,11 +617,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Creates necessary list data streams + summary: Create list data streams tags: - Security Solution Lists API /api/lists/items: delete: + description: 'Delete a list item using its `id`, or its `list_id` and `value` fields.' operationId: DeleteListItem parameters: - description: Required if `list_id` and `value` are not specified @@ -678,10 +699,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Deletes a list item + summary: Delete a list item tags: - Security Solution Lists API get: + description: Get the details of a list item. operationId: ReadListItem parameters: - description: Required if `list_id` and `value` are not specified @@ -745,10 +767,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Gets a list item + summary: Get a list item tags: - Security Solution Lists API patch: + description: Update specific fields of an existing list item using the list item ID. operationId: PatchListItem requestBody: content: @@ -816,10 +839,20 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Patches a list item + summary: Patch a list item tags: - Security Solution Lists API post: + description: > + Create a list item and associate it with the specified list. + + + All list items in the same list must be the same type. For example, each + list item in an `ip` list must define a specific IP address. + + > info + + > Before creating a list item, you must create a list. operationId: CreateListItem requestBody: content: @@ -888,10 +921,17 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Creates a list item + summary: Create a list item tags: - Security Solution Lists API put: + description: > + Update a list item using the list item ID. The original list item is + replaced, and all unspecified fields are deleted. + + > info + + > You cannot modify the `id` value. operationId: UpdateListItem requestBody: content: @@ -951,12 +991,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Updates a list item + summary: Update a list item tags: - Security Solution Lists API /api/lists/items/_export: post: - description: Exports list item values from the specified list + description: Export list item values from the specified list. operationId: ExportListItems parameters: - description: List's id to export @@ -1006,11 +1046,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Exports list items + summary: Export list items tags: - Security Solution Lists API /api/lists/items/_find: get: + description: Get all list items in the specified list. operationId: FindListItems parameters: - description: List's id @@ -1125,14 +1166,14 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Finds list items + summary: Get list items tags: - Security Solution Lists API /api/lists/items/_import: post: description: > - Imports a list of items from a `.txt` or `.csv` file. The maximum file - size is 9 million bytes. + Import list items from a TXT or CSV file. The maximum file size is 9 + million bytes. You can import items to a new or existing list. @@ -1232,7 +1273,7 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Imports list items + summary: Import list items tags: - Security Solution Lists API /api/lists/privileges: @@ -1282,7 +1323,7 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Gets list privileges + summary: Get list privileges tags: - Security Solution Lists API components: diff --git a/packages/kbn-securitysolution-lists-common/docs/openapi/serverless/security_solution_lists_api_2023_10_31.bundled.schema.yaml b/packages/kbn-securitysolution-lists-common/docs/openapi/serverless/security_solution_lists_api_2023_10_31.bundled.schema.yaml index c55ffe963a607..4f91b5112bfd0 100644 --- a/packages/kbn-securitysolution-lists-common/docs/openapi/serverless/security_solution_lists_api_2023_10_31.bundled.schema.yaml +++ b/packages/kbn-securitysolution-lists-common/docs/openapi/serverless/security_solution_lists_api_2023_10_31.bundled.schema.yaml @@ -13,6 +13,10 @@ servers: paths: /api/lists: delete: + description: | + Delete a list using the list ID. + > info + > When you delete a list, all of its list items are also deleted. operationId: DeleteList parameters: - description: List's `id` value @@ -72,10 +76,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Deletes a list + summary: Delete a list tags: - Security Solution Lists API get: + description: Get the details of a list using the list ID. operationId: ReadList parameters: - description: List's `id` value @@ -123,10 +128,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Retrieves a list using its id field + summary: Get list details tags: - Security Solution Lists API patch: + description: Update specific fields of an existing list using the list ID. operationId: PatchList requestBody: content: @@ -190,10 +196,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Patches a list + summary: Patch a list tags: - Security Solution Lists API post: + description: Create a new list. operationId: CreateList requestBody: content: @@ -264,10 +271,17 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Creates a list + summary: Create a list tags: - Security Solution Lists API put: + description: > + Update a list using the list ID. The original list is replaced, and all + unspecified fields are deleted. + + > info + + > You cannot modify the `id` value. operationId: UpdateList requestBody: content: @@ -333,11 +347,14 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Updates a list + summary: Update a list tags: - Security Solution Lists API /api/lists/_find: get: + description: >- + Get a paginated subset of lists. By default, the first page is returned, + with 20 results per page. operationId: FindLists parameters: - description: The page number to return @@ -446,11 +463,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Finds lists + summary: Get lists tags: - Security Solution Lists API /api/lists/index: delete: + description: Delete the `.lists` and `.items` data streams. operationId: DeleteListIndex responses: '200': @@ -496,10 +514,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Deletes list data streams + summary: Delete list data streams tags: - Security Solution Lists API get: + description: Verify that `.lists` and `.items` data streams exist. operationId: ReadListIndex responses: '200': @@ -548,10 +567,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Get list data stream existence status + summary: Get status of list data streams tags: - Security Solution Lists API post: + description: Create `.lists` and `.items` data streams in the relevant space. operationId: CreateListIndex responses: '200': @@ -597,11 +617,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Creates necessary list data streams + summary: Create list data streams tags: - Security Solution Lists API /api/lists/items: delete: + description: 'Delete a list item using its `id`, or its `list_id` and `value` fields.' operationId: DeleteListItem parameters: - description: Required if `list_id` and `value` are not specified @@ -678,10 +699,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Deletes a list item + summary: Delete a list item tags: - Security Solution Lists API get: + description: Get the details of a list item. operationId: ReadListItem parameters: - description: Required if `list_id` and `value` are not specified @@ -745,10 +767,11 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Gets a list item + summary: Get a list item tags: - Security Solution Lists API patch: + description: Update specific fields of an existing list item using the list item ID. operationId: PatchListItem requestBody: content: @@ -816,10 +839,20 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Patches a list item + summary: Patch a list item tags: - Security Solution Lists API post: + description: > + Create a list item and associate it with the specified list. + + + All list items in the same list must be the same type. For example, each + list item in an `ip` list must define a specific IP address. + + > info + + > Before creating a list item, you must create a list. operationId: CreateListItem requestBody: content: @@ -888,10 +921,17 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Creates a list item + summary: Create a list item tags: - Security Solution Lists API put: + description: > + Update a list item using the list item ID. The original list item is + replaced, and all unspecified fields are deleted. + + > info + + > You cannot modify the `id` value. operationId: UpdateListItem requestBody: content: @@ -951,12 +991,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Updates a list item + summary: Update a list item tags: - Security Solution Lists API /api/lists/items/_export: post: - description: Exports list item values from the specified list + description: Export list item values from the specified list. operationId: ExportListItems parameters: - description: List's id to export @@ -1006,11 +1046,12 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Exports list items + summary: Export list items tags: - Security Solution Lists API /api/lists/items/_find: get: + description: Get all list items in the specified list. operationId: FindListItems parameters: - description: List's id @@ -1125,14 +1166,14 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Finds list items + summary: Get list items tags: - Security Solution Lists API /api/lists/items/_import: post: description: > - Imports a list of items from a `.txt` or `.csv` file. The maximum file - size is 9 million bytes. + Import list items from a TXT or CSV file. The maximum file size is 9 + million bytes. You can import items to a new or existing list. @@ -1232,7 +1273,7 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Imports list items + summary: Import list items tags: - Security Solution Lists API /api/lists/privileges: @@ -1282,7 +1323,7 @@ paths: schema: $ref: '#/components/schemas/SiemErrorResponse' description: Internal server error response - summary: Gets list privileges + summary: Get list privileges tags: - Security Solution Lists API components: diff --git a/x-pack/test/api_integration/services/security_solution_lists_api.gen.ts b/x-pack/test/api_integration/services/security_solution_lists_api.gen.ts index 4ebd688bf296a..6ae8c4d1d4903 100644 --- a/x-pack/test/api_integration/services/security_solution_lists_api.gen.ts +++ b/x-pack/test/api_integration/services/security_solution_lists_api.gen.ts @@ -39,6 +39,9 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) const supertest = getService('supertest'); return { + /** + * Create a new list. + */ createList(props: CreateListProps) { return supertest .post('/api/lists') @@ -47,6 +50,9 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + /** + * Create `.lists` and `.items` data streams in the relevant space. + */ createListIndex() { return supertest .post('/api/lists/index') @@ -54,6 +60,14 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, + /** + * Create a list item and associate it with the specified list. + +All list items in the same list must be the same type. For example, each list item in an `ip` list must define a specific IP address. +> info +> Before creating a list item, you must create a list. + + */ createListItem(props: CreateListItemProps) { return supertest .post('/api/lists/items') @@ -62,6 +76,12 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + /** + * Delete a list using the list ID. +> info +> When you delete a list, all of its list items are also deleted. + + */ deleteList(props: DeleteListProps) { return supertest .delete('/api/lists') @@ -70,6 +90,9 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .query(props.query); }, + /** + * Delete the `.lists` and `.items` data streams. + */ deleteListIndex() { return supertest .delete('/api/lists/index') @@ -77,6 +100,9 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, + /** + * Delete a list item using its `id`, or its `list_id` and `value` fields. + */ deleteListItem(props: DeleteListItemProps) { return supertest .delete('/api/lists/items') @@ -86,7 +112,7 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .query(props.query); }, /** - * Exports list item values from the specified list + * Export list item values from the specified list. */ exportListItems(props: ExportListItemsProps) { return supertest @@ -96,6 +122,9 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .query(props.query); }, + /** + * Get all list items in the specified list. + */ findListItems(props: FindListItemsProps) { return supertest .get('/api/lists/items/_find') @@ -104,6 +133,9 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .query(props.query); }, + /** + * Get a paginated subset of lists. By default, the first page is returned, with 20 results per page. + */ findLists(props: FindListsProps) { return supertest .get('/api/lists/_find') @@ -113,7 +145,7 @@ export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) .query(props.query); }, /** - * Imports a list of items from a `.txt` or `.csv` file. The maximum file size is 9 million bytes. + * Import list items from a TXT or CSV file. The maximum file size is 9 million bytes. You can import items to a new or existing list. @@ -126,6 +158,9 @@ You can import items to a new or existing list. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .query(props.query); }, + /** + * Update specific fields of an existing list using the list ID. + */ patchList(props: PatchListProps) { return supertest .patch('/api/lists') @@ -134,6 +169,9 @@ You can import items to a new or existing list. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + /** + * Update specific fields of an existing list item using the list item ID. + */ patchListItem(props: PatchListItemProps) { return supertest .patch('/api/lists/items') @@ -142,6 +180,9 @@ You can import items to a new or existing list. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + /** + * Get the details of a list using the list ID. + */ readList(props: ReadListProps) { return supertest .get('/api/lists') @@ -150,6 +191,9 @@ You can import items to a new or existing list. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .query(props.query); }, + /** + * Verify that `.lists` and `.items` data streams exist. + */ readListIndex() { return supertest .get('/api/lists/index') @@ -157,6 +201,9 @@ You can import items to a new or existing list. .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, + /** + * Get the details of a list item. + */ readListItem(props: ReadListItemProps) { return supertest .get('/api/lists/items') @@ -172,6 +219,12 @@ You can import items to a new or existing list. .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana'); }, + /** + * Update a list using the list ID. The original list is replaced, and all unspecified fields are deleted. +> info +> You cannot modify the `id` value. + + */ updateList(props: UpdateListProps) { return supertest .put('/api/lists') @@ -180,6 +233,12 @@ You can import items to a new or existing list. .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send(props.body as object); }, + /** + * Update a list item using the list item ID. The original list item is replaced, and all unspecified fields are deleted. +> info +> You cannot modify the `id` value. + + */ updateListItem(props: UpdateListItemProps) { return supertest .put('/api/lists/items') From da2f7f6dae265e29713e5c6586c542499b03bcd6 Mon Sep 17 00:00:00 2001 From: Justin Kambic Date: Tue, 17 Sep 2024 08:08:51 -0400 Subject: [PATCH 068/139] [Synthetics] Fix issue where heatmap UI crashes on undefined histogram data (#192508) ## Summary Recently, [we fixed](https://github.com/elastic/kibana/pull/184177) an [issue](https://github.com/elastic/kibana/issues/180076) where the heatmap data on the detail and monitor history pages would not fill up. A side effect of this fix was a new regression that caused certain rarer cases to see the page crash because of an unhandled case of calling a function on a potentially-null object; our histogram data used to populate this heatmap can be `undefined` in certain cases. This patch introduces a change that will handle this case, and adds unit tests for the module in question. ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Shahzad --- .../monitor_status_data.test.ts | 87 +++++++++++++++++++ .../monitor_status/monitor_status_data.ts | 13 ++- .../monitor_status/use_monitor_status_data.ts | 2 +- .../synthetics/state/status_heatmap/index.ts | 2 +- 4 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.test.ts diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.test.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.test.ts new file mode 100644 index 0000000000000..488db9c2a112b --- /dev/null +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.test.ts @@ -0,0 +1,87 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { createStatusTimeBins, getStatusEffectiveValue } from './monitor_status_data'; + +describe('createStatusTimeBins', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should return default values when `heatmapData` is `undefined`', () => { + const timeBuckets = [ + { start: 1000, end: 2000 }, + { start: 2000, end: 3000 }, + ]; + + const result = createStatusTimeBins(timeBuckets, undefined); + + expect(result).toEqual([ + { start: 1000, end: 2000, ups: 0, downs: 0, value: 0 }, + { start: 2000, end: 3000, ups: 0, downs: 0, value: 0 }, + ]); + }); + + it('should calculate `ups` and `downs` correctly from `heatmapData`', () => { + const timeBuckets = [ + { start: 1000, end: 2000 }, + { start: 2000, end: 3000 }, + ]; + + const heatmapData = [ + { key: 1500, key_as_string: '1500', up: { value: 1 }, down: { value: 2 }, doc_count: 3 }, + { key: 2500, key_as_string: '2500', up: { value: 3 }, down: { value: 1 }, doc_count: 4 }, + ]; + + const result = createStatusTimeBins(timeBuckets, heatmapData); + + expect(result).toEqual([ + { start: 1000, end: 2000, ups: 1, downs: 2, value: getStatusEffectiveValue(1, 2) }, + { start: 2000, end: 3000, ups: 3, downs: 1, value: getStatusEffectiveValue(3, 1) }, + ]); + }); + + it('should return value 0 when ups + downs is 0', () => { + const timeBuckets = [ + { start: 1000, end: 2000 }, + { start: 2000, end: 3000 }, + ]; + + const heatmapData = [ + { key: 1500, key_as_string: '1500', up: { value: 0 }, down: { value: 0 }, doc_count: 0 }, + { key: 2500, key_as_string: '2500', up: { value: 0 }, down: { value: 0 }, doc_count: 0 }, + ]; + + const result = createStatusTimeBins(timeBuckets, heatmapData); + + expect(result).toEqual([ + { start: 1000, end: 2000, ups: 0, downs: 0, value: 0 }, + { start: 2000, end: 3000, ups: 0, downs: 0, value: 0 }, + ]); + }); + + it('should filter heatmapData correctly based on start and end values', () => { + const timeBuckets = [ + { start: 1000, end: 2000 }, + { start: 2000, end: 3000 }, + ]; + + const heatmapData = [ + { key: 500, key_as_string: '500', doc_count: 2, up: { value: 1 }, down: { value: 1 } }, + { key: 1500, key_as_string: '1500', doc_count: 5, up: { value: 2 }, down: { value: 3 } }, + { key: 2500, key_as_string: '2500', doc_count: 9, up: { value: 4 }, down: { value: 5 } }, + { key: 3500, key_as_string: '3500', doc_count: 1, up: { value: 6 }, down: { value: 7 } }, + ]; + + const result = createStatusTimeBins(timeBuckets, heatmapData); + + expect(result).toEqual([ + { start: 1000, end: 2000, ups: 2, downs: 3, value: getStatusEffectiveValue(2, 3) }, + { start: 2000, end: 3000, ups: 4, downs: 5, value: getStatusEffectiveValue(4, 5) }, + ]); + }); +}); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.ts index e5ee43aa04f8d..0a76badc574ab 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/monitor_status_data.ts @@ -114,9 +114,18 @@ export function createTimeBuckets(intervalMinutes: number, from: number, to: num export function createStatusTimeBins( timeBuckets: MonitorStatusTimeBucket[], - heatmapData: MonitorStatusHeatmapBucket[] + heatmapData?: MonitorStatusHeatmapBucket[] ): MonitorStatusTimeBin[] { return timeBuckets.map(({ start, end }) => { + if (!Array.isArray(heatmapData)) { + return { + start, + end, + ups: 0, + downs: 0, + value: 0, + }; + } const { ups, downs } = heatmapData .filter(({ key }) => key >= start && key <= end) .reduce( @@ -163,7 +172,7 @@ export function getBrushData(e: BrushEvent) { return { from, to, fromUtc, toUtc }; } -function getStatusEffectiveValue(ups: number, downs: number): number { +export function getStatusEffectiveValue(ups: number, downs: number): number { if (ups === downs) { return -0.1; } diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/use_monitor_status_data.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/use_monitor_status_data.ts index 59d807cb3bef8..efb001f1776b7 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/use_monitor_status_data.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/monitor_details/monitor_status/use_monitor_status_data.ts @@ -59,7 +59,7 @@ export const useMonitorStatusData = ({ from, to, initialSizeRef }: Props) => { }, [binsAvailableByWidth, initialSizeRef]); useEffect(() => { - if (monitor?.id && location?.label && debouncedBinsCount !== null && minsPerBin !== null) { + if (monitor?.id && location?.label && debouncedBinsCount !== null && !!minsPerBin) { dispatch( quietGetMonitorStatusHeatmapAction.get({ monitorId: monitor.id, diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/status_heatmap/index.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/status_heatmap/index.ts index 29f8a1ba87345..b01b7d0e0b918 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/status_heatmap/index.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/state/status_heatmap/index.ts @@ -18,7 +18,7 @@ import { } from './actions'; export interface MonitorStatusHeatmap { - heatmap: MonitorStatusHeatmapBucket[]; + heatmap?: MonitorStatusHeatmapBucket[]; loading: boolean; error: IHttpSerializedFetchError | null; } From 558c6fd9323fd484a95bda6078a4af913933e041 Mon Sep 17 00:00:00 2001 From: Aleksandr Maus Date: Tue, 17 Sep 2024 08:12:19 -0400 Subject: [PATCH 069/139] Osquery: Update exported fields reference for osquery 5.13.1 (#193095) ## Summary Update exported fields reference for osquery 5.13.1. ## Related PR - Relates https://github.com/elastic/beats/pull/40849 - Relates https://github.com/elastic/integrations/pull/11146 --- docs/osquery/exported-fields-reference.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/osquery/exported-fields-reference.asciidoc b/docs/osquery/exported-fields-reference.asciidoc index 99cb79e874754..4a09e998a1a18 100644 --- a/docs/osquery/exported-fields-reference.asciidoc +++ b/docs/osquery/exported-fields-reference.asciidoc @@ -4578,7 +4578,7 @@ For more information about osquery tables, see the https://osquery.io/schema[osq *process* - keyword, text.text -* _alf_explicit_auths.process_ - Process name explicitly allowed +* _alf_explicit_auths.process_ - Process name that is explicitly allowed * _unified_log.process_ - the name of the process that made the entry *process_being_tapped* - keyword, number.long From 193935cbf25c96ae1e6952f7233f001053e60a59 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Tue, 17 Sep 2024 08:13:54 -0400 Subject: [PATCH 070/139] [Fleet] Require AgentPolicies:All to add a fleet server (#193014) --- x-pack/plugins/fleet/common/authz.ts | 3 +- .../fleet_server_hosts_section.tsx | 2 +- .../server/services/security/security.test.ts | 53 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/common/authz.ts b/x-pack/plugins/fleet/common/authz.ts index 7399eb98a583b..409c5eac01d65 100644 --- a/x-pack/plugins/fleet/common/authz.ts +++ b/x-pack/plugins/fleet/common/authz.ts @@ -117,7 +117,8 @@ export const calculateAuthz = ({ allSettings: fleet.settings?.all ?? false, allAgentPolicies: fleet.agentPolicies?.all ?? false, addAgents: fleet.agents?.all ?? false, - addFleetServers: (fleet.agents?.all && fleet.settings?.all) ?? false, + addFleetServers: + (fleet.agents?.all && fleet.agentPolicies?.all && fleet.settings?.all) ?? false, // Setup is needed to access the Fleet UI setup: hasFleetAll || diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_server_hosts_section.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_server_hosts_section.tsx index 51d1a0f98340e..bae62ce412e35 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_server_hosts_section.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_server_hosts_section.tsx @@ -59,7 +59,7 @@ export const FleetServerHostsSection: React.FunctionComponent - {authz.fleet.allSettings && authz.fleet.allAgents ? ( + {authz.fleet.addFleetServers ? ( <> { expect(res.fleet.readAgents).toBe(false); }); }); + + describe('Fleet addFleetServer', () => { + beforeEach(() => { + mockSecurity.authz.mode.useRbacForRequest.mockReturnValue(true); + }); + it('should authorize user with Fleet:Agents:All Fleet:AgentsPolicies:All Fleet:Settings:All', async () => { + checkPrivileges.mockResolvedValue({ + privileges: { + kibana: [ + { + resource: 'default', + privilege: 'api:fleet-agents-all', + authorized: true, + }, + { + resource: 'default', + privilege: 'api:fleet-agent-policies-all', + authorized: true, + }, + { + resource: 'default', + privilege: 'api:fleet-settings-all', + authorized: true, + }, + ], + elasticsearch: {} as any, + }, + hasAllRequested: true, + username: 'test', + }); + const res = await getAuthzFromRequest({} as any); + expect(res.fleet.addFleetServers).toBe(true); + }); + + it('should not authorize user with only Fleet:Agents:All', async () => { + checkPrivileges.mockResolvedValue({ + privileges: { + kibana: [ + { + resource: 'default', + privilege: 'api:fleet-agents-all', + authorized: true, + }, + ], + elasticsearch: {} as any, + }, + hasAllRequested: true, + username: 'test', + }); + const res = await getAuthzFromRequest({} as any); + expect(res.fleet.addFleetServers).toBe(false); + }); + }); }); From 77fe423f7b621b2ece51ca44544c430256437802 Mon Sep 17 00:00:00 2001 From: Bharat Pasupula <123897612+bhapas@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:28:01 +0200 Subject: [PATCH 071/139] [Automatic Import] Add support for handling unstructured syslog samples (#192817) ## Summary This PR handles the `unstructured` syslog samples in Automatic Import. Examples of unstructured samples would be: ``` <34>Oct 11 00:14:05 mymachine su: 'su root' failed for user on /dev/pts/8 <34>Dec 11 00:14:43 yourmachine su: 'su root' failed for someone on /dev/pts/5 <34>Apr 11 00:14:05 mymachine su: 'su root' failed for otheruser on /dev/pts/3 ``` https://github.com/user-attachments/assets/d1381ac9-4889-42cf-b3c1-d1b7a88def02 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../__jest__/fixtures/unstructured.ts | 25 ++++ .../server/graphs/kv/error.ts | 2 +- .../server/graphs/kv/header.test.ts | 2 +- .../server/graphs/kv/header.ts | 2 +- .../server/graphs/kv/validate.ts | 6 +- .../server/graphs/log_type_detection/graph.ts | 12 +- .../server/graphs/unstructured/constants.ts | 27 +++++ .../server/graphs/unstructured/error.ts | 32 +++++ .../server/graphs/unstructured/errors.test.ts | 40 +++++++ .../server/graphs/unstructured/graph.test.ts | 39 ++++++ .../server/graphs/unstructured/graph.ts | 112 ++++++++++++++++++ .../server/graphs/unstructured/index.ts | 7 ++ .../server/graphs/unstructured/prompts.ts | 105 ++++++++++++++++ .../server/graphs/unstructured/types.ts | 31 +++++ .../graphs/unstructured/unstructured.test.ts | 40 +++++++ .../graphs/unstructured/unstructured.ts | 32 +++++ .../graphs/unstructured/validate.test.ts | 71 +++++++++++ .../server/graphs/unstructured/validate.ts | 41 +++++++ .../server/routes/analyze_logs_routes.ts | 2 +- .../server/templates/processors/grok.yml.njk | 3 +- .../integration_assistant/server/types.ts | 13 ++ .../server/util/processors.ts | 4 +- 22 files changed, 633 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugins/integration_assistant/__jest__/fixtures/unstructured.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/constants.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/error.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/errors.test.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.test.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/index.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/prompts.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/types.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.test.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.test.ts create mode 100644 x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.ts diff --git a/x-pack/plugins/integration_assistant/__jest__/fixtures/unstructured.ts b/x-pack/plugins/integration_assistant/__jest__/fixtures/unstructured.ts new file mode 100644 index 0000000000000..113ef4d37c073 --- /dev/null +++ b/x-pack/plugins/integration_assistant/__jest__/fixtures/unstructured.ts @@ -0,0 +1,25 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const unstructuredLogState = { + lastExecutedChain: 'testchain', + packageName: 'testPackage', + dataStreamName: 'testDatastream', + grokPatterns: ['%{GREEDYDATA:message}'], + logSamples: ['dummy data'], + jsonSamples: ['{"message":"dummy data"}'], + finalized: false, + ecsVersion: 'testVersion', + errors: { test: 'testerror' }, + additionalProcessors: [], +}; + +export const unstructuredLogResponse = { + grok_patterns: [ + '####<%{MONTH} %{MONTHDAY}, %{YEAR} %{TIME} (?:AM|PM) %{WORD:timezone}> <%{WORD:log_level}> <%{WORD:component}> <%{DATA:hostname}> <%{DATA:server_name}> <%{DATA:thread_info}> <%{DATA:user}> <%{DATA:empty_field}> <%{DATA:empty_field2}> <%{NUMBER:timestamp}> <%{DATA:message_id}> <%{GREEDYDATA:message}>', + ], +}; diff --git a/x-pack/plugins/integration_assistant/server/graphs/kv/error.ts b/x-pack/plugins/integration_assistant/server/graphs/kv/error.ts index b6d64ee4f615d..b1b7c12a68d5a 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/kv/error.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/kv/error.ts @@ -33,7 +33,7 @@ export async function handleKVError({ return { kvProcessor, - lastExecutedChain: 'kv_error', + lastExecutedChain: 'kvError', }; } diff --git a/x-pack/plugins/integration_assistant/server/graphs/kv/header.test.ts b/x-pack/plugins/integration_assistant/server/graphs/kv/header.test.ts index 7991484024713..353384361d2da 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/kv/header.test.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/kv/header.test.ts @@ -43,6 +43,6 @@ describe('Testing kv header', () => { expect(response.grokPattern).toStrictEqual( '<%{NUMBER:priority}>%{NUMBER:version} %{GREEDYDATA:message}' ); - expect(response.lastExecutedChain).toBe('kv_header'); + expect(response.lastExecutedChain).toBe('kvHeader'); }); }); diff --git a/x-pack/plugins/integration_assistant/server/graphs/kv/header.ts b/x-pack/plugins/integration_assistant/server/graphs/kv/header.ts index 473eae1516112..36d8968ab9e67 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/kv/header.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/kv/header.ts @@ -26,6 +26,6 @@ export async function handleHeader({ return { grokPattern: pattern.grok_pattern, - lastExecutedChain: 'kv_header', + lastExecutedChain: 'kvHeader', }; } diff --git a/x-pack/plugins/integration_assistant/server/graphs/kv/validate.ts b/x-pack/plugins/integration_assistant/server/graphs/kv/validate.ts index 0bca2ac3fd5e4..b0601de74aa5e 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/kv/validate.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/kv/validate.ts @@ -41,7 +41,7 @@ export async function handleKVValidate({ )) as { pipelineResults: KVResult[]; errors: object[] }; if (errors.length > 0) { - return { errors, lastExecutedChain: 'kv_validate' }; + return { errors, lastExecutedChain: 'kvValidate' }; } // Converts JSON Object into a string and parses it as a array of JSON strings @@ -56,7 +56,7 @@ export async function handleKVValidate({ jsonSamples, additionalProcessors, errors: [], - lastExecutedChain: 'kv_validate', + lastExecutedChain: 'kvValidate', }; } @@ -65,7 +65,7 @@ export async function handleHeaderValidate({ client, }: HandleKVNodeParams): Promise> { const grokPattern = state.grokPattern; - const grokProcessor = createGrokProcessor(grokPattern); + const grokProcessor = createGrokProcessor([grokPattern]); const pipeline = { processors: grokProcessor, on_failure: [onFailure] }; const { pipelineResults, errors } = (await testPipeline(state.logSamples, pipeline, client)) as { diff --git a/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/graph.ts b/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/graph.ts index 5ef894bf64a20..b1cdecd39fe69 100644 --- a/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/graph.ts +++ b/x-pack/plugins/integration_assistant/server/graphs/log_type_detection/graph.ts @@ -14,6 +14,7 @@ import { ESProcessorItem, SamplesFormat } from '../../../common'; import { getKVGraph } from '../kv/graph'; import { LogDetectionGraphParams, LogDetectionBaseNodeParams } from './types'; import { LogFormat } from '../../constants'; +import { getUnstructuredGraph } from '../unstructured/graph'; const graphState: StateGraphArgs['channels'] = { lastExecutedChain: { @@ -90,9 +91,9 @@ function logFormatRouter({ state }: LogDetectionBaseNodeParams): string { if (state.samplesFormat.name === LogFormat.STRUCTURED) { return 'structured'; } - // if (state.samplesFormat === LogFormat.UNSTRUCTURED) { - // return 'unstructured'; - // } + if (state.samplesFormat.name === LogFormat.UNSTRUCTURED) { + return 'unstructured'; + } // if (state.samplesFormat === LogFormat.CSV) { // return 'csv'; // } @@ -109,18 +110,19 @@ export async function getLogFormatDetectionGraph({ model, client }: LogDetection handleLogFormatDetection({ state, model }) ) .addNode('handleKVGraph', await getKVGraph({ model, client })) - // .addNode('handleUnstructuredGraph', (state: LogFormatDetectionState) => getCompiledUnstructuredGraph({state, model})) + .addNode('handleUnstructuredGraph', await getUnstructuredGraph({ model, client })) // .addNode('handleCsvGraph', (state: LogFormatDetectionState) => getCompiledCsvGraph({state, model})) .addEdge(START, 'modelInput') .addEdge('modelInput', 'handleLogFormatDetection') .addEdge('handleKVGraph', 'modelOutput') + .addEdge('handleUnstructuredGraph', 'modelOutput') .addEdge('modelOutput', END) .addConditionalEdges( 'handleLogFormatDetection', (state: LogFormatDetectionState) => logFormatRouter({ state }), { structured: 'handleKVGraph', - // unstructured: 'handleUnstructuredGraph', + unstructured: 'handleUnstructuredGraph', // csv: 'handleCsvGraph', unsupported: 'modelOutput', } diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/constants.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/constants.ts new file mode 100644 index 0000000000000..b0e36de9be85d --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/constants.ts @@ -0,0 +1,27 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const GROK_EXAMPLE_ANSWER = { + rfc: 'RFC2454', + regex: + '/(?:(d{4}[-]d{2}[-]d{2}[T]d{2}[:]d{2}[:]d{2}(?:.d{1,6})?(?:[+-]d{2}[:]d{2}|Z)?)|-)s(?:([w][wd.@-]*)|-)s(.*)$/', + grok_patterns: ['%{WORD:key1}:%{WORD:value1};%{WORD:key2}:%{WORD:value2}:%{GREEDYDATA:message}'], +}; + +export const GROK_ERROR_EXAMPLE_ANSWER = { + grok_patterns: [ + '%{TIMESTAMP:timestamp}:%{WORD:value1};%{WORD:key2}:%{WORD:value2}:%{GREEDYDATA:message}', + ], +}; + +export const onFailure = { + append: { + field: 'error.message', + value: + '{% raw %}Processor {{{_ingest.on_failure_processor_type}}} with tag {{{_ingest.on_failure_processor_tag}}} in pipeline {{{_ingest.on_failure_pipeline}}} failed with message: {{{_ingest.on_failure_message}}}{% endraw %}', + }, +}; diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/error.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/error.ts new file mode 100644 index 0000000000000..d002dd19d5439 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/error.ts @@ -0,0 +1,32 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { JsonOutputParser } from '@langchain/core/output_parsers'; +import type { UnstructuredLogState } from '../../types'; +import type { HandleUnstructuredNodeParams } from './types'; +import { GROK_ERROR_PROMPT } from './prompts'; +import { GROK_ERROR_EXAMPLE_ANSWER } from './constants'; + +export async function handleUnstructuredError({ + state, + model, +}: HandleUnstructuredNodeParams): Promise> { + const outputParser = new JsonOutputParser(); + const grokErrorGraph = GROK_ERROR_PROMPT.pipe(model).pipe(outputParser); + const currentPatterns = state.grokPatterns; + + const pattern = await grokErrorGraph.invoke({ + current_pattern: JSON.stringify(currentPatterns, null, 2), + errors: JSON.stringify(state.errors, null, 2), + ex_answer: JSON.stringify(GROK_ERROR_EXAMPLE_ANSWER, null, 2), + }); + + return { + grokPatterns: pattern.grok_patterns, + lastExecutedChain: 'unstructuredError', + }; +} diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/errors.test.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/errors.test.ts new file mode 100644 index 0000000000000..212b4b6255be2 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/errors.test.ts @@ -0,0 +1,40 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FakeLLM } from '@langchain/core/utils/testing'; +import { handleUnstructuredError } from './error'; +import type { UnstructuredLogState } from '../../types'; +import { + unstructuredLogState, + unstructuredLogResponse, +} from '../../../__jest__/fixtures/unstructured'; +import { + ActionsClientChatOpenAI, + ActionsClientSimpleChatModel, +} from '@kbn/langchain/server/language_models'; +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +const model = new FakeLLM({ + response: JSON.stringify(unstructuredLogResponse, null, 2), +}) as unknown as ActionsClientChatOpenAI | ActionsClientSimpleChatModel; + +const state: UnstructuredLogState = unstructuredLogState; + +describe('Testing unstructured error handling node', () => { + const client = { + asCurrentUser: { + ingest: { + simulate: jest.fn(), + }, + }, + } as unknown as IScopedClusterClient; + it('handleUnstructuredError()', async () => { + const response = await handleUnstructuredError({ state, model, client }); + expect(response.grokPatterns).toStrictEqual(unstructuredLogResponse.grok_patterns); + expect(response.lastExecutedChain).toBe('unstructuredError'); + }); +}); diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.test.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.test.ts new file mode 100644 index 0000000000000..60a9bdc4329de --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.test.ts @@ -0,0 +1,39 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + ActionsClientChatOpenAI, + ActionsClientSimpleChatModel, +} from '@kbn/langchain/server/language_models'; +import { FakeLLM } from '@langchain/core/utils/testing'; +import { getUnstructuredGraph } from './graph'; +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +const model = new FakeLLM({ + response: '{"log_type": "structured"}', +}) as unknown as ActionsClientChatOpenAI | ActionsClientSimpleChatModel; + +describe('UnstructuredGraph', () => { + const client = { + asCurrentUser: { + ingest: { + simulate: jest.fn(), + }, + }, + } as unknown as IScopedClusterClient; + describe('Compiling and Running', () => { + it('Ensures that the graph compiles', async () => { + // When getUnstructuredGraph runs, langgraph compiles the graph it will error if the graph has any issues. + // Common issues for example detecting a node has no next step, or there is a infinite loop between them. + try { + await getUnstructuredGraph({ model, client }); + } catch (error) { + fail(`getUnstructuredGraph threw an error: ${error}`); + } + }); + }); +}); diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.ts new file mode 100644 index 0000000000000..6048404728bfb --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/graph.ts @@ -0,0 +1,112 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { StateGraphArgs } from '@langchain/langgraph'; +import { StateGraph, END, START } from '@langchain/langgraph'; +import type { UnstructuredLogState } from '../../types'; +import { handleUnstructured } from './unstructured'; +import type { UnstructuredGraphParams, UnstructuredBaseNodeParams } from './types'; +import { handleUnstructuredError } from './error'; +import { handleUnstructuredValidate } from './validate'; + +const graphState: StateGraphArgs['channels'] = { + lastExecutedChain: { + value: (x: string, y?: string) => y ?? x, + default: () => '', + }, + packageName: { + value: (x: string, y?: string) => y ?? x, + default: () => '', + }, + dataStreamName: { + value: (x: string, y?: string) => y ?? x, + default: () => '', + }, + logSamples: { + value: (x: string[], y?: string[]) => y ?? x, + default: () => [], + }, + grokPatterns: { + value: (x: string[], y?: string[]) => y ?? x, + default: () => [], + }, + jsonSamples: { + value: (x: string[], y?: string[]) => y ?? x, + default: () => [], + }, + finalized: { + value: (x: boolean, y?: boolean) => y ?? x, + default: () => false, + }, + errors: { + value: (x: object, y?: object) => y ?? x, + default: () => [], + }, + additionalProcessors: { + value: (x: object[], y?: object[]) => y ?? x, + default: () => [], + }, + ecsVersion: { + value: (x: string, y?: string) => y ?? x, + default: () => '', + }, +}; + +function modelInput({ state }: UnstructuredBaseNodeParams): Partial { + return { + finalized: false, + lastExecutedChain: 'modelInput', + }; +} + +function modelOutput({ state }: UnstructuredBaseNodeParams): Partial { + return { + finalized: true, + additionalProcessors: state.additionalProcessors, + lastExecutedChain: 'modelOutput', + }; +} + +function validationRouter({ state }: UnstructuredBaseNodeParams): string { + if (Object.keys(state.errors).length === 0) { + return 'modelOutput'; + } + return 'handleUnstructuredError'; +} + +export async function getUnstructuredGraph({ model, client }: UnstructuredGraphParams) { + const workflow = new StateGraph({ + channels: graphState, + }) + .addNode('modelInput', (state: UnstructuredLogState) => modelInput({ state })) + .addNode('modelOutput', (state: UnstructuredLogState) => modelOutput({ state })) + .addNode('handleUnstructuredError', (state: UnstructuredLogState) => + handleUnstructuredError({ state, model, client }) + ) + .addNode('handleUnstructured', (state: UnstructuredLogState) => + handleUnstructured({ state, model, client }) + ) + .addNode('handleUnstructuredValidate', (state: UnstructuredLogState) => + handleUnstructuredValidate({ state, model, client }) + ) + .addEdge(START, 'modelInput') + .addEdge('modelInput', 'handleUnstructured') + .addEdge('handleUnstructured', 'handleUnstructuredValidate') + .addConditionalEdges( + 'handleUnstructuredValidate', + (state: UnstructuredLogState) => validationRouter({ state }), + { + handleUnstructuredError: 'handleUnstructuredError', + modelOutput: 'modelOutput', + } + ) + .addEdge('handleUnstructuredError', 'handleUnstructuredValidate') + .addEdge('modelOutput', END); + + const compiledUnstructuredGraph = workflow.compile(); + return compiledUnstructuredGraph; +} diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/index.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/index.ts new file mode 100644 index 0000000000000..8fa7bb99744ed --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/index.ts @@ -0,0 +1,7 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +export { getUnstructuredGraph } from './graph'; diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/prompts.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/prompts.ts new file mode 100644 index 0000000000000..5cf5c67135d53 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/prompts.ts @@ -0,0 +1,105 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ChatPromptTemplate } from '@langchain/core/prompts'; + +export const GROK_MAIN_PROMPT = ChatPromptTemplate.fromMessages([ + [ + 'system', + `You are an expert in Syslogs and identifying the headers and structured body in syslog messages. Here is some context for you to reference for your task, read it carefully as you will get questions about it later: + + + {samples} + + `, + ], + [ + 'human', + `Looking at the multiple syslog samples provided in the context, You are tasked with identifying the appropriate regex and Grok pattern for a set of syslog samples. + Your goal is to accurately extract key components such as timestamps, hostnames, priority levels, process names, events, VLAN information, MAC addresses, IP addresses, STP roles, port statuses, messages and more. + + Follow these steps to help improve the grok patterns and apply it step by step: + 1. Familiarize yourself with various syslog message formats. + 2. PRI (Priority Level): Encoded in angle brackets, e.g., <134>, indicating the facility and severity. + 3. Timestamp: Use \`SYSLOGTIMESTAMP\` for RFC 3164 timestamps (e.g., Aug 10 16:34:02). Use \`TIMESTAMP_ISO8601\` for ISO 8601 (RFC 5424) timestamps. For epoch time, use \`NUMBER\`. + 4. If the timestamp could not be categorized into a predefined format, extract the date time fields separately and combine them with the format identified in the grok pattern. + 5. Make sure to identify the timezone component in the timestamp. + 6. Hostname/IP Address: The system or device that generated the message, which could be an IP address or fully qualified domain name + 7. Process Name and PID: Often included with brackets, such as sshd[1234]. + 8. VLAN information: Usually in the format of VLAN: 1234. + 9. MAC Address: The network interface MAC address. + 10. Port number: The port number on the device. + 11. Look for status codes ,interface ,log type, source ,User action, destination, protocol, etc. + 12. message: This is the free-form message text that varies widely across log entries. + + + You ALWAYS follow these guidelines when writing your response: + + - Make sure to map the remaining message part to \'message\' in grok pattern. + - Do not respond with anything except the processor as a JSON object enclosed with 3 backticks (\`), see example response above. Use strict JSON response format. + + + You are required to provide the output in the following example response format: + + + A: Please find the JSON object below: + \`\`\`json + {ex_answer} + \`\`\` + `, + ], + ['ai', 'Please find the JSON object below:'], +]); + +export const GROK_ERROR_PROMPT = ChatPromptTemplate.fromMessages([ + [ + 'system', + `You are an expert in Syslogs and identifying the headers and structured body in syslog messages. Here is some context for you to reference for your task, read it carefully as you will get questions about it later: + + +{current_pattern} + +`, + ], + [ + 'human', + `Please go through each error below, carefully review the provided current grok pattern, and resolve the most likely cause to the supplied error by returning an updated version of the current_pattern. + + +{errors} + + +Follow these steps to help improve the grok patterns and apply it step by step: + 1. Familiarize yourself with various syslog message formats. + 2. PRI (Priority Level): Encoded in angle brackets, e.g., <134>, indicating the facility and severity. + 3. Timestamp: Use \`SYSLOGTIMESTAMP\` for RFC 3164 timestamps (e.g., Aug 10 16:34:02). Use \`TIMESTAMP_ISO8601\` for ISO 8601 (RFC 5424) timestamps. For epoch time, use \`NUMBER\`. + 4. If the timestamp could not be categorized into a predefined format, extract the date time fields separately and combine them with the format identified in the grok pattern. + 5. Make sure to identify the timezone component in the timestamp. + 6. Hostname/IP Address: The system or device that generated the message, which could be an IP address or fully qualified domain name + 7. Process Name and PID: Often included with brackets, such as sshd[1234]. + 8. VLAN information: Usually in the format of VLAN: 1234. + 9. MAC Address: The network interface MAC address. + 10. Port number: The port number on the device. + 11. Look for status codes ,interface ,log type, source ,User action, destination, protocol, etc. + 12. message: This is the free-form message text that varies widely across log entries. + + You ALWAYS follow these guidelines when writing your response: + + - Make sure to map the remaining message part to \'message\' in grok pattern. + - Do not respond with anything except the processor as a JSON object enclosed with 3 backticks (\`), see example response above. Use strict JSON response format. + + + You are required to provide the output in the following example response format: + + + A: Please find the JSON object below: + \`\`\`json + {ex_answer} + \`\`\` + `, + ], + ['ai', 'Please find the JSON object below:'], +]); diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/types.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/types.ts new file mode 100644 index 0000000000000..218d3856cb661 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/types.ts @@ -0,0 +1,31 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; +import type { UnstructuredLogState, ChatModels } from '../../types'; + +export interface UnstructuredBaseNodeParams { + state: UnstructuredLogState; +} + +export interface UnstructuredNodeParams extends UnstructuredBaseNodeParams { + model: ChatModels; +} + +export interface UnstructuredGraphParams { + client: IScopedClusterClient; + model: ChatModels; +} + +export interface HandleUnstructuredNodeParams extends UnstructuredNodeParams { + client: IScopedClusterClient; +} + +export interface GrokResult { + [key: string]: unknown; + grok_patterns: string[]; + message: string; +} diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.test.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.test.ts new file mode 100644 index 0000000000000..11d7107be13c0 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.test.ts @@ -0,0 +1,40 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FakeLLM } from '@langchain/core/utils/testing'; +import { handleUnstructured } from './unstructured'; +import type { UnstructuredLogState } from '../../types'; +import { + unstructuredLogState, + unstructuredLogResponse, +} from '../../../__jest__/fixtures/unstructured'; +import { + ActionsClientChatOpenAI, + ActionsClientSimpleChatModel, +} from '@kbn/langchain/server/language_models'; +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +const model = new FakeLLM({ + response: JSON.stringify(unstructuredLogResponse, null, 2), +}) as unknown as ActionsClientChatOpenAI | ActionsClientSimpleChatModel; + +const state: UnstructuredLogState = unstructuredLogState; + +describe('Testing unstructured log handling node', () => { + const client = { + asCurrentUser: { + ingest: { + simulate: jest.fn(), + }, + }, + } as unknown as IScopedClusterClient; + it('handleUnstructured()', async () => { + const response = await handleUnstructured({ state, model, client }); + expect(response.grokPatterns).toStrictEqual(unstructuredLogResponse.grok_patterns); + expect(response.lastExecutedChain).toBe('handleUnstructured'); + }); +}); diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.ts new file mode 100644 index 0000000000000..42186e796275f --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/unstructured.ts @@ -0,0 +1,32 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { JsonOutputParser } from '@langchain/core/output_parsers'; +import type { UnstructuredLogState } from '../../types'; +import { GROK_MAIN_PROMPT } from './prompts'; +import { GrokResult, HandleUnstructuredNodeParams } from './types'; +import { GROK_EXAMPLE_ANSWER } from './constants'; + +export async function handleUnstructured({ + state, + model, + client, +}: HandleUnstructuredNodeParams): Promise> { + const grokMainGraph = GROK_MAIN_PROMPT.pipe(model).pipe(new JsonOutputParser()); + + // Pick logSamples if there was no header detected. + const samples = state.logSamples; + + const pattern = (await grokMainGraph.invoke({ + samples: samples[0], + ex_answer: JSON.stringify(GROK_EXAMPLE_ANSWER, null, 2), + })) as GrokResult; + + return { + grokPatterns: pattern.grok_patterns, + lastExecutedChain: 'handleUnstructured', + }; +} diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.test.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.test.ts new file mode 100644 index 0000000000000..493834e3220f9 --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.test.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FakeLLM } from '@langchain/core/utils/testing'; +import { handleUnstructuredValidate } from './validate'; +import type { UnstructuredLogState } from '../../types'; +import { + unstructuredLogState, + unstructuredLogResponse, +} from '../../../__jest__/fixtures/unstructured'; +import { + ActionsClientChatOpenAI, + ActionsClientSimpleChatModel, +} from '@kbn/langchain/server/language_models'; +import { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +const model = new FakeLLM({ + response: JSON.stringify(unstructuredLogResponse, null, 2), +}) as unknown as ActionsClientChatOpenAI | ActionsClientSimpleChatModel; + +const state: UnstructuredLogState = unstructuredLogState; + +describe('Testing unstructured validation without errors', () => { + const client = { + asCurrentUser: { + ingest: { + simulate: jest + .fn() + .mockReturnValue({ docs: [{ doc: { _source: { message: 'dummy data' } } }] }), + }, + }, + } as unknown as IScopedClusterClient; + + it('handleUnstructuredValidate() without errors', async () => { + const response = await handleUnstructuredValidate({ state, model, client }); + expect(response.jsonSamples).toStrictEqual(unstructuredLogState.jsonSamples); + expect(response.additionalProcessors).toStrictEqual([ + { + grok: { + field: 'message', + patterns: unstructuredLogState.grokPatterns, + tag: 'grok_header_pattern', + }, + }, + ]); + expect(response.errors).toStrictEqual([]); + expect(response.lastExecutedChain).toBe('unstructuredValidate'); + }); +}); + +describe('Testing unstructured validation errors', () => { + const client = { + asCurrentUser: { + ingest: { + simulate: jest + .fn() + .mockReturnValue({ docs: [{ doc: { _source: { error: 'some error' } } }] }), + }, + }, + } as unknown as IScopedClusterClient; + + it('handleUnstructuredValidate() errors', async () => { + const response = await handleUnstructuredValidate({ state, model, client }); + expect(response.errors).toStrictEqual(['some error']); + expect(response.lastExecutedChain).toBe('unstructuredValidate'); + }); +}); diff --git a/x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.ts b/x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.ts new file mode 100644 index 0000000000000..043e38be0983f --- /dev/null +++ b/x-pack/plugins/integration_assistant/server/graphs/unstructured/validate.ts @@ -0,0 +1,41 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UnstructuredLogState } from '../../types'; +import type { GrokResult, HandleUnstructuredNodeParams } from './types'; +import { testPipeline } from '../../util'; +import { onFailure } from './constants'; +import { createGrokProcessor } from '../../util/processors'; + +export async function handleUnstructuredValidate({ + state, + client, +}: HandleUnstructuredNodeParams): Promise> { + const grokPatterns = state.grokPatterns; + const grokProcessor = createGrokProcessor(grokPatterns); + const pipeline = { processors: grokProcessor, on_failure: [onFailure] }; + + const { pipelineResults, errors } = (await testPipeline(state.logSamples, pipeline, client)) as { + pipelineResults: GrokResult[]; + errors: object[]; + }; + + if (errors.length > 0) { + return { errors, lastExecutedChain: 'unstructuredValidate' }; + } + + const jsonSamples: string[] = pipelineResults.map((entry) => JSON.stringify(entry)); + const additionalProcessors = state.additionalProcessors; + additionalProcessors.push(grokProcessor[0]); + + return { + jsonSamples, + additionalProcessors, + errors: [], + lastExecutedChain: 'unstructuredValidate', + }; +} diff --git a/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts b/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts index c0a81193a465b..29a68c4395a7c 100644 --- a/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts +++ b/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts @@ -81,7 +81,7 @@ export function registerAnalyzeLogsRoutes( const graph = await getLogFormatDetectionGraph({ model, client }); const graphResults = await graph.invoke(logFormatParameters, options); const graphLogFormat = graphResults.results.samplesFormat.name; - if (graphLogFormat === 'unsupported') { + if (graphLogFormat === 'unsupported' || graphLogFormat === 'csv') { return res.customError({ statusCode: 501, body: { message: `Unsupported log samples format` }, diff --git a/x-pack/plugins/integration_assistant/server/templates/processors/grok.yml.njk b/x-pack/plugins/integration_assistant/server/templates/processors/grok.yml.njk index 53ce913df0515..9b0456b134e34 100644 --- a/x-pack/plugins/integration_assistant/server/templates/processors/grok.yml.njk +++ b/x-pack/plugins/integration_assistant/server/templates/processors/grok.yml.njk @@ -1,5 +1,6 @@ - grok: field: message patterns: - - '{{ grokPattern }}' + {% for grokPattern in grokPatterns %} + - '{{ grokPattern }}'{% endfor %} tag: 'grok_header_pattern' diff --git a/x-pack/plugins/integration_assistant/server/types.ts b/x-pack/plugins/integration_assistant/server/types.ts index 0fb68b4e04572..454370a02c366 100644 --- a/x-pack/plugins/integration_assistant/server/types.ts +++ b/x-pack/plugins/integration_assistant/server/types.ts @@ -122,6 +122,19 @@ export interface KVState { ecsVersion: string; } +export interface UnstructuredLogState { + lastExecutedChain: string; + packageName: string; + dataStreamName: string; + grokPatterns: string[]; + logSamples: string[]; + jsonSamples: string[]; + finalized: boolean; + errors: object; + additionalProcessors: object[]; + ecsVersion: string; +} + export interface RelatedState { rawSamples: string[]; samples: string[]; diff --git a/x-pack/plugins/integration_assistant/server/util/processors.ts b/x-pack/plugins/integration_assistant/server/util/processors.ts index 12200f9d32db9..b2e6b1683482a 100644 --- a/x-pack/plugins/integration_assistant/server/util/processors.ts +++ b/x-pack/plugins/integration_assistant/server/util/processors.ts @@ -50,13 +50,13 @@ function createAppendProcessors(processors: SimplifiedProcessors): ESProcessorIt // The kv graph returns a simplified grok processor for header // This function takes in the grok pattern string and creates the grok processor -export function createGrokProcessor(grokPattern: string): ESProcessorItem { +export function createGrokProcessor(grokPatterns: string[]): ESProcessorItem { const templatesPath = joinPath(__dirname, '../templates/processors'); const env = new Environment(new FileSystemLoader(templatesPath), { autoescape: false, }); const template = env.getTemplate('grok.yml.njk'); - const renderedTemplate = template.render({ grokPattern }); + const renderedTemplate = template.render({ grokPatterns }); const grokProcessor = safeLoad(renderedTemplate) as ESProcessorItem; return grokProcessor; } From f4fe0bdaabaf8a8fddfc1d498743bd8a03c557e0 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Tue, 17 Sep 2024 15:25:34 +0200 Subject: [PATCH 072/139] [APM] Attempt to fix APMEventClient unit test (#193049) fixes https://github.com/elastic/kibana/issues/190703 ## Summary The problem seems to be on the `void` keyword used when calling `incomingRequest.abort()`. I ran a few tests changing the `setTimeout` interval with and without using the `void` keyword, and the test always passed when running without it. Co-authored-by: Elastic Machine --- .../create_es_client/create_apm_event_client/index.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability_solution/apm_data_access/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts b/x-pack/plugins/observability_solution/apm_data_access/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts index c2a5676e85c28..2239f6d8d8fb0 100644 --- a/x-pack/plugins/observability_solution/apm_data_access/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts +++ b/x-pack/plugins/observability_solution/apm_data_access/server/lib/helpers/create_es_client/create_apm_event_client/index.test.ts @@ -76,8 +76,9 @@ describe('APMEventClient', () => { resolve(undefined); }, 100); }); + void incomingRequest.abort(); - }, 100); + }, 200); }); expect(abortSignal?.aborted).toBe(true); From ebe4686e6c53a640d8ff2cfc60a7eeceb132812b Mon Sep 17 00:00:00 2001 From: Kerry Gallagher Date: Tue, 17 Sep 2024 14:26:54 +0100 Subject: [PATCH 073/139] [Logs] Remove AI Assistant specific log index setting (#192003) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Closes https://github.com/elastic/logs-dev/issues/167. - Removes registration of the AI Assistant specific advanced setting (`observability:aiAssistantLogsIndexPattern`). - Replaces the setting with use of the central log sources setting (`observability:logSources`). - ℹ️ Also registers the central log sources setting in serverless (this was missed previously). Due to the impact that this setting has on alerts ([Discussion](https://github.com/elastic/logs-dev/issues/170#issuecomment-2229130314)) a migration path from one setting to the other isn't really possible, as values from the AI Assistant setting could potentially cause unwanted alerts. As such these changes opt for the route that we'll do a straight swap, and document this in release notes. We will also need to do a migration on the `config` (for advanced settings) Saved Object to remove instances of the old setting / property. With the new "model version" migration model [my understanding is this should happen in a separate followup PR](https://github.com/elastic/kibana/blob/main/packages/core/saved-objects/core-saved-objects-server/src/model_version/model_change.ts#L131). ⚠️ ~One potentially open question is whether the custom management section that the AI Assistant mounts when clicking "AI Assistant Settings" should render the log sources setting? (As this setting affects more than just the AI Assistant).~ [Resolved](https://github.com/elastic/kibana/pull/192003#issuecomment-2352727034) ![Screenshot 2024-09-05 at 11 53 31](https://github.com/user-attachments/assets/ac3816ca-9021-42f1-9a9c-4c623c6943bb) --------- Co-authored-by: Elastic Machine --- .../settings/setting_ids/index.ts | 2 - .../settings/observability_project/index.ts | 2 +- .../server/collectors/management/schema.ts | 4 - .../server/collectors/management/types.ts | 1 - src/plugins/telemetry/schema/oss_plugins.json | 6 -- .../get_log_categories/index.ts | 9 +- .../get_log_rate_analysis_for_alert/index.ts | 9 +- .../get_container_id_from_signals.ts | 13 +-- .../get_service_name_from_signals.ts | 15 ++- .../index.ts | 10 +- .../settings/indices_configuration_panel.tsx | 6 +- ...a_advanced_setting_configuration_panel.tsx | 98 +++---------------- .../log_sources_service.mocks.ts | 4 + .../services/log_sources_service/types.ts | 1 + .../services/log_sources_service/utils.ts | 11 +++ .../components/logs_sources_setting.tsx | 81 +++++++++++++++ .../public/hooks/use_log_sources.ts | 3 +- .../logs_data_access/public/index.ts | 1 + .../services/log_sources_service/index.ts | 9 +- .../services/log_sources_service/index.ts | 12 ++- .../logs_data_access/tsconfig.json | 4 +- .../common/ui_settings/settings_keys.ts | 4 +- .../observability_ai_assistant/tsconfig.json | 4 + .../kibana.jsonc | 3 +- .../server/functions/changes/index.ts | 8 +- .../server/types.ts | 2 + .../tsconfig.json | 3 +- .../common/ui_settings.ts | 19 ---- .../kibana.jsonc | 2 +- .../settings_tab/settings_tab.test.tsx | 51 +--------- .../components/settings_tab/ui_settings.tsx | 11 ++- .../tsconfig.json | 3 +- .../translations/translations/fr-FR.json | 6 +- .../translations/translations/ja-JP.json | 6 +- .../translations/translations/zh-CN.json | 6 +- .../common/ui/index.ts | 5 +- .../settings_security.spec.ts | 25 ++--- 37 files changed, 215 insertions(+), 244 deletions(-) create mode 100644 x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/utils.ts create mode 100644 x-pack/plugins/observability_solution/logs_data_access/public/components/logs_sources_setting.tsx diff --git a/packages/kbn-management/settings/setting_ids/index.ts b/packages/kbn-management/settings/setting_ids/index.ts index 0f79a5fff0506..611a7a0e13df5 100644 --- a/packages/kbn-management/settings/setting_ids/index.ts +++ b/packages/kbn-management/settings/setting_ids/index.ts @@ -144,8 +144,6 @@ export const OBSERVABILITY_LOGS_EXPLORER_ALLOWED_DATA_VIEWS_ID = 'observability:logsExplorer:allowedDataViews'; export const OBSERVABILITY_ENTITY_CENTRIC_EXPERIENCE = 'observability:entityCentricExperience'; export const OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID = 'observability:logSources'; -export const OBSERVABILITY_AI_ASSISTANT_LOGS_INDEX_PATTERN_ID = - 'observability:aiAssistantLogsIndexPattern'; export const OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING = 'observability:aiAssistantSimulatedFunctionCalling'; export const OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN = diff --git a/packages/serverless/settings/observability_project/index.ts b/packages/serverless/settings/observability_project/index.ts index 85f6327bf0a07..f8bb8dbe12542 100644 --- a/packages/serverless/settings/observability_project/index.ts +++ b/packages/serverless/settings/observability_project/index.ts @@ -34,8 +34,8 @@ export const OBSERVABILITY_PROJECT_SETTINGS = [ settings.OBSERVABILITY_APM_ENABLE_TABLE_SEARCH_BAR, settings.OBSERVABILITY_APM_ENABLE_SERVICE_INVENTORY_TABLE_SEARCH_BAR, settings.OBSERVABILITY_ENTITY_CENTRIC_EXPERIENCE, - settings.OBSERVABILITY_AI_ASSISTANT_LOGS_INDEX_PATTERN_ID, settings.OBSERVABILITY_AI_ASSISTANT_SIMULATED_FUNCTION_CALLING, settings.OBSERVABILITY_AI_ASSISTANT_SEARCH_CONNECTOR_INDEX_PATTERN, + settings.OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID, settings.OBSERVABILITY_SEARCH_EXCLUDED_DATA_TIERS, ]; diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index 52c0df738246a..1c118620773ae 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -484,10 +484,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'integer', _meta: { description: 'Non-default value of setting.' }, }, - 'observability:aiAssistantLogsIndexPattern': { - type: 'keyword', - _meta: { description: 'Non-default value of setting.' }, - }, 'observability:aiAssistantSimulatedFunctionCalling': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 0a0ebe8ebbac6..71c692b6fdf34 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -55,7 +55,6 @@ export interface UsageStats { 'observability:apmEnableServiceInventoryTableSearchBar': boolean; 'observability:logsExplorer:allowedDataViews': string[]; 'observability:logSources': string[]; - 'observability:aiAssistantLogsIndexPattern': string; 'observability:aiAssistantSimulatedFunctionCalling': boolean; 'observability:aiAssistantSearchConnectorIndexPattern': string; 'visualization:heatmap:maxBuckets': number; diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 77e050334803b..ce626c90c2d82 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -10319,12 +10319,6 @@ "description": "Non-default value of setting." } }, - "observability:aiAssistantLogsIndexPattern": { - "type": "keyword", - "_meta": { - "description": "Non-default value of setting." - } - }, "observability:aiAssistantSimulatedFunctionCalling": { "type": "boolean", "_meta": { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts index 41af9a4a0360d..5f36325031ccb 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_categories/index.ts @@ -7,8 +7,7 @@ import datemath from '@elastic/datemath'; import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import type { CoreRequestHandlerContext } from '@kbn/core/server'; -import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/server'; +import { LogSourcesService } from '@kbn/logs-data-access-plugin/common/types'; import { flattenObject, KeyValuePair } from '../../../../common/utils/flatten_object'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { PROCESSOR_EVENT, TRACE_ID } from '../../../../common/es_fields/apm'; @@ -26,12 +25,12 @@ export interface LogCategory { export async function getLogCategories({ apmEventClient, esClient, - coreContext, + logSourcesService, arguments: args, }: { apmEventClient: APMEventClient; esClient: ElasticsearchClient; - coreContext: Pick; + logSourcesService: LogSourcesService; arguments: { start: string; end: string; @@ -53,7 +52,7 @@ export async function getLogCategories({ Object.entries(args.entities).map(([key, value]) => ({ field: key, value })) ); - const index = await coreContext.uiSettings.client.get(aiAssistantLogsIndexPattern); + const index = await logSourcesService.getFlattenedLogSources(); const search = getTypedSearch(esClient); const query = { diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_rate_analysis_for_alert/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_rate_analysis_for_alert/index.ts index 097eff91ced14..2d367780fc9dd 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_rate_analysis_for_alert/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_log_rate_analysis_for_alert/index.ts @@ -6,9 +6,8 @@ */ import { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import type { CoreRequestHandlerContext } from '@kbn/core/server'; -import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/server'; import { fetchLogRateAnalysisForAlert } from '@kbn/aiops-log-rate-analysis/queries/fetch_log_rate_analysis_for_alert'; +import { LogSourcesService } from '@kbn/logs-data-access-plugin/common/types'; import { PROCESSOR_EVENT } from '../../../../common/es_fields/apm'; import { getShouldMatchOrNotExistFilter } from '../utils/get_should_match_or_not_exist_filter'; @@ -17,11 +16,11 @@ import { getShouldMatchOrNotExistFilter } from '../utils/get_should_match_or_not */ export async function getLogRateAnalysisForAlert({ esClient, - coreContext, + logSourcesService, arguments: args, }: { esClient: ElasticsearchClient; - coreContext: Pick; + logSourcesService: LogSourcesService; arguments: { alertStartedAt: string; alertRuleParameterTimeSize?: number; @@ -34,7 +33,7 @@ export async function getLogRateAnalysisForAlert({ }; }; }): ReturnType { - const index = await coreContext.uiSettings.client.get(aiAssistantLogsIndexPattern); + const index = await logSourcesService.getFlattenedLogSources(); const keyValueFilters = getShouldMatchOrNotExistFilter( Object.entries(args.entities).map(([key, value]) => ({ field: key, value })) diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts index 638903e813545..e7f3ace07e2a1 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_container_id_from_signals.ts @@ -7,12 +7,12 @@ import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { CoreRequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; -import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/common'; import { rangeQuery, typedSearch } from '@kbn/observability-plugin/server/utils/queries'; import * as t from 'io-ts'; import moment from 'moment'; import { ESSearchRequest } from '@kbn/es-types'; import { alertDetailsContextRt } from '@kbn/observability-plugin/server/services'; +import { LogSourcesService } from '@kbn/logs-data-access-plugin/common/types'; import { ApmDocumentType } from '../../../../common/document_type'; import { APMEventClient, @@ -23,11 +23,12 @@ import { RollupInterval } from '../../../../common/rollup'; export async function getContainerIdFromSignals({ query, esClient, - coreContext, + logSourcesService, apmEventClient, }: { query: t.TypeOf; esClient: ElasticsearchClient; + logSourcesService: LogSourcesService; coreContext: Pick; apmEventClient: APMEventClient; }) { @@ -66,19 +67,19 @@ export async function getContainerIdFromSignals({ return containerId; } - return getContainerIdFromLogs({ params, esClient, coreContext }); + return getContainerIdFromLogs({ params, esClient, logSourcesService }); } async function getContainerIdFromLogs({ params, esClient, - coreContext, + logSourcesService, }: { params: ESSearchRequest['body']; esClient: ElasticsearchClient; - coreContext: Pick; + logSourcesService: LogSourcesService; }) { - const index = await coreContext.uiSettings.client.get(aiAssistantLogsIndexPattern); + const index = await logSourcesService.getFlattenedLogSources(); const res = await typedSearch<{ container: { id: string } }, any>(esClient, { index, ...params, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts index 284c286766c76..0168431d0ac4e 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/get_service_name_from_signals.ts @@ -6,13 +6,12 @@ */ import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; -import { CoreRequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; -import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/common'; import { rangeQuery, termQuery, typedSearch } from '@kbn/observability-plugin/server/utils/queries'; import * as t from 'io-ts'; import moment from 'moment'; import { ESSearchRequest } from '@kbn/es-types'; import { alertDetailsContextRt } from '@kbn/observability-plugin/server/services'; +import type { LogSourcesService } from '@kbn/logs-data-access-plugin/common/types'; import { ApmDocumentType } from '../../../../common/document_type'; import { APMEventClient, @@ -23,12 +22,12 @@ import { RollupInterval } from '../../../../common/rollup'; export async function getServiceNameFromSignals({ query, esClient, - coreContext, + logSourcesService, apmEventClient, }: { query: t.TypeOf; esClient: ElasticsearchClient; - coreContext: Pick; + logSourcesService: LogSourcesService; apmEventClient: APMEventClient; }) { if (query['service.name']) { @@ -75,19 +74,19 @@ export async function getServiceNameFromSignals({ return serviceName; } - return getServiceNameFromLogs({ params, esClient, coreContext }); + return getServiceNameFromLogs({ params, esClient, logSourcesService }); } async function getServiceNameFromLogs({ params, esClient, - coreContext, + logSourcesService, }: { params: ESSearchRequest['body']; esClient: ElasticsearchClient; - coreContext: Pick; + logSourcesService: LogSourcesService; }) { - const index = await coreContext.uiSettings.client.get(aiAssistantLogsIndexPattern); + const index = await logSourcesService.getFlattenedLogSources(); const res = await typedSearch<{ service: { name: string } }, any>(esClient, { index, ...params, diff --git a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts index e0f3f833a5ae2..84e51675233c9 100644 --- a/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts +++ b/x-pack/plugins/observability_solution/apm/server/routes/assistant_functions/get_observability_alert_details_context/index.ts @@ -87,6 +87,9 @@ export const getAlertDetailsContextHandler = ( }), ]); const esClient = coreContext.elasticsearch.client.asCurrentUser; + const logSourcesService = await ( + await resourcePlugins.logsDataAccess.start() + ).services.logSourcesServiceFactory.getScopedLogSourcesService(requestContext.request); const alertStartedAt = query.alert_started_at; const serviceEnvironment = query['service.environment']; @@ -97,13 +100,14 @@ export const getAlertDetailsContextHandler = ( getServiceNameFromSignals({ query, esClient, - coreContext, + logSourcesService, apmEventClient, }), getContainerIdFromSignals({ query, esClient, coreContext, + logSourcesService, apmEventClient, }), ]); @@ -165,7 +169,7 @@ export const getAlertDetailsContextHandler = ( dataFetchers.push(async () => { const { logRateAnalysisType, significantItems } = await getLogRateAnalysisForAlert({ esClient, - coreContext, + logSourcesService, arguments: { alertStartedAt: moment(alertStartedAt).toISOString(), alertRuleParameterTimeSize: query.alert_rule_parameter_time_size @@ -203,7 +207,7 @@ export const getAlertDetailsContextHandler = ( const { logCategories, entities } = await getLogCategories({ apmEventClient, esClient, - coreContext, + logSourcesService, arguments: { start: moment(alertStartedAt).subtract(15, 'minute').toISOString(), end: alertStartedAt, diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx index 0aad03315c8e1..8f42b4cf1bc6a 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/indices_configuration_panel.tsx @@ -140,11 +140,7 @@ export const IndicesConfigurationPanel = React.memo<{ disabled={isReadOnly} > {isKibanaAdvancedSettingFormElement(indicesFormElement) && ( - + )} diff --git a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/kibana_advanced_setting_configuration_panel.tsx b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/kibana_advanced_setting_configuration_panel.tsx index 49636e4171f2f..a095b2825cd3e 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/kibana_advanced_setting_configuration_panel.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/logs/settings/kibana_advanced_setting_configuration_panel.tsx @@ -5,33 +5,15 @@ * 2.0. */ -import { EuiDescribedFormGroup, EuiFieldText, EuiFormRow } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import React, { useMemo } from 'react'; +import React from 'react'; import { useTrackPageview } from '@kbn/observability-shared-plugin/public'; -import { LogSourcesKibanaAdvancedSettingReference } from '@kbn/logs-shared-plugin/common'; -import { ApplicationStart } from '@kbn/core-application-browser'; -import { EuiLink } from '@elastic/eui'; -import { useLogSourcesContext } from '@kbn/logs-data-access-plugin/public'; +import { + LogSourcesSettingSynchronisationInfo, + useLogSourcesContext, +} from '@kbn/logs-data-access-plugin/public'; import { useKibanaContextForPlugin } from '../../../hooks/use_kibana'; -import { FormElement } from './form_elements'; -import { getFormRowProps } from './form_field_props'; -import { FormValidationError } from './validation_errors'; -function getKibanaAdvancedSettingsHref(application: ApplicationStart) { - return application.getUrlForApp('management', { - path: `/kibana/settings?query=${encodeURIComponent('Log sources')}`, - }); -} - -export const KibanaAdvancedSettingConfigurationPanel: React.FC<{ - isLoading: boolean; - isReadOnly: boolean; - advancedSettingFormElement: FormElement< - LogSourcesKibanaAdvancedSettingReference, - FormValidationError - >; -}> = ({ isLoading, isReadOnly, advancedSettingFormElement }) => { +export const KibanaAdvancedSettingConfigurationPanel: React.FC = () => { const { services: { application }, } = useKibanaContextForPlugin(); @@ -43,71 +25,13 @@ export const KibanaAdvancedSettingConfigurationPanel: React.FC<{ delay: 15000, }); - const advancedSettingsHref = useMemo( - () => getKibanaAdvancedSettingsHref(application), - [application] - ); - const { isLoadingLogSources, combinedIndices } = useLogSourcesContext(); return ( - <> - - - - } - description={ - - - - ), - }} - /> - } - > - - } - label={ - - } - {...getFormRowProps(advancedSettingFormElement)} - > - - - - + ); }; diff --git a/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/log_sources_service.mocks.ts b/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/log_sources_service.mocks.ts index 3f1f8b9db5979..8073adc35d627 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/log_sources_service.mocks.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/log_sources_service.mocks.ts @@ -6,6 +6,7 @@ */ import { LogSource, LogSourcesService } from './types'; +import { flattenLogSources } from './utils'; const LOG_SOURCES: LogSource[] = [{ indexPattern: 'logs-*-*' }]; export const createLogSourcesServiceMock = ( @@ -16,6 +17,9 @@ export const createLogSourcesServiceMock = ( async getLogSources() { return Promise.resolve(sources); }, + async getFlattenedLogSources() { + return Promise.resolve(flattenLogSources(sources)); + }, async setLogSources(nextLogSources: LogSource[]) { sources = nextLogSources; return Promise.resolve(); diff --git a/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/types.ts b/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/types.ts index 0d4cb51051237..a2c1ae825c285 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/types.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/types.ts @@ -11,5 +11,6 @@ export interface LogSource { export interface LogSourcesService { getLogSources: () => Promise; + getFlattenedLogSources: () => Promise; setLogSources: (sources: LogSource[]) => Promise; } diff --git a/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/utils.ts b/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/utils.ts new file mode 100644 index 0000000000000..e6c7faa1c1140 --- /dev/null +++ b/x-pack/plugins/observability_solution/logs_data_access/common/services/log_sources_service/utils.ts @@ -0,0 +1,11 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LogSource } from './types'; + +export const flattenLogSources = (logSources: LogSource[]) => + logSources.map((source) => source.indexPattern).join(','); diff --git a/x-pack/plugins/observability_solution/logs_data_access/public/components/logs_sources_setting.tsx b/x-pack/plugins/observability_solution/logs_data_access/public/components/logs_sources_setting.tsx new file mode 100644 index 0000000000000..0b970ecbb2d25 --- /dev/null +++ b/x-pack/plugins/observability_solution/logs_data_access/public/components/logs_sources_setting.tsx @@ -0,0 +1,81 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { EuiDescribedFormGroup, EuiFieldText, EuiFormRow, EuiLink } from '@elastic/eui'; +import { ApplicationStart } from '@kbn/core-application-browser'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React, { useMemo } from 'react'; + +export const LogSourcesSettingSynchronisationInfo: React.FC<{ + isLoading: boolean; + logSourcesValue: string; + getUrlForApp: ApplicationStart['getUrlForApp']; + title?: string; +}> = ({ isLoading, logSourcesValue, getUrlForApp, title }) => { + const advancedSettingsHref = useMemo( + () => + getUrlForApp('management', { + path: `/kibana/settings?query=${encodeURIComponent('Log sources')}`, + }), + [getUrlForApp] + ); + + return ( + <> + + {title ?? ( + + )} + + } + description={ + + + + ), + }} + /> + } + > + + } + > + + + + + ); +}; diff --git a/x-pack/plugins/observability_solution/logs_data_access/public/hooks/use_log_sources.ts b/x-pack/plugins/observability_solution/logs_data_access/public/hooks/use_log_sources.ts index ff463867a7a77..c69348c4c7275 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/public/hooks/use_log_sources.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/public/hooks/use_log_sources.ts @@ -8,6 +8,7 @@ import createContainer from 'constate'; import { useTrackedPromise } from '@kbn/use-tracked-promise'; import { useState, useEffect, useMemo } from 'react'; +import { flattenLogSources } from '../../common/services/log_sources_service/utils'; import { LogSource, LogSourcesService } from '../../common/services/log_sources_service/types'; export const useLogSources = ({ logSourcesService }: { logSourcesService: LogSourcesService }) => { @@ -35,7 +36,7 @@ export const useLogSources = ({ logSourcesService }: { logSourcesService: LogSou }, [getLogSources]); const combinedIndices = useMemo(() => { - return logSources.map((logSource) => logSource.indexPattern).join(','); + return flattenLogSources(logSources); }, [logSources]); return { diff --git a/x-pack/plugins/observability_solution/logs_data_access/public/index.ts b/x-pack/plugins/observability_solution/logs_data_access/public/index.ts index cc09500ef0a84..ed8facea9b91b 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/public/index.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/public/index.ts @@ -16,6 +16,7 @@ export type { LogsDataAccessPluginSetup, LogsDataAccessPluginStart }; import { LogsDataAccessPluginSetupDeps, LogsDataAccessPluginStartDeps } from './types'; export { LogSourcesProvider, useLogSourcesContext } from './hooks/use_log_sources'; +export { LogSourcesSettingSynchronisationInfo } from './components/logs_sources_setting'; export const plugin: PluginInitializer< LogsDataAccessPluginSetup, diff --git a/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts b/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts index a75bbd65c26e3..f329907f145ef 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/public/services/log_sources_service/index.ts @@ -6,19 +6,24 @@ */ import { OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID } from '@kbn/management-settings-ids'; +import { flattenLogSources } from '../../../common/services/log_sources_service/utils'; import { LogSource, LogSourcesService } from '../../../common/services/log_sources_service/types'; import { RegisterServicesParams } from '../register_services'; export function createLogSourcesService(params: RegisterServicesParams): LogSourcesService { const { uiSettings } = params.deps; return { - getLogSources: async () => { + async getLogSources() { const logSources = uiSettings.get(OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID); return logSources.map((logSource) => ({ indexPattern: logSource, })); }, - setLogSources: async (sources: LogSource[]) => { + async getFlattenedLogSources() { + const logSources = await this.getLogSources(); + return flattenLogSources(logSources); + }, + async setLogSources(sources: LogSource[]) { await uiSettings.set( OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID, sources.map((source) => source.indexPattern) diff --git a/x-pack/plugins/observability_solution/logs_data_access/server/services/log_sources_service/index.ts b/x-pack/plugins/observability_solution/logs_data_access/server/services/log_sources_service/index.ts index e8907d7537932..925deb53524cd 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/server/services/log_sources_service/index.ts +++ b/x-pack/plugins/observability_solution/logs_data_access/server/services/log_sources_service/index.ts @@ -8,6 +8,7 @@ import type { KibanaRequest } from '@kbn/core-http-server'; import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; import { OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID } from '@kbn/management-settings-ids'; +import { flattenLogSources } from '../../../common/services/log_sources_service/utils'; import { LogSource, LogSourcesService } from '../../../common/services/log_sources_service/types'; import { RegisterServicesParams } from '../register_services'; @@ -18,8 +19,8 @@ export function createLogSourcesServiceFactory(params: RegisterServicesParams) { ): Promise { const { uiSettings } = params.deps; const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); - return { - getLogSources: async () => { + const logSourcesService: LogSourcesService = { + async getLogSources() { const logSources = await uiSettingsClient.get( OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID ); @@ -27,13 +28,18 @@ export function createLogSourcesServiceFactory(params: RegisterServicesParams) { indexPattern: logSource, })); }, - setLogSources: async (sources: LogSource[]) => { + async getFlattenedLogSources() { + const logSources = await this.getLogSources(); + return flattenLogSources(logSources); + }, + async setLogSources(sources: LogSource[]) { return await uiSettingsClient.set( OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID, sources.map((source) => source.indexPattern) ); }, }; + return logSourcesService; }, async getScopedLogSourcesService(request: KibanaRequest): Promise { const { savedObjects } = params.deps; diff --git a/x-pack/plugins/observability_solution/logs_data_access/tsconfig.json b/x-pack/plugins/observability_solution/logs_data_access/tsconfig.json index fb2457edd993f..ff67c2f1c8f30 100644 --- a/x-pack/plugins/observability_solution/logs_data_access/tsconfig.json +++ b/x-pack/plugins/observability_solution/logs_data_access/tsconfig.json @@ -22,6 +22,8 @@ "@kbn/logging", "@kbn/core-saved-objects-api-server", "@kbn/es-query", - "@kbn/use-tracked-promise" + "@kbn/use-tracked-promise", + "@kbn/core-application-browser", + "@kbn/i18n-react" ] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts b/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts index eae50d1116a8f..fdcb34f22ecde 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/common/ui_settings/settings_keys.ts @@ -5,8 +5,10 @@ * 2.0. */ +import { OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID } from '@kbn/management-settings-ids'; + // AI Assistant -export const aiAssistantLogsIndexPattern = 'observability:aiAssistantLogsIndexPattern'; +export const aiAssistantLogsIndexPattern = OBSERVABILITY_LOGS_DATA_ACCESS_LOG_SOURCES_ID; export const aiAssistantSimulatedFunctionCalling = 'observability:aiAssistantSimulatedFunctionCalling'; export const aiAssistantSearchConnectorIndexPattern = diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json index aeb103e041cae..d9c747731073b 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant/tsconfig.json @@ -42,6 +42,10 @@ "@kbn/features-plugin", "@kbn/cloud-plugin", "@kbn/serverless", + "@kbn/core-elasticsearch-server", + "@kbn/core-ui-settings-server", + "@kbn/inference-plugin", + "@kbn/management-settings-ids" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc index 1e02cbd1e7792..1414912d39164 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/kibana.jsonc @@ -24,7 +24,8 @@ "ml", "alerting", "features", - "inference" + "inference", + "logsDataAccess" ], "requiredBundles": ["kibanaReact", "esqlDataGrid"], "optionalPlugins": ["cloud"], diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts index 987414214a17b..dc0e26ea9c777 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/functions/changes/index.ts @@ -7,7 +7,6 @@ import { omit, orderBy } from 'lodash'; import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; import type { AggregationsAutoDateHistogramAggregation } from '@elastic/elasticsearch/lib/api/types'; -import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/server'; import { createElasticsearchClient } from '../../clients/elasticsearch'; import type { FunctionRegistrationParameters } from '..'; import { @@ -25,6 +24,7 @@ export function registerChangesFunction({ logger, context: { core: corePromise }, }, + pluginsStart, }: FunctionRegistrationParameters) { functions.registerFunction( { @@ -41,7 +41,11 @@ export function registerChangesFunction({ const core = await corePromise; - const logsIndexPattern = await core.uiSettings.client.get(aiAssistantLogsIndexPattern); + const logSourcesService = + await pluginsStart.logsDataAccess.services.logSourcesServiceFactory.getLogSourcesService( + core.savedObjects.client + ); + const logsIndexPattern = await logSourcesService.getFlattenedLogSources(); const client = createElasticsearchClient({ client: core.elasticsearch.client.asCurrentUser, diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts index 320459d203f9e..fc39e0b7fb24e 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/server/types.ts @@ -36,6 +36,7 @@ import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; import type { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; import type { InferenceServerStart, InferenceServerSetup } from '@kbn/inference-plugin/server'; +import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/server'; // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface ObservabilityAIAssistantAppServerStart {} @@ -55,6 +56,7 @@ export interface ObservabilityAIAssistantAppPluginStartDependencies { cloud?: CloudStart; serverless?: ServerlessPluginStart; inference: InferenceServerStart; + logsDataAccess: LogsDataAccessPluginStart; } export interface ObservabilityAIAssistantAppPluginSetupDependencies { diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json index 55d965c9c37e3..84fe8f0b93911 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_app/tsconfig.json @@ -72,7 +72,8 @@ "@kbn/esql-datagrid", "@kbn/alerting-comparators", "@kbn/core-lifecycle-browser", - "@kbn/inference-plugin" + "@kbn/inference-plugin", + "@kbn/logs-data-access-plugin" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts b/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts index f972eb5742a91..3319860de6610 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/common/ui_settings.ts @@ -9,30 +9,11 @@ import { schema } from '@kbn/config-schema'; import { UiSettingsParams } from '@kbn/core-ui-settings-common'; import { i18n } from '@kbn/i18n'; import { - aiAssistantLogsIndexPattern, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, } from '@kbn/observability-ai-assistant-plugin/common'; export const uiSettings: Record = { - [aiAssistantLogsIndexPattern]: { - category: ['observability'], - name: i18n.translate( - 'xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel', - { defaultMessage: 'Logs index pattern' } - ), - value: 'logs-*', - description: i18n.translate( - 'xpack.observabilityAiAssistantManagement.settingsPage.logIndexPatternDescription', - { - defaultMessage: - 'Index pattern used by the AI Assistant when querying for logs. Logs are categorised and used for root cause analysis', - } - ), - schema: schema.string(), - type: 'string', - requiresPageReload: true, - }, [aiAssistantSimulatedFunctionCalling]: { category: ['observability'], name: i18n.translate( diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/kibana.jsonc b/x-pack/plugins/observability_solution/observability_ai_assistant_management/kibana.jsonc index 03d217d84e94f..ddf00c84c0ac3 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/kibana.jsonc +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/kibana.jsonc @@ -9,6 +9,6 @@ "configPath": ["xpack", "observabilityAiAssistantManagement"], "requiredPlugins": ["management", "observabilityAIAssistant", "observabilityShared"], "optionalPlugins": ["actions", "home", "serverless", "enterpriseSearch"], - "requiredBundles": ["kibanaReact"] + "requiredBundles": ["kibanaReact", "logsDataAccess"] } } diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx index 807bde0557d8d..2bed5aed37160 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/settings_tab.test.tsx @@ -6,11 +6,9 @@ */ import React from 'react'; -import { fireEvent, waitFor } from '@testing-library/react'; +import { fireEvent } from '@testing-library/react'; import { render } from '../../../helpers/test_helper'; import { SettingsTab } from './settings_tab'; -import { aiAssistantLogsIndexPattern } from '@kbn/observability-ai-assistant-plugin/server'; -import { uiSettings } from '../../../../common/ui_settings'; jest.mock('../../../hooks/use_app_context'); @@ -42,51 +40,4 @@ describe('SettingsTab', () => { path: '/insightsAndAlerting/triggersActionsConnectors/connectors', }); }); - - describe('allows updating the AI Assistant settings', () => { - const windowLocationReloadMock = jest.fn(); - const windowLocationOriginal = window.location; - const settingsClientSet = jest.fn(); - - beforeEach(async () => { - Object.defineProperty(window, 'location', { - value: { - reload: windowLocationReloadMock, - }, - writable: true, - }); - - const { getByTestId, container } = render(, { - coreStart: { - settings: { - client: { - set: settingsClientSet, - getAll: () => uiSettings, - }, - }, - }, - }); - - await waitFor(() => expect(container.querySelector('.euiLoadingSpinner')).toBeNull()); - - fireEvent.input(getByTestId(`management-settings-editField-${aiAssistantLogsIndexPattern}`), { - target: { value: 'observability-ai-assistant-*' }, - }); - - fireEvent.click(getByTestId('observabilityAiAssistantManagementBottomBarActionsButton')); - - await waitFor(() => expect(windowLocationReloadMock).toHaveBeenCalledTimes(1)); - }); - - afterEach(() => { - window.location = windowLocationOriginal; - }); - - it('calls the settings client with correct args', async () => { - expect(settingsClientSet).toBeCalledWith( - aiAssistantLogsIndexPattern, - 'observability-ai-assistant-*' - ); - }); - }); }); diff --git a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx index 5be8456954d64..a8c20a641f042 100644 --- a/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx +++ b/x-pack/plugins/observability_solution/observability_ai_assistant_management/public/routes/components/settings_tab/ui_settings.tsx @@ -17,10 +17,10 @@ import { FieldRow, FieldRowProvider } from '@kbn/management-settings-components- import { EuiSpacer } from '@elastic/eui'; import { isEmpty } from 'lodash'; import { i18n } from '@kbn/i18n'; +import { LogSourcesSettingSynchronisationInfo } from '@kbn/logs-data-access-plugin/public'; import { useKibana } from '../../../hooks/use_kibana'; const settingsKeys = [ - aiAssistantLogsIndexPattern, aiAssistantSimulatedFunctionCalling, aiAssistantSearchConnectorIndexPattern, aiAssistantPreferredAIAssistantType, @@ -31,7 +31,7 @@ export function UISettings() { docLinks, settings, notifications, - application: { capabilities }, + application: { capabilities, getUrlForApp }, } = useKibana().services; const { fields, handleFieldChange, unsavedChanges, saveAll, isSaving, cleanUnsavedChanges } = @@ -84,6 +84,13 @@ export function UISettings() { ); })} + + + {!isEmpty(unsavedChanges) && ( > Fonctionnalités.", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingDescription": "[version d'évaluation technique] Utilisez l'appel de fonction simulé. L’appel de fonction simulé ne nécessite pas la prise en charge de l'API pour les fonctions ou les outils, mais il peut réduire les performances. L'appel de fonction simulé est actuellement toujours activé pour les connecteurs non-OpenAI, indépendamment de ce paramètre.", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingLabel": "Simuler un appel de fonction", - "xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel": "Modèle d'indexation des logs", "xpack.observabilityAiAssistantManagement.settingsTab.h3.searchConnectorIndexPatternLabel": "Modèle d'indexation de connecteur de recherche", "xpack.observabilityAiAssistantManagement.span.expandRowLabel": "Développer la ligne", "xpack.observabilityLogsExplorer.alertsPopover.buttonLabel": "Alertes", @@ -47895,4 +47893,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "Ce champ est requis.", "xpack.watcher.watcherDescription": "Détectez les modifications survenant dans vos données en créant, gérant et monitorant des alertes." } -} \ No newline at end of file +} diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 9280f3b99b867..f2237c38b3275 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -766,8 +766,8 @@ "core.euiDataGridCell.focusTrapEnterPrompt": "このセルの内容を操作するには、Enterキーを押してください。", "core.euiDataGridCell.position": "{columnId}, 列{col}, 行{row}", "core.euiDataGridCellActions.expandButtonTitle": "クリックするか enter を押すと、セルのコンテンツとインタラクトできます。", - "core.euiDataGridHeaderCell.actionsPopoverScreenReaderText": "列アクションのリストを移動するには、Tabまたは上下矢印キーを押します。", "core.euiDataGridHeaderCell.actionsButtonAriaLabel": "{title}。クリックすると、列ヘッダーアクションが表示されます", + "core.euiDataGridHeaderCell.actionsPopoverScreenReaderText": "列アクションのリストを移動するには、Tabまたは上下矢印キーを押します。", "core.euiDataGridHeaderCell.sortedByAscendingFirst": "{columnId}の昇順で並べ替え", "core.euiDataGridHeaderCell.sortedByAscendingMultiple": "、{columnId}の昇順で並べ替え", "core.euiDataGridHeaderCell.sortedByAscendingSingle": "昇順で並べ替えます", @@ -32954,7 +32954,6 @@ "xpack.observabilityAiAssistantManagement.settingsPage.goToFeatureControlsButtonLabel": "スペースに移動", "xpack.observabilityAiAssistantManagement.settingsPage.h2.settingsLabel": "設定", "xpack.observabilityAiAssistantManagement.settingsPage.knowledgeBaseLabel": "ナレッジベース", - "xpack.observabilityAiAssistantManagement.settingsPage.logIndexPatternDescription": "ログのクエリを実行するときにAI Assistantによって使用されるインデックスパターン。ログは分類され、根本原因分析で使用されます。", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnector": "検索コネクター", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnectorIndexPatternDescription": "検索コネクターインデックス(ナレッジベースの一部)をクエリするときに、AI Assistantによって使用されるインデックスパターン。デフォルトでは、すべての検索コネクターのインデックスに対してクエリが実行されます。", "xpack.observabilityAiAssistantManagement.settingsPage.settingsLabel": "設定", @@ -32962,7 +32961,6 @@ "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantDescriptionLabel": "オブザーバビリティアプリでAI Assistantボタンと状況に応じたインサイトのオン/オフを切り替えるには、[スペース]>[]>[機能]でAI Assistant機能のチェックをオンまたはオフにします。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingDescription": "[technical preview] シミュレートされた関数呼び出しを使用します。シミュレートされた関数呼び出しでは、関数またはツールのAPIサポートは必要ありませんが、パフォーマンスが低下する可能性があります。現在、シミュレートされた関数呼び出しは、この設定に関係なく、非OpenAIコネクターで常に有効です。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingLabel": "関数呼び出しをシミュレート", - "xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel": "ログインデックスパターン", "xpack.observabilityAiAssistantManagement.settingsTab.h3.searchConnectorIndexPatternLabel": "検索コネクターインデックスパターン", "xpack.observabilityAiAssistantManagement.span.expandRowLabel": "行を展開", "xpack.observabilityLogsExplorer.alertsPopover.buttonLabel": "アラート", @@ -47878,4 +47876,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。", "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 08826a2d5775e..c57a42b464836 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -764,8 +764,8 @@ "core.euiDataGridCell.focusTrapEnterPrompt": "按 Enter 键与此单元格的内容进行交互。", "core.euiDataGridCell.position": "{columnId},列 {col},行 {row}", "core.euiDataGridCellActions.expandButtonTitle": "单击或按 Enter 键以便与单元格内容进行交互", - "core.euiDataGridHeaderCell.actionsPopoverScreenReaderText": "要在列操作列表中导航,请按 Tab 键或向上和向下箭头键。", "core.euiDataGridHeaderCell.actionsButtonAriaLabel": "{title}。单击以查看列标题操作", + "core.euiDataGridHeaderCell.actionsPopoverScreenReaderText": "要在列操作列表中导航,请按 Tab 键或向上和向下箭头键。", "core.euiDataGridHeaderCell.sortedByAscendingFirst": "按 {columnId} 排序,升序", "core.euiDataGridHeaderCell.sortedByAscendingMultiple": ",然后按 {columnId} 排序,升序", "core.euiDataGridHeaderCell.sortedByAscendingSingle": "已升序", @@ -32994,7 +32994,6 @@ "xpack.observabilityAiAssistantManagement.settingsPage.goToFeatureControlsButtonLabel": "前往工作区", "xpack.observabilityAiAssistantManagement.settingsPage.h2.settingsLabel": "设置", "xpack.observabilityAiAssistantManagement.settingsPage.knowledgeBaseLabel": "知识库", - "xpack.observabilityAiAssistantManagement.settingsPage.logIndexPatternDescription": "AI 助手查询日志时使用的索引模式。日志将进行归类并用于根本原因分析", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnector": "搜索连接器", "xpack.observabilityAiAssistantManagement.settingsPage.searchConnectorIndexPatternDescription": "查询搜索连接器索引(知识库的一部分)时 AI 助手使用的索引模式。默认情况下,将查询每个搜索连接器的索引", "xpack.observabilityAiAssistantManagement.settingsPage.settingsLabel": "设置", @@ -33002,7 +33001,6 @@ "xpack.observabilityAiAssistantManagement.settingsPage.showAIAssistantDescriptionLabel": "通过在“工作区 > > 功能”中选中或取消选中 AI 助手功能,在 Observability 应用中打开或关闭 AI 助手按钮和上下文洞察。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingDescription": "[技术预览] 使用模拟函数调用。模拟函数调用不需要函数或工具的 API 支持,但可能会降低性能。无论此设置如何,当前会始终对非 OpenAI 连接器启用模拟函数调用。", "xpack.observabilityAiAssistantManagement.settingsPage.simulatedFunctionCallingLabel": "模拟函数调用", - "xpack.observabilityAiAssistantManagement.settingsTab.h3.logIndexPatternLabel": "日志索引模式", "xpack.observabilityAiAssistantManagement.settingsTab.h3.searchConnectorIndexPatternLabel": "搜索连接器索引模式", "xpack.observabilityAiAssistantManagement.span.expandRowLabel": "展开行", "xpack.observabilityLogsExplorer.alertsPopover.buttonLabel": "告警", @@ -47929,4 +47927,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。", "xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。" } -} \ No newline at end of file +} diff --git a/x-pack/test/observability_ai_assistant_functional/common/ui/index.ts b/x-pack/test/observability_ai_assistant_functional/common/ui/index.ts index a5d2802dfbcc5..2c6852988cde5 100644 --- a/x-pack/test/observability_ai_assistant_functional/common/ui/index.ts +++ b/x-pack/test/observability_ai_assistant_functional/common/ui/index.ts @@ -57,8 +57,9 @@ const pages = { settings: { settingsPage: 'aiAssistantSettingsPage', managementLink: 'aiAssistantManagementSelection', - logsIndexPatternInput: - 'management-settings-editField-observability:aiAssistantLogsIndexPattern', + logsIndexPatternInput: 'management-settings-editField-observability:logSources', + searchConnectorIndexPatternInput: + 'management-settings-editField-observability:aiAssistantSearchConnectorIndexPattern', saveButton: 'observabilityAiAssistantManagementBottomBarActionsButton', aiAssistantCard: 'aiAssistantSelectionPageObservabilityCard', }, diff --git a/x-pack/test/observability_ai_assistant_functional/tests/feature_controls/settings_security.spec.ts b/x-pack/test/observability_ai_assistant_functional/tests/feature_controls/settings_security.spec.ts index ef87707c62a2c..96f2ff4b00f7f 100644 --- a/x-pack/test/observability_ai_assistant_functional/tests/feature_controls/settings_security.spec.ts +++ b/x-pack/test/observability_ai_assistant_functional/tests/feature_controls/settings_security.spec.ts @@ -58,20 +58,21 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.existOrFail(ui.pages.settings.settingsPage); }); it('allows updating of an advanced setting', async () => { - const testLogsIndexPattern = 'my-logs-index-pattern'; - const logsIndexPatternInput = await testSubjects.find( - ui.pages.settings.logsIndexPatternInput + const testSearchConnectorIndexPattern = 'my-logs-index-pattern'; + const searchConnectorIndexPatternInput = await testSubjects.find( + ui.pages.settings.searchConnectorIndexPatternInput ); - await logsIndexPatternInput.clearValue(); - await logsIndexPatternInput.type(testLogsIndexPattern); + await searchConnectorIndexPatternInput.clearValue(); + await searchConnectorIndexPatternInput.type(testSearchConnectorIndexPattern); const saveButton = await testSubjects.find(ui.pages.settings.saveButton); await saveButton.click(); await browser.refresh(); - const logsIndexPatternInputValue = await logsIndexPatternInput.getAttribute('value'); - expect(logsIndexPatternInputValue).to.be(testLogsIndexPattern); + const searchConnectorIndexPatternInputValue = + await searchConnectorIndexPatternInput.getAttribute('value'); + expect(searchConnectorIndexPatternInputValue).to.be(testSearchConnectorIndexPattern); // reset the value - await logsIndexPatternInput.clearValue(); - await logsIndexPatternInput.type('logs-*'); + await searchConnectorIndexPatternInput.clearValue(); + await searchConnectorIndexPatternInput.type('logs-*'); await saveButton.click(); }); }); @@ -114,10 +115,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.existOrFail(ui.pages.settings.settingsPage); }); it('has disabled inputs', async () => { - const logsIndexPatternInput = await testSubjects.find( - ui.pages.settings.logsIndexPatternInput + const searchConnectorIndexPatternInput = await testSubjects.find( + ui.pages.settings.searchConnectorIndexPatternInput ); - expect(await logsIndexPatternInput.getAttribute('disabled')).to.be('true'); + expect(await searchConnectorIndexPatternInput.getAttribute('disabled')).to.be('true'); }); }); describe('observabilityAIAssistant privilege with no aiAssistantManagementSelection privilege', () => { From b3a1e5fb8f3bd6a05943ca3646186a0e3567cfe9 Mon Sep 17 00:00:00 2001 From: Ignacio Rivas Date: Tue, 17 Sep 2024 16:35:20 +0300 Subject: [PATCH 074/139] [Console] UX Improvements for phase 2 (#190698) --- .buildkite/ftr_platform_stateful_configs.yml | 3 +- packages/kbn-monaco/index.ts | 1 + packages/kbn-monaco/src/console/index.ts | 2 + .../kbn-monaco/src/console/output_parser.js | 401 +++++++++ .../src/console/output_parser.test.ts | 40 + packages/kbn-monaco/src/console/types.ts | 10 + .../constants/autocomplete_definitions.ts | 2 + src/plugins/console/common/constants/index.ts | 1 + .../application/components/console_menu.tsx | 16 +- .../components/console_tour_step.tsx | 64 ++ .../components/editor_content_spinner.tsx | 6 +- .../application/components/editor_example.tsx | 91 -- .../application/components/help_panel.tsx | 163 ---- .../application/components/help_popover.tsx | 136 +++ .../public/application/components/index.ts | 46 +- .../components/output_panel_empty_state.tsx | 57 ++ .../application/components/settings/index.ts | 31 + .../components/settings/settings_editor.tsx | 371 ++++++++ .../components/settings/settings_form_row.tsx | 33 + .../components/settings/settings_group.tsx | 37 + .../index.ts => components/settings/types.ts} | 3 +- .../application/components/settings_modal.tsx | 391 -------- .../shortcuts_popover}/index.ts | 3 +- .../components/shortcuts_popover/keys.tsx | 69 ++ .../shortcuts_popover/shortcut_line.tsx | 65 ++ .../shortcuts_popover/shortcuts_popover.tsx | 114 +++ .../application/components/top_nav_menu.tsx | 21 +- .../application/components/variables/index.ts | 24 +- .../application/components/variables/types.ts | 14 + .../application/components/variables/utils.ts | 30 +- .../components/variables/variables_editor.tsx | 255 ++++++ .../variables/variables_editor_form.tsx | 184 ++++ .../components/variables/variables_flyout.tsx | 215 ----- .../application/components/welcome_panel.tsx | 167 ---- .../application/containers/config/config.tsx | 47 + .../{editor/utilities => config}/index.ts | 2 +- .../containers/{ => config}/settings.tsx | 19 +- .../containers/{ => config}/variables.tsx | 19 +- .../console_history/console_history.tsx | 242 ----- .../console_history/history_viewer.tsx | 61 -- .../components/context_menu/context_menu.tsx | 36 +- .../components/context_menu/index.ts | 0 .../context_menu/language_selector_modal.tsx | 2 +- .../editor/{monaco => }/components/index.ts | 0 .../application/containers/editor/editor.tsx | 350 ++++++-- .../editor/{monaco => }/hooks/index.ts | 0 .../hooks/use_register_keyboard_commands.ts | 0 .../hooks/use_resize_checker_utils.ts | 0 .../hooks/use_set_initial_value.ts | 12 +- .../hooks/use_setup_autocomplete_polling.ts | 2 +- .../{monaco => }/hooks/use_setup_autosave.ts | 2 +- .../application/containers/editor/index.ts | 1 - .../console_editor/apply_editor_settings.ts | 27 - .../console_editor/editor.test.mock.tsx | 50 -- .../legacy/console_editor/editor.test.tsx | 100 --- .../editor/legacy/console_editor/editor.tsx | 343 ------- .../legacy/console_editor/editor_output.tsx | 125 --- .../console_editor/keyboard_shortcuts.ts | 92 -- .../editor/legacy/console_menu_actions.ts | 39 - .../containers/editor/legacy/index.ts | 11 - .../subscribe_console_resize_checker.ts | 28 - .../containers/editor/monaco/index.ts | 11 - .../editor/{monaco => }/monaco_editor.tsx | 63 +- .../monaco_editor_actions_provider.test.ts | 4 +- .../monaco_editor_actions_provider.ts | 123 ++- .../{monaco => }/monaco_editor_output.tsx | 88 +- .../monaco_editor_output_actions_provider.ts | 185 ++++ .../monaco_editor_suggestion_provider.ts | 0 .../containers/editor/{monaco => }/types.ts | 0 .../utils/autocomplete_utils.test.ts | 4 +- .../{monaco => }/utils/autocomplete_utils.ts | 6 +- .../editor/{monaco => }/utils/constants.ts | 0 .../editor/{monaco => }/utils/index.ts | 7 + ...convert_mapbox_vector_tile_to_json.test.ts | 0 .../convert_mapbox_vector_tile_to_json.ts | 0 .../mapbox_vector_tile/index.ts | 0 .../mapbox_vector_tile/response.pbf | Bin .../{utilities => utils}/output_data.ts | 0 .../{monaco => }/utils/requests_utils.test.ts | 2 +- .../{monaco => }/utils/requests_utils.ts | 6 +- .../status_code_decoration_utils.test.ts | 2 +- .../utils/status_code_decoration_utils.ts | 2 +- .../{monaco => }/utils/tokens_utils.test.ts | 0 .../editor/{monaco => }/utils/tokens_utils.ts | 0 .../containers/embeddable/console_wrapper.tsx | 5 +- .../embeddable/embeddable_console.tsx | 2 - .../containers/history/history.tsx | 306 +++++++ .../containers/history/history_empty.tsx | 61 ++ .../history_viewer_monaco.tsx | 5 +- .../{console_history => history}/index.ts | 2 +- .../public/application/containers/index.ts | 1 - .../application/containers/main/constants.ts | 30 + .../main/get_console_tour_step_props.tsx | 82 ++ .../containers/main/get_top_nav.ts | 82 +- .../containers/main/get_tour_steps.tsx | 122 +++ .../application/containers/main/i18n.ts | 43 + .../containers/main/import_confirm_modal.tsx | 67 ++ .../application/containers/main/index.ts | 1 + .../application/containers/main/main.tsx | 387 ++++++-- .../containers/main/nav_icon_button.tsx | 38 + .../__snapshots__/split_panel.test.tsx.snap | 101 --- .../containers/split_panel/panel.tsx | 47 - .../split_panel/panel_container.tsx | 140 --- .../containers/split_panel/resizer.tsx | 35 - .../split_panel/split_panel.test.tsx | 74 -- .../editor_context/editor_registry.ts | 2 +- .../public/application/contexts/index.ts | 2 - .../contexts/services_context.mock.ts | 3 +- .../application/contexts/services_context.tsx | 3 +- .../application/contexts/split_panel/index.ts | 11 - .../split_panel/split_panel_context.tsx | 30 - .../restore_request_from_history_to_monaco.ts | 2 +- .../use_restore_request_from_history.ts | 21 +- .../use_send_current_request/send_request.ts | 5 +- .../application/hooks/use_set_input_editor.ts | 2 +- .../console/public/application/index.tsx | 35 +- .../format_request.ts} | 22 +- .../console/public/application/lib/index.ts | 1 + .../public/application/stores/editor.ts | 38 +- .../public/application/stores/request.ts | 7 + .../console/public/lib/autocomplete/types.ts | 2 +- .../lib/autocomplete_entities/data_stream.ts | 11 +- src/plugins/console/public/plugin.ts | 9 +- src/plugins/console/public/services/api.ts | 2 +- .../console/public/services/autocomplete.ts | 12 + .../console/public/services/storage.ts | 2 +- src/plugins/console/public/shared_imports.ts | 13 + src/plugins/console/public/styles/_app.scss | 91 +- src/plugins/console/public/types/common.ts | 10 + src/plugins/console/public/types/config.ts | 3 - .../public/types/embeddable_console.ts | 1 - src/plugins/console/server/config.ts | 2 - .../services/spec_definitions_service.test.ts | 1 + .../services/spec_definitions_service.ts | 13 +- src/plugins/console/tsconfig.json | 6 +- src/plugins/dev_tools/public/application.tsx | 9 +- src/plugins/dev_tools/public/dev_tool.ts | 1 + test/accessibility/apps/console.ts | 2 +- .../apps/console/{ace => }/_autocomplete.ts | 156 ++-- .../apps/console/{monaco => }/_comments.ts | 16 +- .../apps/console/{monaco => }/_console.ts | 124 ++- .../apps/console/{monaco => }/_console_ccs.ts | 12 +- .../console/{monaco => }/_context_menu.ts | 32 +- .../apps/console/_misc_console_behavior.ts | 262 ++++++ .../apps/console/_onboarding_tour.ts | 107 +++ test/functional/apps/console/_output_panel.ts | 85 ++ .../apps/console/{ace => }/_settings.ts | 18 +- .../apps/console/{monaco => }/_text_input.ts | 55 +- .../apps/console/{monaco => }/_variables.ts | 32 +- .../apps/console/{ace => }/_vector_tile.ts | 8 +- .../apps/console/{monaco => }/_xjson.ts | 54 +- test/functional/apps/console/ace/_comments.ts | 232 ----- test/functional/apps/console/ace/_console.ts | 210 ----- .../apps/console/ace/_console_ccs.ts | 52 -- .../apps/console/ace/_context_menu.ts | 104 --- .../console/ace/_misc_console_behavior.ts | 142 --- .../apps/console/ace/_text_input.ts | 102 --- .../functional/apps/console/ace/_variables.ts | 75 -- test/functional/apps/console/ace/_xjson.ts | 189 ---- test/functional/apps/console/ace/config.ts | 28 - .../apps/console/{monaco => }/config.ts | 4 +- .../apps/console/{ace => }/index.ts | 4 +- .../apps/console/monaco/_autocomplete.ts | 386 -------- .../console/monaco/_misc_console_behavior.ts | 183 ---- .../apps/console/monaco/_settings.ts | 42 - .../apps/console/monaco/_vector_tile.ts | 52 -- test/functional/apps/console/monaco/index.ts | 35 - .../controls/common/config.ts | 5 - .../controls/common/control_group_chaining.ts | 13 +- .../controls/options_list/config.ts | 5 - ...ptions_list_allow_expensive_queries_off.ts | 5 +- .../options_list_dashboard_interaction.ts | 12 +- test/functional/config.ccs.ts | 2 +- test/functional/firefox/console.config.ts | 2 +- test/functional/page_objects/console_page.ts | 837 ++++++------------ .../page_objects/embedded_console.ts | 3 + .../test_suites/core_plugins/rendering.ts | 1 - .../translations/translations/fr-FR.json | 61 -- .../translations/translations/ja-JP.json | 61 -- .../translations/translations/zh-CN.json | 61 -- .../apps/dev_tools/embedded_console.ts | 1 + .../apps/reporting_management/config.ts | 5 - .../reporting_management/report_listing.ts | 9 +- .../page_objects/embedded_console.ts | 3 + .../apps/ccs/ccs_console.js | 6 +- .../test_suites/common/console/console.ts | 32 +- .../test_suites/search/embedded_console.ts | 1 + 187 files changed, 5167 insertions(+), 5943 deletions(-) create mode 100644 packages/kbn-monaco/src/console/output_parser.js create mode 100644 packages/kbn-monaco/src/console/output_parser.test.ts create mode 100644 src/plugins/console/public/application/components/console_tour_step.tsx delete mode 100644 src/plugins/console/public/application/components/editor_example.tsx delete mode 100644 src/plugins/console/public/application/components/help_panel.tsx create mode 100644 src/plugins/console/public/application/components/help_popover.tsx create mode 100644 src/plugins/console/public/application/components/output_panel_empty_state.tsx create mode 100644 src/plugins/console/public/application/components/settings/index.ts create mode 100644 src/plugins/console/public/application/components/settings/settings_editor.tsx create mode 100644 src/plugins/console/public/application/components/settings/settings_form_row.tsx create mode 100644 src/plugins/console/public/application/components/settings/settings_group.tsx rename src/plugins/console/public/application/{containers/split_panel/index.ts => components/settings/types.ts} (84%) delete mode 100644 src/plugins/console/public/application/components/settings_modal.tsx rename src/plugins/console/public/application/{containers/editor/legacy/console_editor => components/shortcuts_popover}/index.ts (84%) create mode 100644 src/plugins/console/public/application/components/shortcuts_popover/keys.tsx create mode 100644 src/plugins/console/public/application/components/shortcuts_popover/shortcut_line.tsx create mode 100644 src/plugins/console/public/application/components/shortcuts_popover/shortcuts_popover.tsx create mode 100644 src/plugins/console/public/application/components/variables/types.ts create mode 100644 src/plugins/console/public/application/components/variables/variables_editor.tsx create mode 100644 src/plugins/console/public/application/components/variables/variables_editor_form.tsx delete mode 100644 src/plugins/console/public/application/components/variables/variables_flyout.tsx delete mode 100644 src/plugins/console/public/application/components/welcome_panel.tsx create mode 100644 src/plugins/console/public/application/containers/config/config.tsx rename src/plugins/console/public/application/containers/{editor/utilities => config}/index.ts (93%) rename src/plugins/console/public/application/containers/{ => config}/settings.tsx (88%) rename src/plugins/console/public/application/containers/{ => config}/variables.tsx (66%) delete mode 100644 src/plugins/console/public/application/containers/console_history/console_history.tsx delete mode 100644 src/plugins/console/public/application/containers/console_history/history_viewer.tsx rename src/plugins/console/public/application/containers/editor/{monaco => }/components/context_menu/context_menu.tsx (90%) rename src/plugins/console/public/application/containers/editor/{monaco => }/components/context_menu/index.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/components/context_menu/language_selector_modal.tsx (98%) rename src/plugins/console/public/application/containers/editor/{monaco => }/components/index.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/hooks/index.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/hooks/use_register_keyboard_commands.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/hooks/use_resize_checker_utils.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/hooks/use_set_initial_value.ts (91%) rename src/plugins/console/public/application/containers/editor/{monaco => }/hooks/use_setup_autocomplete_polling.ts (94%) rename src/plugins/console/public/application/containers/editor/{monaco => }/hooks/use_setup_autosave.ts (96%) delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_editor/apply_editor_settings.ts delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_editor/keyboard_shortcuts.ts delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/console_menu_actions.ts delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/index.ts delete mode 100644 src/plugins/console/public/application/containers/editor/legacy/subscribe_console_resize_checker.ts delete mode 100644 src/plugins/console/public/application/containers/editor/monaco/index.ts rename src/plugins/console/public/application/containers/editor/{monaco => }/monaco_editor.tsx (79%) rename src/plugins/console/public/application/containers/editor/{monaco => }/monaco_editor_actions_provider.test.ts (99%) rename src/plugins/console/public/application/containers/editor/{monaco => }/monaco_editor_actions_provider.ts (86%) rename src/plugins/console/public/application/containers/editor/{monaco => }/monaco_editor_output.tsx (60%) create mode 100644 src/plugins/console/public/application/containers/editor/monaco_editor_output_actions_provider.ts rename src/plugins/console/public/application/containers/editor/{monaco => }/monaco_editor_suggestion_provider.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/types.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/autocomplete_utils.test.ts (98%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/autocomplete_utils.ts (99%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/constants.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/index.ts (86%) rename src/plugins/console/public/application/containers/editor/{legacy/console_editor => utils}/mapbox_vector_tile/convert_mapbox_vector_tile_to_json.test.ts (100%) rename src/plugins/console/public/application/containers/editor/{legacy/console_editor => utils}/mapbox_vector_tile/convert_mapbox_vector_tile_to_json.ts (100%) rename src/plugins/console/public/application/containers/editor/{legacy/console_editor => utils}/mapbox_vector_tile/index.ts (100%) rename src/plugins/console/public/application/containers/editor/{legacy/console_editor => utils}/mapbox_vector_tile/response.pbf (100%) rename src/plugins/console/public/application/containers/editor/{utilities => utils}/output_data.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/requests_utils.test.ts (99%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/requests_utils.ts (98%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/status_code_decoration_utils.test.ts (98%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/status_code_decoration_utils.ts (95%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/tokens_utils.test.ts (100%) rename src/plugins/console/public/application/containers/editor/{monaco => }/utils/tokens_utils.ts (100%) create mode 100644 src/plugins/console/public/application/containers/history/history.tsx create mode 100644 src/plugins/console/public/application/containers/history/history_empty.tsx rename src/plugins/console/public/application/containers/{console_history => history}/history_viewer_monaco.tsx (94%) rename src/plugins/console/public/application/containers/{console_history => history}/index.ts (90%) create mode 100644 src/plugins/console/public/application/containers/main/constants.ts create mode 100644 src/plugins/console/public/application/containers/main/get_console_tour_step_props.tsx create mode 100644 src/plugins/console/public/application/containers/main/get_tour_steps.tsx create mode 100644 src/plugins/console/public/application/containers/main/i18n.ts create mode 100644 src/plugins/console/public/application/containers/main/import_confirm_modal.tsx create mode 100644 src/plugins/console/public/application/containers/main/nav_icon_button.tsx delete mode 100644 src/plugins/console/public/application/containers/split_panel/__snapshots__/split_panel.test.tsx.snap delete mode 100644 src/plugins/console/public/application/containers/split_panel/panel.tsx delete mode 100644 src/plugins/console/public/application/containers/split_panel/panel_container.tsx delete mode 100644 src/plugins/console/public/application/containers/split_panel/resizer.tsx delete mode 100644 src/plugins/console/public/application/containers/split_panel/split_panel.test.tsx delete mode 100644 src/plugins/console/public/application/contexts/split_panel/index.ts delete mode 100644 src/plugins/console/public/application/contexts/split_panel/split_panel_context.tsx rename src/plugins/console/public/application/{contexts/split_panel/split_panel_registry.ts => lib/format_request.ts} (57%) rename test/functional/apps/console/{ace => }/_autocomplete.ts (74%) rename test/functional/apps/console/{monaco => }/_comments.ts (88%) rename test/functional/apps/console/{monaco => }/_console.ts (50%) rename test/functional/apps/console/{monaco => }/_console_ccs.ts (84%) rename test/functional/apps/console/{monaco => }/_context_menu.ts (85%) create mode 100644 test/functional/apps/console/_misc_console_behavior.ts create mode 100644 test/functional/apps/console/_onboarding_tour.ts create mode 100644 test/functional/apps/console/_output_panel.ts rename test/functional/apps/console/{ace => }/_settings.ts (71%) rename test/functional/apps/console/{monaco => }/_text_input.ts (64%) rename test/functional/apps/console/{monaco => }/_variables.ts (74%) rename test/functional/apps/console/{ace => }/_vector_tile.ts (88%) rename test/functional/apps/console/{monaco => }/_xjson.ts (62%) delete mode 100644 test/functional/apps/console/ace/_comments.ts delete mode 100644 test/functional/apps/console/ace/_console.ts delete mode 100644 test/functional/apps/console/ace/_console_ccs.ts delete mode 100644 test/functional/apps/console/ace/_context_menu.ts delete mode 100644 test/functional/apps/console/ace/_misc_console_behavior.ts delete mode 100644 test/functional/apps/console/ace/_text_input.ts delete mode 100644 test/functional/apps/console/ace/_variables.ts delete mode 100644 test/functional/apps/console/ace/_xjson.ts delete mode 100644 test/functional/apps/console/ace/config.ts rename test/functional/apps/console/{monaco => }/config.ts (88%) rename test/functional/apps/console/{ace => }/index.ts (88%) delete mode 100644 test/functional/apps/console/monaco/_autocomplete.ts delete mode 100644 test/functional/apps/console/monaco/_misc_console_behavior.ts delete mode 100644 test/functional/apps/console/monaco/_settings.ts delete mode 100644 test/functional/apps/console/monaco/_vector_tile.ts delete mode 100644 test/functional/apps/console/monaco/index.ts diff --git a/.buildkite/ftr_platform_stateful_configs.yml b/.buildkite/ftr_platform_stateful_configs.yml index fc46fa24f257f..02d6355c212bd 100644 --- a/.buildkite/ftr_platform_stateful_configs.yml +++ b/.buildkite/ftr_platform_stateful_configs.yml @@ -44,8 +44,7 @@ enabled: - test/api_integration/config.js - test/examples/config.js - test/functional/apps/bundles/config.ts - - test/functional/apps/console/monaco/config.ts - - test/functional/apps/console/ace/config.ts + - test/functional/apps/console/config.ts - test/functional/apps/context/config.ts - test/functional/apps/dashboard_elements/controls/common/config.ts - test/functional/apps/dashboard_elements/controls/options_list/config.ts diff --git a/packages/kbn-monaco/index.ts b/packages/kbn-monaco/index.ts index 795664b60e7b7..ba8b0edb68e1a 100644 --- a/packages/kbn-monaco/index.ts +++ b/packages/kbn-monaco/index.ts @@ -39,6 +39,7 @@ export { CONSOLE_THEME_ID, getParsedRequestsProvider, ConsoleParsedRequestsProvider, + createOutputParser, } from './src/console'; export type { ParsedRequest } from './src/console'; diff --git a/packages/kbn-monaco/src/console/index.ts b/packages/kbn-monaco/src/console/index.ts index 6b26c6262f568..cf36505b27759 100644 --- a/packages/kbn-monaco/src/console/index.ts +++ b/packages/kbn-monaco/src/console/index.ts @@ -43,3 +43,5 @@ export const ConsoleOutputLang: LangModuleType = { export type { ParsedRequest } from './types'; export { getParsedRequestsProvider } from './language'; export { ConsoleParsedRequestsProvider } from './console_parsed_requests_provider'; + +export { createOutputParser } from './output_parser'; diff --git a/packages/kbn-monaco/src/console/output_parser.js b/packages/kbn-monaco/src/console/output_parser.js new file mode 100644 index 0000000000000..8601cf764055e --- /dev/null +++ b/packages/kbn-monaco/src/console/output_parser.js @@ -0,0 +1,401 @@ +/* + * 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". + */ + +/* eslint-disable prettier/prettier,prefer-const,no-throw-literal,camelcase,@typescript-eslint/no-shadow,one-var,object-shorthand,eqeqeq */ + +export const createOutputParser = () => { + let at, // The index of the current character + ch, // The current character + escapee = { + '"': '"', + '\\': '\\', + '/': '/', + b: '\b', + f: '\f', + n: '\n', + r: '\r', + t: '\t', + }, + text, + errors, + addError = function (text) { + errors.push({ text: text, offset: at }); + }, + responses, + responseStartOffset, + responseEndOffset, + getLastResponse = function() { + return responses.length > 0 ? responses.pop() : {}; + }, + addResponseStart = function() { + responseStartOffset = at - 1; + responses.push({ startOffset: responseStartOffset }); + }, + addResponseData = function(data) { + const lastResponse = getLastResponse(); + const dataArray = lastResponse.data || []; + dataArray.push(data); + lastResponse.data = dataArray; + responses.push(lastResponse); + responseEndOffset = at - 1; + }, + addResponseEnd = function() { + const lastResponse = getLastResponse(); + lastResponse.endOffset = responseEndOffset; + responses.push(lastResponse); + }, + error = function (m) { + throw { + name: 'SyntaxError', + message: m, + at: at, + text: text, + }; + }, + reset = function (newAt) { + ch = text.charAt(newAt); + at = newAt + 1; + }, + next = function (c) { + if (c && c !== ch) { + error('Expected \'' + c + '\' instead of \'' + ch + '\''); + } + + ch = text.charAt(at); + at += 1; + return ch; + }, + nextUpTo = function (upTo, errorMessage) { + let currentAt = at, + i = text.indexOf(upTo, currentAt); + if (i < 0) { + error(errorMessage || 'Expected \'' + upTo + '\''); + } + reset(i + upTo.length); + return text.substring(currentAt, i); + }, + peek = function (offset) { + return text.charAt(at + offset); + }, + number = function () { + let number, + string = ''; + + if (ch === '-') { + string = '-'; + next('-'); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + if (ch === '.') { + string += '.'; + while (next() && ch >= '0' && ch <= '9') { + string += ch; + } + } + if (ch === 'e' || ch === 'E') { + string += ch; + next(); + if (ch === '-' || ch === '+') { + string += ch; + next(); + } + while (ch >= '0' && ch <= '9') { + string += ch; + next(); + } + } + number = +string; + if (isNaN(number)) { + error('Bad number'); + } else { + return number; + } + }, + string = function () { + let hex, + i, + string = '', + uffff; + + if (ch === '"') { + // If the current and the next characters are equal to "", empty string or start of triple quoted strings + if (peek(0) === '"' && peek(1) === '"') { + // literal + next('"'); + next('"'); + return nextUpTo('"""', 'failed to find closing \'"""\''); + } else { + while (next()) { + if (ch === '"') { + next(); + return string; + } else if (ch === '\\') { + next(); + if (ch === 'u') { + uffff = 0; + for (i = 0; i < 4; i += 1) { + hex = parseInt(next(), 16); + if (!isFinite(hex)) { + break; + } + uffff = uffff * 16 + hex; + } + string += String.fromCharCode(uffff); + } else if (typeof escapee[ch] === 'string') { + string += escapee[ch]; + } else { + break; + } + } else { + string += ch; + } + } + } + } + error('Bad string'); + }, + white = function () { + while (ch) { + // Skip whitespace. + while (ch && ch <= ' ') { + next(); + } + // if the current char in iteration is '#' or the char and the next char is equal to '//' + // we are on the single line comment + if (ch === '#' || ch === '/' && peek(0) === '/') { + // Until we are on the new line, skip to the next char + while (ch && ch !== '\n') { + next(); + } + } else if (ch === '/' && peek(0) === '*') { + // If the chars starts with '/*', we are on the multiline comment + next(); + next(); + while (ch && !(ch === '*' && peek(0) === '/')) { + // Until we have closing tags '*/', skip to the next char + next(); + } + if (ch) { + next(); + next(); + } + } else break; + } + }, + strictWhite = function () { + while (ch && (ch == ' ' || ch == '\t')) { + next(); + } + }, + newLine = function () { + if (ch == '\n') next(); + }, + word = function () { + switch (ch) { + case 't': + next('t'); + next('r'); + next('u'); + next('e'); + return true; + case 'f': + next('f'); + next('a'); + next('l'); + next('s'); + next('e'); + return false; + case 'n': + next('n'); + next('u'); + next('l'); + next('l'); + return null; + } + error('Unexpected \'' + ch + '\''); + }, + value, // Place holder for the value function. + array = function () { + const array = []; + + if (ch === '[') { + next('['); + white(); + if (ch === ']') { + next(']'); + return array; // empty array + } + while (ch) { + array.push(value()); + white(); + if (ch === ']') { + next(']'); + return array; + } + next(','); + white(); + } + } + error('Bad array'); + }, + object = function () { + let key, + object = {}; + + if (ch === '{') { + next('{'); + white(); + if (ch === '}') { + next('}'); + return object; // empty object + } + while (ch) { + key = string(); + white(); + next(':'); + if (Object.hasOwnProperty.call(object, key)) { + error('Duplicate key "' + key + '"'); + } + object[key] = value(); + white(); + if (ch === '}') { + next('}'); + return object; + } + next(','); + white(); + } + } + error('Bad object'); + }; + + value = function () { + white(); + switch (ch) { + case '{': + return object(); + case '[': + return array(); + case '"': + return string(); + case '-': + return number(); + default: + return ch >= '0' && ch <= '9' ? number() : word(); + } + }; + + let response = function () { + white(); + addResponseStart(); + // it can be an object + if (ch == '{') { + const parsedObject = object(); + addResponseData(parsedObject); + // but it could also be an array of objects + } else if (ch == '[') { + const parsedArray = array(); + parsedArray.forEach(item => { + if (typeof item === 'object') { + addResponseData(item); + } else { + error('Array elements must be objects'); + } + }); + } else { + error('Invalid input'); + } + // multi doc response + strictWhite(); // advance to one new line + newLine(); + strictWhite(); + while (ch == '{') { + // another object + const parsedObject = object(); + addResponseData(parsedObject); + strictWhite(); + newLine(); + strictWhite(); + } + addResponseEnd(); + }, + comment = function () { + while (ch == '#') { + while (ch && ch !== '\n') { + next(); + } + white(); + } + }, + multi_response = function () { + while (ch && ch != '') { + white(); + if (!ch) { + continue; + } + try { + comment(); + white(); + if (!ch) { + continue; + } + response(); + white(); + } catch (e) { + addError(e.message); + // snap + const substring = text.substr(at); + const nextMatch = substring.search(/[#{]/); + if (nextMatch < 1) return; + reset(at + nextMatch); + } + } + }; + + return function (source, reviver) { + let result; + + text = source; + at = 0; + errors = []; + responses = []; + next(); + multi_response(); + white(); + if (ch) { + addError('Syntax error'); + } + + result = { errors, responses }; + + return typeof reviver === 'function' + ? (function walk(holder, key) { + let k, + v, + value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + }({ '': result }, '')) + : result; + }; +} diff --git a/packages/kbn-monaco/src/console/output_parser.test.ts b/packages/kbn-monaco/src/console/output_parser.test.ts new file mode 100644 index 0000000000000..47ec0bbeb65e4 --- /dev/null +++ b/packages/kbn-monaco/src/console/output_parser.test.ts @@ -0,0 +1,40 @@ +/* + * 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 { createOutputParser } from './output_parser'; +import { ConsoleOutputParserResult } from './types'; + +const parser = createOutputParser(); +describe('console output parser', () => { + it('returns errors if input is not correct', () => { + const input = 'x'; + const parserResult = parser(input) as ConsoleOutputParserResult; + + expect(parserResult.responses.length).toBe(1); + // the parser should generate an invalid input error + expect(parserResult.errors).toContainEqual({ text: 'Invalid input', offset: 1 }); + }); + + it('returns parsed responses if the input is correct', () => { + const input = `# 1: GET /my-index/_doc/0 \n { "_index": "my-index" }`; + const { responses, errors } = parser(input) as ConsoleOutputParserResult; + expect(responses.length).toBe(1); + expect(errors.length).toBe(0); + const { data } = responses[0]; + + const expected = [{ _index: 'my-index' }]; + expect(data).toEqual(expected); + }); + + it('parses several responses', () => { + const input = `# 1: GET /my-index/_doc/0 \n { "_index": "my-index" } \n # 2: GET /my-index/_doc/1 \n { "_index": "my-index" }`; + const { responses } = parser(input) as ConsoleOutputParserResult; + expect(responses.length).toBe(2); + }); +}); diff --git a/packages/kbn-monaco/src/console/types.ts b/packages/kbn-monaco/src/console/types.ts index 6c7573eabdb2c..a024e4696f8cd 100644 --- a/packages/kbn-monaco/src/console/types.ts +++ b/packages/kbn-monaco/src/console/types.ts @@ -21,6 +21,16 @@ export interface ConsoleParserResult { requests: ParsedRequest[]; } +export interface ConsoleOutputParsedResponse { + startOffset: number; + endOffset?: number; + data?: Array>; +} +export interface ConsoleOutputParserResult { + errors: ErrorAnnotation[]; + responses: ConsoleOutputParsedResponse[]; +} + export interface ConsoleWorkerDefinition { getParserResult: (modelUri: string) => ConsoleParserResult | undefined; } diff --git a/src/plugins/console/common/constants/autocomplete_definitions.ts b/src/plugins/console/common/constants/autocomplete_definitions.ts index b2ef4f1375419..0ab69c1fa9528 100644 --- a/src/plugins/console/common/constants/autocomplete_definitions.ts +++ b/src/plugins/console/common/constants/autocomplete_definitions.ts @@ -17,3 +17,5 @@ export const AUTOCOMPLETE_DEFINITIONS_FOLDER = resolve( export const GENERATED_SUBFOLDER = 'generated'; export const OVERRIDES_SUBFOLDER = 'overrides'; export const MANUAL_SUBFOLDER = 'manual'; + +export const API_DOCS_LINK = 'https://www.elastic.co/docs/api'; diff --git a/src/plugins/console/common/constants/index.ts b/src/plugins/console/common/constants/index.ts index ea572db743ef4..a00bcebcf38cc 100644 --- a/src/plugins/console/common/constants/index.ts +++ b/src/plugins/console/common/constants/index.ts @@ -15,6 +15,7 @@ export { GENERATED_SUBFOLDER, OVERRIDES_SUBFOLDER, MANUAL_SUBFOLDER, + API_DOCS_LINK, } from './autocomplete_definitions'; export { DEFAULT_INPUT_VALUE } from './editor_input'; export { DEFAULT_LANGUAGE, AVAILABLE_LANGUAGES } from './copy_as'; diff --git a/src/plugins/console/public/application/components/console_menu.tsx b/src/plugins/console/public/application/components/console_menu.tsx index 3ed1d67c3602b..4dee3ff06df0a 100644 --- a/src/plugins/console/public/application/components/console_menu.tsx +++ b/src/plugins/console/public/application/components/console_menu.tsx @@ -11,13 +11,7 @@ import React, { Component } from 'react'; import { NotificationsSetup } from '@kbn/core/public'; -import { - EuiIcon, - EuiContextMenuPanel, - EuiContextMenuItem, - EuiPopover, - EuiLink, -} from '@elastic/eui'; +import { EuiContextMenuPanel, EuiContextMenuItem, EuiPopover, EuiButtonIcon } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; @@ -115,15 +109,15 @@ export class ConsoleMenu extends Component { render() { const button = ( - - - + iconType="boxesVertical" + iconSize="s" + /> ); const items = [ diff --git a/src/plugins/console/public/application/components/console_tour_step.tsx b/src/plugins/console/public/application/components/console_tour_step.tsx new file mode 100644 index 0000000000000..578d590bfff4a --- /dev/null +++ b/src/plugins/console/public/application/components/console_tour_step.tsx @@ -0,0 +1,64 @@ +/* + * 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 React, { ReactNode, ReactElement } from 'react'; +import { EuiTourStep, PopoverAnchorPosition } from '@elastic/eui'; + +export interface ConsoleTourStepProps { + step: number; + stepsTotal: number; + isStepOpen: boolean; + title: ReactNode; + content: ReactNode; + onFinish: () => void; + footerAction: ReactNode | ReactNode[]; + dataTestSubj: string; + anchorPosition: string; + maxWidth: number; + css?: any; +} + +interface Props { + tourStepProps: ConsoleTourStepProps; + children: ReactNode & ReactElement; +} + +export const ConsoleTourStep = ({ tourStepProps, children }: Props) => { + const { + step, + isStepOpen, + stepsTotal, + title, + content, + onFinish, + footerAction, + dataTestSubj, + anchorPosition, + maxWidth, + css, + } = tourStepProps; + + return ( + + {children} + + ); +}; diff --git a/src/plugins/console/public/application/components/editor_content_spinner.tsx b/src/plugins/console/public/application/components/editor_content_spinner.tsx index eecd9aebf67cc..a4d0ccc98b76c 100644 --- a/src/plugins/console/public/application/components/editor_content_spinner.tsx +++ b/src/plugins/console/public/application/components/editor_content_spinner.tsx @@ -8,12 +8,12 @@ */ import React, { FunctionComponent } from 'react'; -import { EuiSkeletonText, EuiPageSection } from '@elastic/eui'; +import { EuiLoadingSpinner, EuiPageSection } from '@elastic/eui'; export const EditorContentSpinner: FunctionComponent = () => { return ( - - + + ); }; diff --git a/src/plugins/console/public/application/components/editor_example.tsx b/src/plugins/console/public/application/components/editor_example.tsx deleted file mode 100644 index 6a5ab6333c3b5..0000000000000 --- a/src/plugins/console/public/application/components/editor_example.tsx +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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 { EuiScreenReaderOnly, withEuiTheme } from '@elastic/eui'; -import type { WithEuiThemeProps } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React, { useEffect, useRef } from 'react'; -import { createReadOnlyAceEditor, CustomAceEditor } from '../models/sense_editor'; -// @ts-ignore -import { Mode as InputMode } from '../models/legacy_core_editor/mode/input'; -import { Mode as OutputMode } from '../models/legacy_core_editor/mode/output'; - -interface EditorExampleProps { - panel: string; - example?: string; - theme: WithEuiThemeProps['theme']; - linesOfExampleCode?: number; - mode?: string; -} - -const exampleText = ` -GET _search -{ - "query": { - "match_all": {} - } -} -`; - -const EditorExample = ({ - panel, - example, - theme, - linesOfExampleCode = 6, - mode = 'input', -}: EditorExampleProps) => { - const inputId = `help-example-${panel}-input`; - const wrapperDivRef = useRef(null); - const editorRef = useRef(); - - useEffect(() => { - if (wrapperDivRef.current) { - editorRef.current = createReadOnlyAceEditor(wrapperDivRef.current); - - const editor = editorRef.current; - const editorMode = mode === 'input' ? new InputMode() : new OutputMode(); - editor.update((example || exampleText).trim(), editorMode); - editor.session.setUseWorker(false); - editor.setHighlightActiveLine(false); - - const textareaElement = wrapperDivRef.current.querySelector('textarea'); - if (textareaElement) { - textareaElement.setAttribute('id', inputId); - textareaElement.setAttribute('readonly', 'true'); - } - } - - return () => { - if (editorRef.current) { - editorRef.current.destroy(); - } - }; - }, [example, inputId, mode]); - - const wrapperDivStyle = { - height: `${parseInt(theme.euiTheme.size.base, 10) * linesOfExampleCode}px`, - margin: `${theme.euiTheme.size.base} 0`, - }; - - return ( - <> - - - -
- - ); -}; - -// eslint-disable-next-line import/no-default-export -export default withEuiTheme(EditorExample); diff --git a/src/plugins/console/public/application/components/help_panel.tsx b/src/plugins/console/public/application/components/help_panel.tsx deleted file mode 100644 index 30a356e27002e..0000000000000 --- a/src/plugins/console/public/application/components/help_panel.tsx +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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 React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { - EuiText, - EuiFlyout, - EuiFlyoutHeader, - EuiFlyoutBody, - EuiTitle, - EuiSpacer, - EuiLink, -} from '@elastic/eui'; -import EditorExample from './editor_example'; -import { useServicesContext } from '../contexts'; - -interface Props { - onClose: () => void; -} - -export function HelpPanel(props: Props) { - const { docLinks } = useServicesContext(); - - return ( - - - -

- -

-
-
- - -

- -

-

- -

-

- - Console - - ), - queryDsl: ( - - Query DSL - - ), - }} - /> -

- -

- -

- -
-
Ctrl/Cmd + I
-
- -
-
Ctrl/Cmd + /
-
- -
-
Ctrl + Space
-
- -
-
Ctrl/Cmd + Enter
-
- -
-
Ctrl/Cmd + Up/Down
-
- -
-
Ctrl/Cmd + Alt + L
-
- -
-
Ctrl/Cmd + Option + 0
-
- -
-
Down arrow
-
- -
-
Enter/Tab
-
- -
-
Ctrl/Cmd + L
-
- -
-
Esc
-
- -
-
-
-
-
- ); -} diff --git a/src/plugins/console/public/application/components/help_popover.tsx b/src/plugins/console/public/application/components/help_popover.tsx new file mode 100644 index 0000000000000..16e9465d4d388 --- /dev/null +++ b/src/plugins/console/public/application/components/help_popover.tsx @@ -0,0 +1,136 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiPopover, + EuiTitle, + EuiText, + EuiFlexGroup, + EuiFlexItem, + EuiButtonIcon, + EuiSpacer, +} from '@elastic/eui'; +import { useServicesContext } from '../contexts'; + +interface HelpPopoverProps { + button: any; + isOpen: boolean; + closePopover: () => void; + resetTour: () => void; +} + +export const HelpPopover = ({ button, isOpen, closePopover, resetTour }: HelpPopoverProps) => { + const { docLinks } = useServicesContext(); + + return ( + + +

+ {i18n.translate('console.helpPopover.title', { + defaultMessage: 'Elastic Console', + })} +

+
+ + + + +

+ {i18n.translate('console.helpPopover.description', { + defaultMessage: + 'Console is an interactive UI for calling Elasticsearch and Kibana APIs and viewing their responses. Search your data, manage settings, and more, using Query DSL and REST API syntax.', + })} +

+
+ + + + + + + +

+ {i18n.translate('console.helpPopover.aboutConsoleLabel', { + defaultMessage: 'About Console', + })} +

+
+ + + +
+
+ + + + +

+ {i18n.translate('console.helpPopover.aboutQueryDSLLabel', { + defaultMessage: 'About Query DSL', + })} +

+
+ + + +
+
+ + + + +

+ {i18n.translate('console.helpPopover.rerunTourLabel', { + defaultMessage: 'Re-run feature tour', + })} +

+
+ + + +
+
+
+
+ ); +}; diff --git a/src/plugins/console/public/application/components/index.ts b/src/plugins/console/public/application/components/index.ts index e091fb5f2f8a5..111778d8fa776 100644 --- a/src/plugins/console/public/application/components/index.ts +++ b/src/plugins/console/public/application/components/index.ts @@ -7,50 +7,14 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React from 'react'; -import { withSuspense } from '@kbn/shared-ux-utility'; - export { NetworkRequestStatusBar } from './network_request_status_bar'; export { SomethingWentWrongCallout } from './something_went_wrong_callout'; export type { TopNavMenuItem } from './top_nav_menu'; export { TopNavMenu } from './top_nav_menu'; export { ConsoleMenu } from './console_menu'; -export { WelcomePanel } from './welcome_panel'; -export type { AutocompleteOptions } from './settings_modal'; -export { HelpPanel } from './help_panel'; export { EditorContentSpinner } from './editor_content_spinner'; -export type { DevToolsVariable } from './variables'; - -/** - * The Lazily-loaded `DevToolsSettingsModal` component. Consumers should use `React.Suspense` or - * the withSuspense` HOC to load this component. - */ -export const DevToolsSettingsModalLazy = React.lazy(() => - import('./settings_modal').then(({ DevToolsSettingsModal }) => ({ - default: DevToolsSettingsModal, - })) -); - -/** - * A `DevToolsSettingsModal` component that is wrapped by the `withSuspense` HOC. This component can - * be used directly by consumers and will load the `DevToolsSettingsModalLazy` component lazily with - * a predefined fallback and error boundary. - */ -export const DevToolsSettingsModal = withSuspense(DevToolsSettingsModalLazy); - -/** - * The Lazily-loaded `DevToolsVariablesFlyout` component. Consumers should use `React.Suspense` or - * the withSuspense` HOC to load this component. - */ -export const DevToolsVariablesFlyoutLazy = React.lazy(() => - import('./variables').then(({ DevToolsVariablesFlyout }) => ({ - default: DevToolsVariablesFlyout, - })) -); - -/** - * A `DevToolsVariablesFlyout` component that is wrapped by the `withSuspense` HOC. This component can - * be used directly by consumers and will load the `DevToolsVariablesFlyoutLazy` component lazily with - * a predefined fallback and error boundary. - */ -export const DevToolsVariablesFlyout = withSuspense(DevToolsVariablesFlyoutLazy); +export { OutputPanelEmptyState } from './output_panel_empty_state'; +export { HelpPopover } from './help_popover'; +export { ShortcutsPopover } from './shortcuts_popover'; +export type { DevToolsVariable } from './variables/types'; +export { ConsoleTourStep, type ConsoleTourStepProps } from './console_tour_step'; diff --git a/src/plugins/console/public/application/components/output_panel_empty_state.tsx b/src/plugins/console/public/application/components/output_panel_empty_state.tsx new file mode 100644 index 0000000000000..6fdda1b5e3c5f --- /dev/null +++ b/src/plugins/console/public/application/components/output_panel_empty_state.tsx @@ -0,0 +1,57 @@ +/* + * 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 React, { FunctionComponent } from 'react'; +import { EuiEmptyPrompt, EuiTitle, EuiLink } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useServicesContext } from '../contexts'; + +export const OutputPanelEmptyState: FunctionComponent = () => { + const { docLinks } = useServicesContext(); + + return ( + + + + } + body={ +

+ +

+ } + footer={ + <> + +

+ +

+
+ + + + + } + data-test-subj="consoleOutputPanelEmptyState" + /> + ); +}; diff --git a/src/plugins/console/public/application/components/settings/index.ts b/src/plugins/console/public/application/components/settings/index.ts new file mode 100644 index 0000000000000..b446307a04a01 --- /dev/null +++ b/src/plugins/console/public/application/components/settings/index.ts @@ -0,0 +1,31 @@ +/* + * 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 React from 'react'; +import { withSuspense } from '@kbn/shared-ux-utility'; + +export { type Props } from './settings_editor'; +export { type AutocompleteOptions } from './types'; + +/** + * The Lazily-loaded `SettingsEditorLazy` component. Consumers should use `React.Suspense` or + * the withSuspense` HOC to load this component. + */ +export const SettingsEditorLazy = React.lazy(() => + import('./settings_editor').then(({ SettingsEditor }) => ({ + default: SettingsEditor, + })) +); + +/** + * A `SettingsEditor` component that is wrapped by the `withSuspense` HOC. This component can + * be used directly by consumers and will load the `SettingsEditorLazy` component lazily with + * a predefined fallback and error boundary. + */ +export const SettingsEditor = withSuspense(SettingsEditorLazy); diff --git a/src/plugins/console/public/application/components/settings/settings_editor.tsx b/src/plugins/console/public/application/components/settings/settings_editor.tsx new file mode 100644 index 0000000000000..6f2bef834a559 --- /dev/null +++ b/src/plugins/console/public/application/components/settings/settings_editor.tsx @@ -0,0 +1,371 @@ +/* + * 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 { debounce } from 'lodash'; +import React, { useState, useCallback, useEffect, useRef } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { + EuiButton, + EuiFieldNumber, + EuiSwitch, + EuiSuperSelect, + EuiTitle, + EuiSpacer, + EuiText, +} from '@elastic/eui'; + +import { SettingsGroup } from './settings_group'; +import { SettingsFormRow } from './settings_form_row'; +import { DevToolsSettings } from '../../../services'; + +const DEBOUNCE_DELAY = 500; +const ON_LABEL = i18n.translate('console.settingsPage.onLabel', { defaultMessage: 'On' }); +const OFF_LABEL = i18n.translate('console.settingsPage.offLabel', { defaultMessage: 'Off' }); + +const onceTimeInterval = () => + i18n.translate('console.settingsPage.refreshInterval.onceTimeInterval', { + defaultMessage: 'Once, when console loads', + }); + +const everyNMinutesTimeInterval = (value: number) => + i18n.translate('console.settingsPage.refreshInterval.everyNMinutesTimeInterval', { + defaultMessage: 'Every {value} {value, plural, one {minute} other {minutes}}', + values: { value }, + }); + +const everyHourTimeInterval = () => + i18n.translate('console.settingsPage.refreshInterval.everyHourTimeInterval', { + defaultMessage: 'Every hour', + }); + +const PRESETS_IN_MINUTES = [0, 1, 10, 20, 60]; +const intervalOptions = PRESETS_IN_MINUTES.map((value) => ({ + value: (value * 60000).toString(), + inputDisplay: + value === 0 + ? onceTimeInterval() + : value === 60 + ? everyHourTimeInterval() + : everyNMinutesTimeInterval(value), +})); + +export interface Props { + onSaveSettings: (newSettings: DevToolsSettings) => void; + refreshAutocompleteSettings: (selectedSettings: DevToolsSettings['autocomplete']) => void; + settings: DevToolsSettings; +} + +export const SettingsEditor = (props: Props) => { + const isMounted = useRef(false); + + const [fontSize, setFontSize] = useState(props.settings.fontSize); + const [wrapMode, setWrapMode] = useState(props.settings.wrapMode); + const [fields, setFields] = useState(props.settings.autocomplete.fields); + const [indices, setIndices] = useState(props.settings.autocomplete.indices); + const [templates, setTemplates] = useState(props.settings.autocomplete.templates); + const [dataStreams, setDataStreams] = useState(props.settings.autocomplete.dataStreams); + const [polling, setPolling] = useState(props.settings.polling); + const [pollInterval, setPollInterval] = useState(props.settings.pollInterval); + const [tripleQuotes, setTripleQuotes] = useState(props.settings.tripleQuotes); + const [isHistoryEnabled, setIsHistoryEnabled] = useState(props.settings.isHistoryEnabled); + const [isKeyboardShortcutsEnabled, setIsKeyboardShortcutsEnabled] = useState( + props.settings.isKeyboardShortcutsEnabled + ); + const [isAccessibilityOverlayEnabled, setIsAccessibilityOverlayEnabled] = useState( + props.settings.isAccessibilityOverlayEnabled + ); + + const autoCompleteCheckboxes = [ + { + id: 'fields', + label: i18n.translate('console.settingsPage.fieldsLabelText', { + defaultMessage: 'Fields', + }), + stateSetter: setFields, + checked: fields, + }, + { + id: 'indices', + label: i18n.translate('console.settingsPage.indicesAndAliasesLabelText', { + defaultMessage: 'Indices and aliases', + }), + stateSetter: setIndices, + checked: indices, + }, + { + id: 'templates', + label: i18n.translate('console.settingsPage.templatesLabelText', { + defaultMessage: 'Templates', + }), + stateSetter: setTemplates, + checked: templates, + }, + { + id: 'dataStreams', + label: i18n.translate('console.settingsPage.dataStreamsLabelText', { + defaultMessage: 'Data streams', + }), + stateSetter: setDataStreams, + checked: dataStreams, + }, + ]; + + const saveSettings = () => { + props.onSaveSettings({ + fontSize, + wrapMode, + autocomplete: { + fields, + indices, + templates, + dataStreams, + }, + polling, + pollInterval, + tripleQuotes, + isHistoryEnabled, + isKeyboardShortcutsEnabled, + isAccessibilityOverlayEnabled, + }); + }; + const debouncedSaveSettings = debounce(saveSettings, DEBOUNCE_DELAY); + + useEffect(() => { + if (isMounted.current) { + debouncedSaveSettings(); + } else { + isMounted.current = true; + } + }, [ + fontSize, + wrapMode, + fields, + indices, + templates, + dataStreams, + polling, + pollInterval, + tripleQuotes, + isHistoryEnabled, + isKeyboardShortcutsEnabled, + isAccessibilityOverlayEnabled, + debouncedSaveSettings, + ]); + + const onPollingIntervalChange = useCallback((value: string) => { + const sanitizedValue = parseInt(value, 10); + + setPolling(!!sanitizedValue); + setPollInterval(sanitizedValue); + }, []); + + const toggleKeyboardShortcuts = useCallback((isEnabled: boolean) => { + setIsKeyboardShortcutsEnabled(isEnabled); + }, []); + + const toggleAccessibilityOverlay = useCallback( + (isEnabled: boolean) => setIsAccessibilityOverlayEnabled(isEnabled), + [] + ); + + const toggleSavingToHistory = useCallback( + (isEnabled: boolean) => setIsHistoryEnabled(isEnabled), + [] + ); + + return ( + <> + +

+ +

+
+ + +

+ +

+
+ + {/* GENERAL SETTINGS */} + + + toggleSavingToHistory(e.target.checked)} + /> + + + toggleKeyboardShortcuts(e.target.checked)} + /> + + + toggleAccessibilityOverlay(e.target.checked)} + /> + + + {/* DISPLAY SETTINGS */} + + + { + const val = parseInt(e.target.value, 10); + if (!val) return; + setFontSize(val); + }} + /> + + + setWrapMode(e.target.checked)} + id="wrapLines" + /> + + + setTripleQuotes(e.target.checked)} + id="tripleQuotes" + /> + + + {/* AUTOCOMPLETE SETTINGS */} + + {autoCompleteCheckboxes.map((opts) => ( + + opts.stateSetter(e.target.checked)} + /> + + ))} + + {/* AUTOCOMPLETE REFRESH SETTINGS */} + {(fields || indices || templates || dataStreams) && ( + <> + + + + + + + { + // Only refresh the currently selected settings. + props.refreshAutocompleteSettings({ + fields, + indices, + templates, + dataStreams, + }); + }} + > + + + + + )} + + ); +}; diff --git a/src/plugins/console/public/application/components/settings/settings_form_row.tsx b/src/plugins/console/public/application/components/settings/settings_form_row.tsx new file mode 100644 index 0000000000000..383eabfb93bd2 --- /dev/null +++ b/src/plugins/console/public/application/components/settings/settings_form_row.tsx @@ -0,0 +1,33 @@ +/* + * 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 React from 'react'; + +import { EuiFlexGroup, EuiFlexItem, EuiFormRow } from '@elastic/eui'; + +export interface DevToolsSettingsModalProps { + label: string; + children: React.ReactNode; +} + +export const SettingsFormRow = ({ label, children }: DevToolsSettingsModalProps) => { + return ( + + + + + {label} + + + + {children} + + + ); +}; diff --git a/src/plugins/console/public/application/components/settings/settings_group.tsx b/src/plugins/console/public/application/components/settings/settings_group.tsx new file mode 100644 index 0000000000000..d6feb8af1c90a --- /dev/null +++ b/src/plugins/console/public/application/components/settings/settings_group.tsx @@ -0,0 +1,37 @@ +/* + * 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 React from 'react'; + +import { EuiTitle, EuiSpacer, EuiText, EuiHorizontalRule } from '@elastic/eui'; + +export interface DevToolsSettingsModalProps { + title: string; + description?: string; +} + +export const SettingsGroup = ({ title, description }: DevToolsSettingsModalProps) => { + return ( + <> + + +

{title}

+
+ {description && ( + <> + + +

{description}

+
+ + )} + + + ); +}; diff --git a/src/plugins/console/public/application/containers/split_panel/index.ts b/src/plugins/console/public/application/components/settings/types.ts similarity index 84% rename from src/plugins/console/public/application/containers/split_panel/index.ts rename to src/plugins/console/public/application/components/settings/types.ts index 00aa2b83db6d8..f524e37124746 100644 --- a/src/plugins/console/public/application/containers/split_panel/index.ts +++ b/src/plugins/console/public/application/components/settings/types.ts @@ -7,5 +7,4 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export { Panel } from './panel'; -export { PanelsContainer } from './panel_container'; +export type AutocompleteOptions = 'fields' | 'indices' | 'templates'; diff --git a/src/plugins/console/public/application/components/settings_modal.tsx b/src/plugins/console/public/application/components/settings_modal.tsx deleted file mode 100644 index 9b7740b4affdf..0000000000000 --- a/src/plugins/console/public/application/components/settings_modal.tsx +++ /dev/null @@ -1,391 +0,0 @@ -/* - * 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 _ from 'lodash'; -import React, { Fragment, useState, useCallback } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { - EuiButton, - EuiButtonEmpty, - EuiFieldNumber, - EuiFormRow, - EuiCheckboxGroup, - EuiModal, - EuiModalBody, - EuiModalFooter, - EuiModalHeader, - EuiModalHeaderTitle, - EuiSwitch, - EuiSuperSelect, -} from '@elastic/eui'; - -import { DevToolsSettings } from '../../services'; -import { unregisterCommands } from '../containers/editor/legacy/console_editor/keyboard_shortcuts'; -import type { SenseEditor } from '../models'; - -export type AutocompleteOptions = 'fields' | 'indices' | 'templates'; - -const onceTimeInterval = () => - i18n.translate('console.settingsPage.refreshInterval.onceTimeInterval', { - defaultMessage: 'Once, when console loads', - }); - -const everyNMinutesTimeInterval = (value: number) => - i18n.translate('console.settingsPage.refreshInterval.everyNMinutesTimeInterval', { - defaultMessage: 'Every {value} {value, plural, one {minute} other {minutes}}', - values: { value }, - }); - -const everyHourTimeInterval = () => - i18n.translate('console.settingsPage.refreshInterval.everyHourTimeInterval', { - defaultMessage: 'Every hour', - }); - -const PRESETS_IN_MINUTES = [0, 1, 10, 20, 60]; -const intervalOptions = PRESETS_IN_MINUTES.map((value) => ({ - value: (value * 60000).toString(), - inputDisplay: - value === 0 - ? onceTimeInterval() - : value === 60 - ? everyHourTimeInterval() - : everyNMinutesTimeInterval(value), -})); - -export interface DevToolsSettingsModalProps { - onSaveSettings: (newSettings: DevToolsSettings) => void; - onClose: () => void; - refreshAutocompleteSettings: (selectedSettings: DevToolsSettings['autocomplete']) => void; - settings: DevToolsSettings; - editorInstance: SenseEditor | null; -} - -export const DevToolsSettingsModal = (props: DevToolsSettingsModalProps) => { - const [fontSize, setFontSize] = useState(props.settings.fontSize); - const [wrapMode, setWrapMode] = useState(props.settings.wrapMode); - const [fields, setFields] = useState(props.settings.autocomplete.fields); - const [indices, setIndices] = useState(props.settings.autocomplete.indices); - const [templates, setTemplates] = useState(props.settings.autocomplete.templates); - const [dataStreams, setDataStreams] = useState(props.settings.autocomplete.dataStreams); - const [polling, setPolling] = useState(props.settings.polling); - const [pollInterval, setPollInterval] = useState(props.settings.pollInterval); - const [tripleQuotes, setTripleQuotes] = useState(props.settings.tripleQuotes); - const [isHistoryEnabled, setIsHistoryEnabled] = useState(props.settings.isHistoryEnabled); - const [isKeyboardShortcutsEnabled, setIsKeyboardShortcutsEnabled] = useState( - props.settings.isKeyboardShortcutsEnabled - ); - const [isAccessibilityOverlayEnabled, setIsAccessibilityOverlayEnabled] = useState( - props.settings.isAccessibilityOverlayEnabled - ); - - const autoCompleteCheckboxes = [ - { - id: 'fields', - label: i18n.translate('console.settingsPage.fieldsLabelText', { - defaultMessage: 'Fields', - }), - stateSetter: setFields, - }, - { - id: 'indices', - label: i18n.translate('console.settingsPage.indicesAndAliasesLabelText', { - defaultMessage: 'Indices and aliases', - }), - stateSetter: setIndices, - }, - { - id: 'templates', - label: i18n.translate('console.settingsPage.templatesLabelText', { - defaultMessage: 'Templates', - }), - stateSetter: setTemplates, - }, - { - id: 'dataStreams', - label: i18n.translate('console.settingsPage.dataStreamsLabelText', { - defaultMessage: 'Data streams', - }), - stateSetter: setDataStreams, - }, - ]; - - const checkboxIdToSelectedMap = { - fields, - indices, - templates, - dataStreams, - }; - - const onAutocompleteChange = (optionId: AutocompleteOptions) => { - const option = _.find(autoCompleteCheckboxes, (item) => item.id === optionId); - if (option) { - option.stateSetter(!checkboxIdToSelectedMap[optionId]); - } - }; - - function saveSettings() { - props.onSaveSettings({ - fontSize, - wrapMode, - autocomplete: { - fields, - indices, - templates, - dataStreams, - }, - polling, - pollInterval, - tripleQuotes, - isHistoryEnabled, - isKeyboardShortcutsEnabled, - isAccessibilityOverlayEnabled, - }); - } - - const onPollingIntervalChange = useCallback((value: string) => { - const sanitizedValue = parseInt(value, 10); - - setPolling(!!sanitizedValue); - setPollInterval(sanitizedValue); - }, []); - - const toggleKeyboardShortcuts = useCallback( - (isEnabled: boolean) => { - if (props.editorInstance) { - unregisterCommands(props.editorInstance); - } - - setIsKeyboardShortcutsEnabled(isEnabled); - }, - [props.editorInstance] - ); - - const toggleAccessibilityOverlay = useCallback( - (isEnabled: boolean) => setIsAccessibilityOverlayEnabled(isEnabled), - [] - ); - - const toggleSavingToHistory = useCallback( - (isEnabled: boolean) => setIsHistoryEnabled(isEnabled), - [] - ); - - // It only makes sense to show polling options if the user needs to fetch any data. - const pollingFields = - fields || indices || templates || dataStreams ? ( - - - } - helpText={ - - } - > - - - - { - // Only refresh the currently selected settings. - props.refreshAutocompleteSettings({ - fields, - indices, - templates, - dataStreams, - }); - }} - > - - - - ) : undefined; - - return ( - - - - - - - - - - } - > - { - const val = parseInt(e.target.value, 10); - if (!val) return; - setFontSize(val); - }} - /> - - - - - } - onChange={(e) => setWrapMode(e.target.checked)} - /> - - - - } - > - - } - onChange={(e) => setTripleQuotes(e.target.checked)} - /> - - - - } - > - - } - onChange={(e) => toggleSavingToHistory(e.target.checked)} - /> - - - - } - > - - } - onChange={(e) => toggleKeyboardShortcuts(e.target.checked)} - /> - - - - } - > - - } - onChange={(e) => toggleAccessibilityOverlay(e.target.checked)} - /> - - - - } - > - { - const { stateSetter, ...rest } = opts; - return rest; - })} - idToSelectedMap={checkboxIdToSelectedMap} - onChange={(e: unknown) => { - onAutocompleteChange(e as AutocompleteOptions); - }} - /> - - - {pollingFields} - - - - - - - - - - - - - ); -}; diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/index.ts b/src/plugins/console/public/application/components/shortcuts_popover/index.ts similarity index 84% rename from src/plugins/console/public/application/containers/editor/legacy/console_editor/index.ts rename to src/plugins/console/public/application/components/shortcuts_popover/index.ts index 3df103aa3be70..67b91a4e6dffb 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/index.ts +++ b/src/plugins/console/public/application/components/shortcuts_popover/index.ts @@ -7,5 +7,4 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export { Editor } from './editor'; -export { EditorOutput } from './editor_output'; +export { ShortcutsPopover } from './shortcuts_popover'; diff --git a/src/plugins/console/public/application/components/shortcuts_popover/keys.tsx b/src/plugins/console/public/application/components/shortcuts_popover/keys.tsx new file mode 100644 index 0000000000000..9a4a0329cbf5c --- /dev/null +++ b/src/plugins/console/public/application/components/shortcuts_popover/keys.tsx @@ -0,0 +1,69 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiIcon } from '@elastic/eui'; + +export const KEYS = { + keyCtrlCmd: i18n.translate('console.shortcutKeys.keyCtrlCmd', { + defaultMessage: 'Ctrl/Cmd', + }), + keyEnter: i18n.translate('console.shortcutKeys.keyEnter', { + defaultMessage: 'Enter', + }), + keyAltOption: i18n.translate('console.shortcutKeys.keyAltOption', { + defaultMessage: 'Alt/Option', + }), + keyOption: i18n.translate('console.shortcutKeys.keyOption', { + defaultMessage: 'Option', + }), + keyShift: i18n.translate('console.shortcutKeys.keyShift', { + defaultMessage: 'Shift', + }), + keyTab: i18n.translate('console.shortcutKeys.keyTab', { + defaultMessage: 'Tab', + }), + keyEsc: i18n.translate('console.shortcutKeys.keyEsc', { + defaultMessage: 'Esc', + }), + keyUp: ( + + ), + keyDown: ( + + ), + keySlash: i18n.translate('console.shortcutKeys.keySlash', { + defaultMessage: '/', + }), + keySpace: i18n.translate('console.shortcutKeys.keySpace', { + defaultMessage: 'Space', + }), + keyI: i18n.translate('console.shortcutKeys.keyI', { + defaultMessage: 'I', + }), + keyO: i18n.translate('console.shortcutKeys.keyO', { + defaultMessage: 'O', + }), + keyL: i18n.translate('console.shortcutKeys.keyL', { + defaultMessage: 'L', + }), +}; diff --git a/src/plugins/console/public/application/components/shortcuts_popover/shortcut_line.tsx b/src/plugins/console/public/application/components/shortcuts_popover/shortcut_line.tsx new file mode 100644 index 0000000000000..a57c256ce3ce5 --- /dev/null +++ b/src/plugins/console/public/application/components/shortcuts_popover/shortcut_line.tsx @@ -0,0 +1,65 @@ +/* + * 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 { EuiCode, EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; + +interface ShortcutLineFlexItemProps { + id: string; + description: string; + keys: any[]; + alternativeKeys?: any[]; +} + +const renderKeys = (keys: string[]) => { + return keys.map((key, index) => ( + + {index > 0 && ' + '} + {key} + + )); +}; + +export const ShortcutLineFlexItem = ({ + id, + description, + keys, + alternativeKeys, +}: ShortcutLineFlexItemProps) => { + return ( + + + + + {i18n.translate('console.shortcutDescription.' + id, { + defaultMessage: description, + })} + + + + + {renderKeys(keys)} + {alternativeKeys && ( + <> + + {' '} + {i18n.translate('console.shortcuts.alternativeKeysOrDivider', { + defaultMessage: 'or', + })}{' '} + + {renderKeys(alternativeKeys)} + + )} + + + + + ); +}; diff --git a/src/plugins/console/public/application/components/shortcuts_popover/shortcuts_popover.tsx b/src/plugins/console/public/application/components/shortcuts_popover/shortcuts_popover.tsx new file mode 100644 index 0000000000000..9ceaf13dc5dba --- /dev/null +++ b/src/plugins/console/public/application/components/shortcuts_popover/shortcuts_popover.tsx @@ -0,0 +1,114 @@ +/* + * 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 React from 'react'; +import { EuiPopover, EuiTitle, EuiHorizontalRule, EuiFlexGroup, EuiSpacer } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ShortcutLineFlexItem } from './shortcut_line'; +import { KEYS } from './keys'; + +interface ShortcutsPopoverProps { + button: any; + isOpen: boolean; + closePopover: () => void; +} + +export const ShortcutsPopover = ({ button, isOpen, closePopover }: ShortcutsPopoverProps) => { + return ( + + +
+ {i18n.translate('console.shortcuts.navigationShortcutsSubtitle', { + defaultMessage: 'Navigation shortcuts', + })} +
+
+ + + + + + + +
+ {i18n.translate('console.shortcuts.requestShortcutsSubtitle', { + defaultMessage: 'Request shortcuts', + })} +
+
+ + + + + + + + + + + +
+ {i18n.translate('console.shortcuts.autocompleteShortcutsSubtitle', { + defaultMessage: 'Autocomplete menu shortcuts', + })} +
+
+ + + + + + +
+ ); +}; diff --git a/src/plugins/console/public/application/components/top_nav_menu.tsx b/src/plugins/console/public/application/components/top_nav_menu.tsx index cddbe95f8f1b5..2309c01afc18a 100644 --- a/src/plugins/console/public/application/components/top_nav_menu.tsx +++ b/src/plugins/console/public/application/components/top_nav_menu.tsx @@ -9,6 +9,7 @@ import React, { FunctionComponent } from 'react'; import { EuiTabs, EuiTab } from '@elastic/eui'; +import { ConsoleTourStep, ConsoleTourStepProps } from './console_tour_step'; export interface TopNavMenuItem { id: string; @@ -16,28 +17,42 @@ export interface TopNavMenuItem { description: string; onClick: () => void; testId: string; + isSelected: boolean; + tourStep?: number; } interface Props { disabled?: boolean; items: TopNavMenuItem[]; + tourStepProps: ConsoleTourStepProps[]; } -export const TopNavMenu: FunctionComponent = ({ items, disabled }) => { +export const TopNavMenu: FunctionComponent = ({ items, disabled, tourStepProps }) => { return ( - + {items.map((item, idx) => { - return ( + const tab = ( {item.label} ); + + if (item.tourStep) { + return ( + + {tab} + + ); + } + + return tab; })} ); diff --git a/src/plugins/console/public/application/components/variables/index.ts b/src/plugins/console/public/application/components/variables/index.ts index 108befce39f51..8051ed2ddaa93 100644 --- a/src/plugins/console/public/application/components/variables/index.ts +++ b/src/plugins/console/public/application/components/variables/index.ts @@ -7,5 +7,25 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export * from './variables_flyout'; -export * from './utils'; +import React from 'react'; +import { withSuspense } from '@kbn/shared-ux-utility'; + +export { type Props } from './variables_editor'; +export { type DevToolsVariable } from './types'; + +/** + * The Lazily-loaded `VariablesEditorLazy` component. Consumers should use `React.Suspense` or + * the withSuspense` HOC to load this component. + */ +export const VariablesEditorLazy = React.lazy(() => + import('./variables_editor').then(({ VariablesEditor }) => ({ + default: VariablesEditor, + })) +); + +/** + * A `VariablesEditor` component that is wrapped by the `withSuspense` HOC. This component can + * be used directly by consumers and will load the `VariablesEditorLazy` component lazily with + * a predefined fallback and error boundary. + */ +export const VariablesEditor = withSuspense(VariablesEditorLazy); diff --git a/src/plugins/console/public/application/components/variables/types.ts b/src/plugins/console/public/application/components/variables/types.ts new file mode 100644 index 0000000000000..40a2ac86c361f --- /dev/null +++ b/src/plugins/console/public/application/components/variables/types.ts @@ -0,0 +1,14 @@ +/* + * 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". + */ + +export interface DevToolsVariable { + id: string; + name: string; + value: string; +} diff --git a/src/plugins/console/public/application/components/variables/utils.ts b/src/plugins/console/public/application/components/variables/utils.ts index 50664e0a99cf6..b636b9b0a6266 100644 --- a/src/plugins/console/public/application/components/variables/utils.ts +++ b/src/plugins/console/public/application/components/variables/utils.ts @@ -7,38 +7,18 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { v4 as uuidv4 } from 'uuid'; -import type { DevToolsVariable } from './variables_flyout'; +import { type DevToolsVariable } from './types'; -export const editVariable = ( - name: string, - value: string, - id: string, - variables: DevToolsVariable[] -) => { - const index = variables.findIndex((v) => v.id === id); - - if (index === -1) { - return variables; - } - - return [ - ...variables.slice(0, index), - { ...variables[index], [name]: value }, - ...variables.slice(index + 1), - ]; +export const editVariable = (newVariable: DevToolsVariable, variables: DevToolsVariable[]) => { + return variables.map((variable: DevToolsVariable) => { + return variable.id === newVariable.id ? newVariable : variable; + }); }; export const deleteVariable = (variables: DevToolsVariable[], id: string) => { return variables.filter((v) => v.id !== id); }; -export const generateEmptyVariableField = (): DevToolsVariable => ({ - id: uuidv4(), - name: '', - value: '', -}); - export const isValidVariableName = (name: string) => { /* * MUST avoid characters that get URL-encoded, because they'll result in unusable variable names. diff --git a/src/plugins/console/public/application/components/variables/variables_editor.tsx b/src/plugins/console/public/application/components/variables/variables_editor.tsx new file mode 100644 index 0000000000000..197fdec7f49c7 --- /dev/null +++ b/src/plugins/console/public/application/components/variables/variables_editor.tsx @@ -0,0 +1,255 @@ +/* + * 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 React, { useState, useCallback, useEffect, useRef } from 'react'; +import { BehaviorSubject } from 'rxjs'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { + EuiTitle, + EuiButton, + EuiBasicTable, + EuiButtonIcon, + EuiSpacer, + EuiText, + EuiCode, + useGeneratedHtmlId, + EuiConfirmModal, + type EuiBasicTableColumn, +} from '@elastic/eui'; + +import { VariableEditorForm } from './variables_editor_form'; +import * as utils from './utils'; +import { type DevToolsVariable } from './types'; + +export interface Props { + onSaveVariables: (newVariables: DevToolsVariable[]) => void; + variables: []; +} + +export const VariablesEditor = (props: Props) => { + const isMounted = useRef(false); + const [isAddingVariable, setIsAddingVariable] = useState(false); + const [deleteModalForVariable, setDeleteModalForVariable] = useState(null); + const [variables, setVariables] = useState(props.variables); + const deleteModalTitleId = useGeneratedHtmlId(); + + // Use a ref to persist the BehaviorSubject across renders + const itemIdToExpandedRowMap$ = useRef(new BehaviorSubject>({})); + // Subscribe to the BehaviorSubject and update local state on change + const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState< + Record + >({}); + // Clear the expanded row map and dispose all the expanded rows + const collapseExpandedRows = () => itemIdToExpandedRowMap$.current.next({}); + + // Subscribe to the BehaviorSubject on mount + useEffect(() => { + const subscription = itemIdToExpandedRowMap$.current.subscribe(setItemIdToExpandedRowMap); + return () => subscription.unsubscribe(); + }, []); + + // Always save variables when they change + useEffect(() => { + if (isMounted.current) { + props.onSaveVariables(variables); + } else { + isMounted.current = true; + } + }, [variables, props]); + + const toggleDetails = (variableId: string) => { + const currentMap = itemIdToExpandedRowMap$.current.getValue(); + let itemIdToExpandedRowMapValues = { ...currentMap }; + + if (itemIdToExpandedRowMapValues[variableId]) { + delete itemIdToExpandedRowMapValues[variableId]; + } else { + // Always close the add variable form when editing a variable + setIsAddingVariable(false); + // We only allow one expanded row at a time + itemIdToExpandedRowMapValues = {}; + itemIdToExpandedRowMapValues[variableId] = ( + { + const updatedVariables = utils.editVariable(data, variables); + setVariables(updatedVariables); + collapseExpandedRows(); + }} + onCancel={() => { + collapseExpandedRows(); + }} + defaultValue={variables.find((v) => v.id === variableId)} + /> + ); + } + + // Update the BehaviorSubject with the new state + itemIdToExpandedRowMap$.current.next(itemIdToExpandedRowMapValues); + }; + + const deleteVariable = useCallback( + (id: string) => { + const updatedVariables = utils.deleteVariable(variables, id); + setVariables(updatedVariables); + setDeleteModalForVariable(null); + }, + [variables, setDeleteModalForVariable] + ); + + const onAddVariable = (data: DevToolsVariable) => { + setVariables((v: DevToolsVariable[]) => [...v, data]); + setIsAddingVariable(false); + }; + + const columns: Array> = [ + { + field: 'name', + name: i18n.translate('console.variablesPage.variablesTable.columns.variableHeader', { + defaultMessage: 'Variable name', + }), + 'data-test-subj': 'variableNameCell', + render: (name: string) => { + return {`\$\{${name}\}`}; + }, + }, + { + field: 'value', + name: i18n.translate('console.variablesPage.variablesTable.columns.valueHeader', { + defaultMessage: 'Value', + }), + 'data-test-subj': 'variableValueCell', + render: (value: string) => {value}, + }, + { + field: 'id', + name: '', + width: '40px', + isExpander: true, + render: (id: string, variable: DevToolsVariable) => { + const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; + + return ( + toggleDetails(id)} + data-test-subj="variableEditButton" + /> + ); + }, + }, + { + field: 'id', + name: '', + width: '40px', + render: (id: string, variable: DevToolsVariable) => ( + setDeleteModalForVariable(id)} + data-test-subj="variablesRemoveButton" + /> + ), + }, + ]; + + return ( + <> + +

+ +

+
+ + +

+ +

+
+ + + + + {isAddingVariable && ( + setIsAddingVariable(false)} /> + )} + + + +
+ { + setIsAddingVariable(true); + collapseExpandedRows(); + }} + disabled={isAddingVariable} + > + + +
+ + {deleteModalForVariable && ( + setDeleteModalForVariable(null)} + onConfirm={() => deleteVariable(deleteModalForVariable)} + cancelButtonText={i18n.translate('console.variablesPage.deleteModal.cancelButtonText', { + defaultMessage: 'Cancel', + })} + confirmButtonText={i18n.translate('console.variablesPage.deleteModal.confirmButtonText', { + defaultMessage: 'Delete variable', + })} + buttonColor="danger" + > +

+ +

+
+ )} + + ); +}; diff --git a/src/plugins/console/public/application/components/variables/variables_editor_form.tsx b/src/plugins/console/public/application/components/variables/variables_editor_form.tsx new file mode 100644 index 0000000000000..446aaab0d4e94 --- /dev/null +++ b/src/plugins/console/public/application/components/variables/variables_editor_form.tsx @@ -0,0 +1,184 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { v4 as uuidv4 } from 'uuid'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { + EuiTitle, + EuiFlexGroup, + EuiFlexItem, + EuiButton, + EuiSpacer, + EuiPanel, + EuiButtonEmpty, +} from '@elastic/eui'; + +import { + useForm, + Form, + UseField, + TextField, + FieldConfig, + fieldValidators, + FormConfig, + ValidationFuncArg, +} from '../../../shared_imports'; + +import { type DevToolsVariable } from './types'; +import { isValidVariableName } from './utils'; + +export interface VariableEditorFormProps { + onSubmit: (data: DevToolsVariable) => void; + onCancel: () => void; + defaultValue?: DevToolsVariable; + title?: string; +} + +const fieldsConfig: Record = { + variableName: { + label: i18n.translate('console.variablesPage.form.variableNameFieldLabel', { + defaultMessage: 'Variable name', + }), + validations: [ + { + validator: ({ value }: ValidationFuncArg) => { + if (value.trim() === '') { + return { + message: i18n.translate('console.variablesPage.form.variableNameRequiredLabel', { + defaultMessage: 'This is a required field', + }), + }; + } + + if (!isValidVariableName(value)) { + return { + message: i18n.translate('console.variablesPage.form.variableNameInvalidLabel', { + defaultMessage: 'Only letters, numbers and underscores are allowed', + }), + }; + } + }, + }, + ], + }, + value: { + label: i18n.translate('console.variablesPage.form.valueFieldLabel', { + defaultMessage: 'Value', + }), + validations: [ + { + validator: fieldValidators.emptyField( + i18n.translate('console.variablesPage.form.valueRequiredLabel', { + defaultMessage: 'Value is required', + }) + ), + }, + ], + }, +}; + +export const VariableEditorForm = (props: VariableEditorFormProps) => { + const onSubmit: FormConfig['onSubmit'] = async (data, isValid) => { + if (isValid) { + props.onSubmit({ + ...props.defaultValue, + ...data, + ...(props.defaultValue ? {} : { id: uuidv4() }), + } as DevToolsVariable); + } + }; + + const { form } = useForm({ onSubmit, defaultValue: props.defaultValue }); + + return ( + <> + + +

+ {props.title ?? ( + + )} +

+
+ + + + + + + + + + + + props.onCancel()}> + + + + + + + + + + + +
+ + ); +}; diff --git a/src/plugins/console/public/application/components/variables/variables_flyout.tsx b/src/plugins/console/public/application/components/variables/variables_flyout.tsx deleted file mode 100644 index 9211d2a7e524f..0000000000000 --- a/src/plugins/console/public/application/components/variables/variables_flyout.tsx +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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 React, { useState, useCallback, ChangeEvent, FormEvent } from 'react'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { - EuiFlyout, - EuiFlyoutHeader, - EuiTitle, - EuiFlyoutBody, - EuiFlyoutFooter, - EuiFlexGroup, - EuiFlexItem, - EuiButton, - EuiButtonEmpty, - EuiBasicTable, - EuiFieldText, - useGeneratedHtmlId, - EuiForm, - EuiFormRow, - EuiButtonIcon, - EuiSpacer, - EuiText, - type EuiBasicTableColumn, -} from '@elastic/eui'; - -import * as utils from './utils'; - -export interface DevToolsVariablesFlyoutProps { - onClose: () => void; - onSaveVariables: (newVariables: DevToolsVariable[]) => void; - variables: []; -} - -export interface DevToolsVariable { - id: string; - name: string; - value: string; -} - -export const DevToolsVariablesFlyout = (props: DevToolsVariablesFlyoutProps) => { - const [variables, setVariables] = useState(props.variables); - const formId = useGeneratedHtmlId({ prefix: '__console' }); - - const addNewVariable = useCallback(() => { - setVariables((v) => [...v, utils.generateEmptyVariableField()]); - }, []); - - const deleteVariable = useCallback( - (id: string) => { - const updatedVariables = utils.deleteVariable(variables, id); - setVariables(updatedVariables); - }, - [variables] - ); - - const onSubmit = useCallback( - (e: FormEvent) => { - e.preventDefault(); - props.onSaveVariables(variables.filter(({ name, value }) => name.trim() && value)); - }, - [props, variables] - ); - - const onChange = useCallback( - (event: ChangeEvent, id: string) => { - const { name, value } = event.target; - const editedVariables = utils.editVariable(name, value, id, variables); - setVariables(editedVariables); - }, - [variables] - ); - - const columns: Array> = [ - { - field: 'name', - name: i18n.translate('console.variablesPage.variablesTable.columns.variableHeader', { - defaultMessage: 'Variable name', - }), - render: (name, { id }) => { - const isInvalid = !utils.isValidVariableName(name); - return ( - , - ]} - fullWidth={true} - css={{ flexGrow: 1 }} - > - onChange(e, id)} - isInvalid={isInvalid} - fullWidth={true} - aria-label={i18n.translate( - 'console.variablesPage.variablesTable.variableInput.ariaLabel', - { - defaultMessage: 'Variable name', - } - )} - /> - - ); - }, - }, - { - field: 'value', - name: i18n.translate('console.variablesPage.variablesTable.columns.valueHeader', { - defaultMessage: 'Value', - }), - render: (value, { id }) => ( - onChange(e, id)} - value={value} - aria-label={i18n.translate('console.variablesPage.variablesTable.valueInput.ariaLabel', { - defaultMessage: 'Variable value', - })} - /> - ), - }, - { - field: 'id', - name: '', - width: '5%', - render: (id: string) => ( - deleteVariable(id)} - data-test-subj="variablesRemoveButton" - /> - ), - }, - ]; - - return ( - - - -

- -

-
- - -

- - - - ), - }} - /> -

-
-
- - - - - - - - - - - - - - - - - - - - - - -
- ); -}; diff --git a/src/plugins/console/public/application/components/welcome_panel.tsx b/src/plugins/console/public/application/components/welcome_panel.tsx deleted file mode 100644 index 967d173821e65..0000000000000 --- a/src/plugins/console/public/application/components/welcome_panel.tsx +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 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 React from 'react'; -import { FormattedMessage } from '@kbn/i18n-react'; - -import { - EuiFlyout, - EuiFlyoutHeader, - EuiFlyoutBody, - EuiTitle, - EuiButton, - EuiText, - EuiFlyoutFooter, - EuiCode, -} from '@elastic/eui'; -import EditorExample from './editor_example'; -import * as examples from '../../../common/constants/welcome_panel'; - -interface Props { - onDismiss: () => void; -} - -export function WelcomePanel(props: Props) { - return ( - - - -

- -

-
-
- - -

- -

- -

- kbn:, - }} - /> -

- -

- -

-

- -

- - -

- -

-

- #, - doubleSlash: //, - slashAsterisk: /*, - asteriskSlash: */, - }} - /> -

- -

- -

-

- ${variableName}, - }} - /> -

- -
    -
  1. - Variables, - }} - /> -
  2. -
  3. - -
  4. -
- -
-
- - - - - -
- ); -} diff --git a/src/plugins/console/public/application/containers/config/config.tsx b/src/plugins/console/public/application/containers/config/config.tsx new file mode 100644 index 0000000000000..503fdbd9c7354 --- /dev/null +++ b/src/plugins/console/public/application/containers/config/config.tsx @@ -0,0 +1,47 @@ +/* + * 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 React from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiSpacer } from '@elastic/eui'; + +import { Settings } from './settings'; +import { Variables } from './variables'; + +export interface Props { + isVerticalLayout: boolean; +} + +export function Config({ isVerticalLayout }: Props) { + return ( + + + + + + + + + + + + + ); +} diff --git a/src/plugins/console/public/application/containers/editor/utilities/index.ts b/src/plugins/console/public/application/containers/config/index.ts similarity index 93% rename from src/plugins/console/public/application/containers/editor/utilities/index.ts rename to src/plugins/console/public/application/containers/config/index.ts index 7561f02006235..b582701ab4481 100644 --- a/src/plugins/console/public/application/containers/editor/utilities/index.ts +++ b/src/plugins/console/public/application/containers/config/index.ts @@ -7,4 +7,4 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export * from './output_data'; +export { Config } from './config'; diff --git a/src/plugins/console/public/application/containers/settings.tsx b/src/plugins/console/public/application/containers/config/settings.tsx similarity index 88% rename from src/plugins/console/public/application/containers/settings.tsx rename to src/plugins/console/public/application/containers/config/settings.tsx index 2c952f4c5d7f9..d5e10f4d2c337 100644 --- a/src/plugins/console/public/application/containers/settings.tsx +++ b/src/plugins/console/public/application/containers/config/settings.tsx @@ -9,11 +9,10 @@ import React from 'react'; -import { AutocompleteOptions, DevToolsSettingsModal } from '../components'; +import { AutocompleteOptions, SettingsEditor } from '../../components/settings'; -import { useServicesContext, useEditorActionContext } from '../contexts'; -import { DevToolsSettings, Settings as SettingsService } from '../../services'; -import type { SenseEditor } from '../models'; +import { useServicesContext, useEditorActionContext } from '../../contexts'; +import { DevToolsSettings, Settings as SettingsService } from '../../../services'; const getAutocompleteDiff = ( newSettings: DevToolsSettings, @@ -25,12 +24,7 @@ const getAutocompleteDiff = ( }) as AutocompleteOptions[]; }; -export interface Props { - onClose: () => void; - editorInstance: SenseEditor | null; -} - -export function Settings({ onClose, editorInstance }: Props) { +export function Settings() { const { services: { settings, autocompleteInfo }, } = useServicesContext(); @@ -92,18 +86,15 @@ export function Settings({ onClose, editorInstance }: Props) { type: 'updateSettings', payload: newSettings, }); - onClose(); }; return ( - refreshAutocompleteSettings(settings, selectedSettings) } settings={settings.toJSON()} - editorInstance={editorInstance} /> ); } diff --git a/src/plugins/console/public/application/containers/variables.tsx b/src/plugins/console/public/application/containers/config/variables.tsx similarity index 66% rename from src/plugins/console/public/application/containers/variables.tsx rename to src/plugins/console/public/application/containers/config/variables.tsx index 54e191d04a9de..32b9615f529aa 100644 --- a/src/plugins/console/public/application/containers/variables.tsx +++ b/src/plugins/console/public/application/containers/config/variables.tsx @@ -8,27 +8,22 @@ */ import React from 'react'; -import { DevToolsVariablesFlyout, DevToolsVariable } from '../components'; -import { useServicesContext } from '../contexts'; -import { StorageKeys } from '../../services'; -import { DEFAULT_VARIABLES } from '../../../common/constants'; +import { type DevToolsVariable, VariablesEditor } from '../../components/variables'; +import { useServicesContext } from '../../contexts'; +import { StorageKeys } from '../../../services'; +import { DEFAULT_VARIABLES } from '../../../../common/constants'; -interface VariablesProps { - onClose: () => void; -} - -export function Variables({ onClose }: VariablesProps) { +export function Variables() { const { services: { storage }, } = useServicesContext(); const onSaveVariables = (newVariables: DevToolsVariable[]) => { storage.set(StorageKeys.VARIABLES, newVariables); - onClose(); }; + return ( - diff --git a/src/plugins/console/public/application/containers/console_history/console_history.tsx b/src/plugins/console/public/application/containers/console_history/console_history.tsx deleted file mode 100644 index 220e0b6a998aa..0000000000000 --- a/src/plugins/console/public/application/containers/console_history/console_history.tsx +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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 React, { useCallback, useEffect, useMemo, useState, useRef } from 'react'; -import { i18n } from '@kbn/i18n'; -import { memoize } from 'lodash'; -import moment from 'moment'; -import { - keys, - EuiSpacer, - EuiIcon, - EuiTitle, - EuiFlexItem, - EuiFlexGroup, - EuiButtonEmpty, - EuiButton, -} from '@elastic/eui'; - -import { useServicesContext } from '../../contexts'; -import { HistoryViewer } from './history_viewer'; -import { HistoryViewer as HistoryViewerMonaco } from './history_viewer_monaco'; -import { useEditorReadContext } from '../../contexts/editor_context'; -import { useRestoreRequestFromHistory } from '../../hooks'; - -interface Props { - close: () => void; -} - -const CHILD_ELEMENT_PREFIX = 'historyReq'; - -export function ConsoleHistory({ close }: Props) { - const { - services: { history }, - config: { isMonacoEnabled }, - } = useServicesContext(); - - const { settings: readOnlySettings } = useEditorReadContext(); - - const [requests, setPastRequests] = useState(history.getHistory()); - - const clearHistory = useCallback(() => { - history.clearHistory(); - setPastRequests(history.getHistory()); - }, [history]); - - const listRef = useRef(null); - - const [viewingReq, setViewingReq] = useState(null); - const [selectedIndex, setSelectedIndex] = useState(0); - const selectedReq = useRef(null); - - const describeReq = useMemo(() => { - const _describeReq = (req: { endpoint: string; time: string }) => { - const endpoint = req.endpoint; - const date = moment(req.time); - - let formattedDate = date.format('MMM D'); - if (date.diff(moment(), 'days') > -7) { - formattedDate = date.fromNow(); - } - - return `${endpoint} (${formattedDate})`; - }; - - (_describeReq as any).cache = new WeakMap(); - - return memoize(_describeReq); - }, []); - - const scrollIntoView = useCallback((idx: number) => { - const activeDescendant = listRef.current!.querySelector(`#${CHILD_ELEMENT_PREFIX}${idx}`); - if (activeDescendant) { - activeDescendant.scrollIntoView(); - } - }, []); - - const initialize = useCallback(() => { - const nextSelectedIndex = 0; - (describeReq as any).cache = new WeakMap(); - setViewingReq(requests[nextSelectedIndex]); - selectedReq.current = requests[nextSelectedIndex]; - setSelectedIndex(nextSelectedIndex); - scrollIntoView(nextSelectedIndex); - }, [describeReq, requests, scrollIntoView]); - - const clear = () => { - clearHistory(); - initialize(); - }; - - const restoreRequestFromHistory = useRestoreRequestFromHistory(isMonacoEnabled); - - useEffect(() => { - initialize(); - }, [initialize]); - - useEffect(() => { - const done = history.change(setPastRequests); - return () => done(); - }, [history]); - - /* eslint-disable jsx-a11y/no-noninteractive-element-to-interactive-role,jsx-a11y/click-events-have-key-events */ - return ( - <> -
- -

{i18n.translate('console.historyPage.pageTitle', { defaultMessage: 'History' })}

-
- -
-
    { - if (ev.key === keys.ENTER) { - restoreRequestFromHistory(selectedReq.current); - return; - } - - let currentIdx = selectedIndex; - - if (ev.key === keys.ARROW_UP) { - ev.preventDefault(); - --currentIdx; - } else if (ev.key === keys.ARROW_DOWN) { - ev.preventDefault(); - ++currentIdx; - } - - const nextSelectedIndex = Math.min(Math.max(0, currentIdx), requests.length - 1); - - setViewingReq(requests[nextSelectedIndex]); - selectedReq.current = requests[nextSelectedIndex]; - setSelectedIndex(nextSelectedIndex); - scrollIntoView(nextSelectedIndex); - }} - role="listbox" - className="list-group conHistory__reqs" - tabIndex={0} - aria-activedescendant={`${CHILD_ELEMENT_PREFIX}${selectedIndex}`} - aria-label={i18n.translate('console.historyPage.requestListAriaLabel', { - defaultMessage: 'History of sent requests', - })} - > - {requests.map((req, idx) => { - const reqDescription = describeReq(req); - const isSelected = viewingReq === req; - return ( - // Ignore a11y issues on li's -
  • { - setViewingReq(req); - selectedReq.current = req; - setSelectedIndex(idx); - }} - role="option" - onMouseEnter={() => setViewingReq(req)} - onMouseLeave={() => setViewingReq(selectedReq.current)} - onDoubleClick={() => restoreRequestFromHistory(selectedReq.current)} - aria-label={i18n.translate('console.historyPage.itemOfRequestListAriaLabel', { - defaultMessage: 'Request: {historyItem}', - values: { historyItem: reqDescription }, - })} - aria-selected={isSelected} - > - {reqDescription} - - - -
  • - ); - })} -
- -
- - {isMonacoEnabled ? ( - - ) : ( - - )} -
- - - - - - clear()} - > - {i18n.translate('console.historyPage.clearHistoryButtonLabel', { - defaultMessage: 'Clear', - })} - - - - - - - close()} - > - {i18n.translate('console.historyPage.closehistoryButtonLabel', { - defaultMessage: 'Close', - })} - - - - - restoreRequestFromHistory(selectedReq.current)} - > - {i18n.translate('console.historyPage.applyHistoryButtonLabel', { - defaultMessage: 'Apply', - })} - - - - - -
- - - ); -} diff --git a/src/plugins/console/public/application/containers/console_history/history_viewer.tsx b/src/plugins/console/public/application/containers/console_history/history_viewer.tsx deleted file mode 100644 index 92d58e557cd89..0000000000000 --- a/src/plugins/console/public/application/containers/console_history/history_viewer.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 React, { useEffect, useRef } from 'react'; -import { i18n } from '@kbn/i18n'; - -import { DevToolsSettings } from '../../../services'; -import { subscribeResizeChecker } from '../editor/legacy/subscribe_console_resize_checker'; - -import * as InputMode from '../../models/legacy_core_editor/mode/input'; -const inputMode = new InputMode.Mode(); -import * as editor from '../../models/legacy_core_editor'; -import { applyCurrentSettings } from '../editor/legacy/console_editor/apply_editor_settings'; -import { formatRequestBodyDoc } from '../../../lib/utils'; - -interface Props { - settings: DevToolsSettings; - req: { method: string; endpoint: string; data: string; time: string } | null; -} - -export function HistoryViewer({ settings, req }: Props) { - const divRef = useRef(null); - const viewerRef = useRef(null); - - useEffect(() => { - const viewer = editor.createReadOnlyAceEditor(divRef.current!); - viewerRef.current = viewer; - const unsubscribe = subscribeResizeChecker(divRef.current!, viewer); - return () => unsubscribe(); - }, []); - - useEffect(() => { - applyCurrentSettings(viewerRef.current!, settings); - }, [settings]); - - if (viewerRef.current) { - const { current: viewer } = viewerRef; - if (req) { - const indent = true; - const formattedData = req.data ? formatRequestBodyDoc([req.data], indent).data : ''; - const s = req.method + ' ' + req.endpoint + '\n' + formattedData; - viewer.update(s, inputMode); - viewer.clearSelection(); - } else { - viewer.update( - i18n.translate('console.historyPage.noHistoryTextMessage', { - defaultMessage: 'No history available', - }), - inputMode - ); - } - } - - return
; -} diff --git a/src/plugins/console/public/application/containers/editor/monaco/components/context_menu/context_menu.tsx b/src/plugins/console/public/application/containers/editor/components/context_menu/context_menu.tsx similarity index 90% rename from src/plugins/console/public/application/containers/editor/monaco/components/context_menu/context_menu.tsx rename to src/plugins/console/public/application/containers/editor/components/context_menu/context_menu.tsx index 34001018900b5..3860f0b7bc704 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/components/context_menu/context_menu.tsx +++ b/src/plugins/console/public/application/containers/editor/components/context_menu/context_menu.tsx @@ -9,7 +9,7 @@ import React, { useState } from 'react'; import { - EuiIcon, + EuiButtonIcon, EuiContextMenuPanel, EuiContextMenuItem, EuiPopover, @@ -18,16 +18,17 @@ import { EuiLink, EuiLoadingSpinner, } from '@elastic/eui'; +import { css } from '@emotion/react'; import { NotificationsSetup } from '@kbn/core/public'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { LanguageSelectorModal } from './language_selector_modal'; -import { convertRequestToLanguage } from '../../../../../../services'; +import { convertRequestToLanguage } from '../../../../../services'; import type { EditorRequest } from '../../types'; -import { useServicesContext } from '../../../../../contexts'; -import { StorageKeys } from '../../../../../../services'; -import { DEFAULT_LANGUAGE, AVAILABLE_LANGUAGES } from '../../../../../../../common/constants'; +import { useServicesContext } from '../../../../contexts'; +import { StorageKeys } from '../../../../../services'; +import { DEFAULT_LANGUAGE, AVAILABLE_LANGUAGES } from '../../../../../../common/constants'; interface Props { getRequests: () => Promise; @@ -36,6 +37,20 @@ interface Props { notifications: NotificationsSetup; } +const styles = { + // Remove the default underline on hover for the context menu items since it + // will also be applied to the language selector button, and apply it only to + // the text in the context menu item. + button: css` + &:hover { + text-decoration: none !important; + .languageSelector { + text-decoration: underline; + } + } + `, +}; + const DELAY_FOR_HIDING_SPINNER = 500; const getLanguageLabelByValue = (value: string) => { @@ -158,15 +173,15 @@ export const ContextMenu = ({ }; const button = ( - setIsPopoverOpen((prev) => !prev)} data-test-subj="toggleConsoleMenu" aria-label={i18n.translate('console.requestOptionsButtonAriaLabel', { defaultMessage: 'Request options', })} - > - - + iconType="boxesVertical" + iconSize="s" + /> ); const items = [ @@ -187,10 +202,11 @@ export const ContextMenu = ({ onCopyAsSubmit(); }} icon="copyClipboard" + css={styles.button} > - + void; diff --git a/src/plugins/console/public/application/containers/editor/monaco/components/index.ts b/src/plugins/console/public/application/containers/editor/components/index.ts similarity index 100% rename from src/plugins/console/public/application/containers/editor/monaco/components/index.ts rename to src/plugins/console/public/application/containers/editor/components/index.ts diff --git a/src/plugins/console/public/application/containers/editor/editor.tsx b/src/plugins/console/public/application/containers/editor/editor.tsx index 3eff2d97b3499..c999deee78637 100644 --- a/src/plugins/console/public/application/containers/editor/editor.tsx +++ b/src/plugins/console/public/application/containers/editor/editor.tsx @@ -7,95 +7,283 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React, { useCallback, memo, useEffect, useState } from 'react'; +import React, { useRef, useCallback, memo, useEffect, useState } from 'react'; import { debounce } from 'lodash'; -import { EuiProgress } from '@elastic/eui'; +import { + EuiProgress, + EuiSplitPanel, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiResizableContainer, +} from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; -import { EditorContentSpinner } from '../../components'; -import { Panel, PanelsContainer } from '..'; -import { Editor as EditorUI, EditorOutput } from './legacy/console_editor'; +import { i18n } from '@kbn/i18n'; +import { TextObject } from '../../../../common/text_object'; + +import { + EditorContentSpinner, + OutputPanelEmptyState, + NetworkRequestStatusBar, +} from '../../components'; import { getAutocompleteInfo, StorageKeys } from '../../../services'; -import { useEditorReadContext, useServicesContext, useRequestReadContext } from '../../contexts'; -import type { SenseEditor } from '../../models'; -import { MonacoEditor, MonacoEditorOutput } from './monaco'; +import { + useEditorReadContext, + useServicesContext, + useRequestReadContext, + useRequestActionContext, + useEditorActionContext, +} from '../../contexts'; +import { MonacoEditor } from './monaco_editor'; +import { MonacoEditorOutput } from './monaco_editor_output'; +import { getResponseWithMostSevereStatusCode } from '../../../lib/utils'; -const INITIAL_PANEL_WIDTH = 50; -const PANEL_MIN_WIDTH = '100px'; +const INITIAL_PANEL_SIZE = 50; +const PANEL_MIN_SIZE = '20%'; +const DEBOUNCE_DELAY = 500; interface Props { loading: boolean; - setEditorInstance: (instance: SenseEditor) => void; + isVerticalLayout: boolean; + inputEditorValue: string; + setInputEditorValue: (value: string) => void; } -export const Editor = memo(({ loading, setEditorInstance }: Props) => { - const { - services: { storage }, - config: { isMonacoEnabled } = {}, - } = useServicesContext(); - - const { currentTextObject } = useEditorReadContext(); - const { requestInFlight } = useRequestReadContext(); - - const [fetchingMappings, setFetchingMappings] = useState(false); - - useEffect(() => { - const subscription = getAutocompleteInfo().mapping.isLoading$.subscribe(setFetchingMappings); - return () => { - subscription.unsubscribe(); - }; - }, []); - - const [firstPanelWidth, secondPanelWidth] = storage.get(StorageKeys.WIDTH, [ - INITIAL_PANEL_WIDTH, - INITIAL_PANEL_WIDTH, - ]); - - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - const onPanelWidthChange = useCallback( - debounce((widths: number[]) => { - storage.set(StorageKeys.WIDTH, widths); - }, 300), - [] - ); - - if (!currentTextObject) return null; - - return ( - <> - {requestInFlight || fetchingMappings ? ( -
- -
- ) : null} - - - {loading ? ( - - ) : isMonacoEnabled ? ( - - ) : ( - - )} - - { + const { + services: { storage, objectStorageClient }, + } = useServicesContext(); + + const editorValueRef = useRef(null); + const { currentTextObject } = useEditorReadContext(); + const { + requestInFlight, + lastResult: { data: requestData, error: requestError }, + } = useRequestReadContext(); + + const dispatch = useRequestActionContext(); + const editorDispatch = useEditorActionContext(); + + const [fetchingAutocompleteEntities, setFetchingAutocompleteEntities] = useState(false); + + useEffect(() => { + const debouncedSetFechingAutocompleteEntities = debounce( + setFetchingAutocompleteEntities, + DEBOUNCE_DELAY + ); + const subscription = getAutocompleteInfo().isLoading$.subscribe( + debouncedSetFechingAutocompleteEntities + ); + + return () => { + subscription.unsubscribe(); + debouncedSetFechingAutocompleteEntities.cancel(); + }; + }, []); + + const [firstPanelSize, secondPanelSize] = storage.get(StorageKeys.SIZE, [ + INITIAL_PANEL_SIZE, + INITIAL_PANEL_SIZE, + ]); + + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + const onPanelSizeChange = useCallback( + debounce((sizes) => { + storage.set(StorageKeys.SIZE, Object.values(sizes)); + }, 300), + [] + ); + + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + const debouncedUpdateLocalStorageValue = useCallback( + debounce((textObject: TextObject) => { + editorValueRef.current = textObject; + objectStorageClient.text.update(textObject); + }, DEBOUNCE_DELAY), + [] + ); + + useEffect(() => { + return () => { + editorDispatch({ + type: 'setCurrentTextObject', + payload: editorValueRef.current!, + }); + }; + }, [editorDispatch]); + + // Always keep the localstorage in sync with the value in the editor + // to avoid losing the text object when the user navigates away from the shell + useEffect(() => { + // Only update when its not empty, this is to avoid setting the localstorage value + // to an empty string that will then be replaced by the example request. + if (inputEditorValue !== '') { + const textObject = { + ...currentTextObject, + text: inputEditorValue, + updatedAt: Date.now(), + } as TextObject; + + debouncedUpdateLocalStorageValue(textObject); + } + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + }, [inputEditorValue, debouncedUpdateLocalStorageValue]); + + const data = getResponseWithMostSevereStatusCode(requestData) ?? requestError; + const isLoading = loading || requestInFlight; + + if (!currentTextObject) return null; + + return ( + <> + {fetchingAutocompleteEntities ? ( +
+ +
+ ) : null} + onPanelSizeChange(sizes)} + data-test-subj="consoleEditorContainer" > - {loading ? ( - - ) : isMonacoEnabled ? ( - - ) : ( - + {(EuiResizablePanel, EuiResizableButton) => ( + <> + + + + {loading ? ( + + ) : ( + + )} + + + {!loading && ( + + setInputEditorValue('')} + > + {i18n.translate('console.editor.clearConsoleInputButton', { + defaultMessage: 'Clear this input', + })} + + + )} + + + + + + + + + {data ? ( + + ) : isLoading ? ( + + ) : ( + + )} + + + {(data || isLoading) && ( + + + + dispatch({ type: 'cleanRequest', payload: undefined })} + > + {i18n.translate('console.editor.clearConsoleOutputButton', { + defaultMessage: 'Clear this output', + })} + + + + + + + + + )} + + + )} -
-
- - ); -}); + + + ); + } +); diff --git a/src/plugins/console/public/application/containers/editor/monaco/hooks/index.ts b/src/plugins/console/public/application/containers/editor/hooks/index.ts similarity index 100% rename from src/plugins/console/public/application/containers/editor/monaco/hooks/index.ts rename to src/plugins/console/public/application/containers/editor/hooks/index.ts diff --git a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_register_keyboard_commands.ts b/src/plugins/console/public/application/containers/editor/hooks/use_register_keyboard_commands.ts similarity index 100% rename from src/plugins/console/public/application/containers/editor/monaco/hooks/use_register_keyboard_commands.ts rename to src/plugins/console/public/application/containers/editor/hooks/use_register_keyboard_commands.ts diff --git a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_resize_checker_utils.ts b/src/plugins/console/public/application/containers/editor/hooks/use_resize_checker_utils.ts similarity index 100% rename from src/plugins/console/public/application/containers/editor/monaco/hooks/use_resize_checker_utils.ts rename to src/plugins/console/public/application/containers/editor/hooks/use_resize_checker_utils.ts diff --git a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_set_initial_value.ts b/src/plugins/console/public/application/containers/editor/hooks/use_set_initial_value.ts similarity index 91% rename from src/plugins/console/public/application/containers/editor/monaco/hooks/use_set_initial_value.ts rename to src/plugins/console/public/application/containers/editor/hooks/use_set_initial_value.ts index 41a3b77a105cd..961ea586bc291 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_set_initial_value.ts +++ b/src/plugins/console/public/application/containers/editor/hooks/use_set_initial_value.ts @@ -13,7 +13,7 @@ import { IToasts } from '@kbn/core-notifications-browser'; import { decompressFromEncodedURIComponent } from 'lz-string'; import { i18n } from '@kbn/i18n'; import { useEffect } from 'react'; -import { DEFAULT_INPUT_VALUE } from '../../../../../../common/constants'; +import { DEFAULT_INPUT_VALUE } from '../../../../../common/constants'; interface QueryParams { load_from: string; @@ -21,7 +21,7 @@ interface QueryParams { interface SetInitialValueParams { /** The text value that is initially in the console editor. */ - initialTextValue?: string; + localStorageValue?: string; /** The function that sets the state of the value in the console editor. */ setValue: (value: string) => void; /** The toasts service. */ @@ -45,7 +45,7 @@ export const readLoadFromParam = () => { * @param params The {@link SetInitialValueParams} to use. */ export const useSetInitialValue = (params: SetInitialValueParams) => { - const { initialTextValue, setValue, toasts } = params; + const { localStorageValue, setValue, toasts } = params; useEffect(() => { const loadBufferFromRemote = async (url: string) => { @@ -61,7 +61,7 @@ export const useSetInitialValue = (params: SetInitialValueParams) => { if (parsedURL.origin === 'https://www.elastic.co') { const resp = await fetch(parsedURL); const data = await resp.text(); - setValue(`${initialTextValue}\n\n${data}`); + setValue(`${localStorageValue}\n\n${data}`); } else { toasts.addWarning( i18n.translate('console.monaco.loadFromDataUnrecognizedUrlErrorMessage', { @@ -107,11 +107,11 @@ export const useSetInitialValue = (params: SetInitialValueParams) => { if (loadFromParam) { loadBufferFromRemote(loadFromParam); } else { - setValue(initialTextValue || DEFAULT_INPUT_VALUE); + setValue(localStorageValue || DEFAULT_INPUT_VALUE); } return () => { window.removeEventListener('hashchange', onHashChange); }; - }, [initialTextValue, setValue, toasts]); + }, [localStorageValue, setValue, toasts]); }; diff --git a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_setup_autocomplete_polling.ts b/src/plugins/console/public/application/containers/editor/hooks/use_setup_autocomplete_polling.ts similarity index 94% rename from src/plugins/console/public/application/containers/editor/monaco/hooks/use_setup_autocomplete_polling.ts rename to src/plugins/console/public/application/containers/editor/hooks/use_setup_autocomplete_polling.ts index 1a1a5bb77dd1e..4785be4054ee0 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_setup_autocomplete_polling.ts +++ b/src/plugins/console/public/application/containers/editor/hooks/use_setup_autocomplete_polling.ts @@ -8,7 +8,7 @@ */ import { useEffect } from 'react'; -import { AutocompleteInfo, Settings } from '../../../../../services'; +import { AutocompleteInfo, Settings } from '../../../../services'; interface SetupAutocompletePollingParams { /** The Console autocomplete service. */ diff --git a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_setup_autosave.ts b/src/plugins/console/public/application/containers/editor/hooks/use_setup_autosave.ts similarity index 96% rename from src/plugins/console/public/application/containers/editor/monaco/hooks/use_setup_autosave.ts rename to src/plugins/console/public/application/containers/editor/hooks/use_setup_autosave.ts index 6f46b8ce6589d..8b4bfaa888649 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/hooks/use_setup_autosave.ts +++ b/src/plugins/console/public/application/containers/editor/hooks/use_setup_autosave.ts @@ -8,7 +8,7 @@ */ import { useEffect, useRef } from 'react'; -import { useSaveCurrentTextObject } from '../../../../hooks'; +import { useSaveCurrentTextObject } from '../../../hooks'; import { readLoadFromParam } from './use_set_initial_value'; interface SetupAutosaveParams { diff --git a/src/plugins/console/public/application/containers/editor/index.ts b/src/plugins/console/public/application/containers/editor/index.ts index c9fbe97f01d8d..696806097badd 100644 --- a/src/plugins/console/public/application/containers/editor/index.ts +++ b/src/plugins/console/public/application/containers/editor/index.ts @@ -7,5 +7,4 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -export { autoIndent, getDocumentation } from './legacy'; export { Editor } from './editor'; diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/apply_editor_settings.ts b/src/plugins/console/public/application/containers/editor/legacy/console_editor/apply_editor_settings.ts deleted file mode 100644 index 75e2516a52a7a..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/apply_editor_settings.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 { DevToolsSettings } from '../../../../../services'; -import { CoreEditor } from '../../../../../types'; -import { CustomAceEditor } from '../../../../models/legacy_core_editor'; - -export function applyCurrentSettings( - editor: CoreEditor | CustomAceEditor, - settings: DevToolsSettings -) { - if ((editor as { setStyles?: Function }).setStyles) { - (editor as CoreEditor).setStyles({ - wrapLines: settings.wrapMode, - fontSize: settings.fontSize + 'px', - }); - } else { - (editor as CustomAceEditor).getSession().setUseWrapMode(settings.wrapMode); - (editor as CustomAceEditor).container.style.fontSize = settings.fontSize + 'px'; - } -} diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx deleted file mode 100644 index f0371562a77bb..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.mock.tsx +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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". - */ - -// TODO(jbudz): should be removed when upgrading to TS@4.8 -// this is a skip for the errors created when typechecking with isolatedModules -export {}; - -jest.mock('../../../../contexts/editor_context/editor_registry', () => ({ - instance: { - setInputEditor: () => {}, - getInputEditor: () => ({ - getRequestsInRange: async () => [{ test: 'test' }], - getCoreEditor: () => ({ getCurrentPosition: jest.fn() }), - }), - }, -})); -jest.mock('../../../../components/editor_example', () => {}); -jest.mock('../../../../models/sense_editor', () => { - return { - create: () => ({ - getCoreEditor: () => ({ - registerKeyboardShortcut: jest.fn(), - setStyles: jest.fn(), - getContainer: () => ({ - focus: () => {}, - }), - on: jest.fn(), - addFoldsAtRanges: jest.fn(), - getAllFoldRanges: jest.fn(), - }), - update: jest.fn(), - commands: { - addCommand: () => {}, - }, - }), - }; -}); - -jest.mock('../../../../hooks/use_send_current_request/send_request', () => ({ - sendRequest: jest.fn(), -})); -jest.mock('../../../../../lib/autocomplete/get_endpoint_from_position', () => ({ - getEndpointFromPosition: jest.fn(), -})); diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx deleted file mode 100644 index 589be10596b9b..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.test.tsx +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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". - */ - -jest.mock('../../../../../lib/utils', () => ({ replaceVariables: jest.fn() })); - -import './editor.test.mock'; - -import React from 'react'; -import { mount } from 'enzyme'; -import { I18nProvider } from '@kbn/i18n-react'; -import { act } from 'react-dom/test-utils'; -import * as sinon from 'sinon'; - -import { serviceContextMock } from '../../../../contexts/services_context.mock'; - -import { nextTick } from '@kbn/test-jest-helpers'; -import { - ServicesContextProvider, - EditorContextProvider, - RequestContextProvider, - ContextValue, -} from '../../../../contexts'; - -// Mocked functions -import { sendRequest } from '../../../../hooks/use_send_current_request/send_request'; -import { getEndpointFromPosition } from '../../../../../lib/autocomplete/get_endpoint_from_position'; -import type { DevToolsSettings } from '../../../../../services'; -import * as consoleMenuActions from '../console_menu_actions'; -import { Editor } from './editor'; -import * as utils from '../../../../../lib/utils'; - -describe('Legacy (Ace) Console Editor Component Smoke Test', () => { - let mockedAppContextValue: ContextValue; - const sandbox = sinon.createSandbox(); - - const doMount = () => - mount( - - - - - {}} /> - - - - - ); - - beforeEach(() => { - document.queryCommandSupported = sinon.fake(() => true); - mockedAppContextValue = serviceContextMock.create(); - (utils.replaceVariables as jest.Mock).mockReturnValue(['test']); - }); - - afterEach(() => { - jest.clearAllMocks(); - sandbox.restore(); - }); - - it('calls send current request', async () => { - (getEndpointFromPosition as jest.Mock).mockReturnValue({ patterns: [] }); - (sendRequest as jest.Mock).mockRejectedValue({}); - const editor = doMount(); - act(() => { - editor.find('button[data-test-subj~="sendRequestButton"]').simulate('click'); - }); - await nextTick(); - expect(sendRequest).toBeCalledTimes(1); - }); - - it('opens docs', () => { - const stub = sandbox.stub(consoleMenuActions, 'getDocumentation'); - const editor = doMount(); - const consoleMenuToggle = editor.find('[data-test-subj~="toggleConsoleMenu"]').last(); - consoleMenuToggle.simulate('click'); - - const docsButton = editor.find('[data-test-subj~="consoleMenuOpenDocs"]').last(); - docsButton.simulate('click'); - - expect(stub.callCount).toBe(1); - }); - - it('prompts auto-indent', () => { - const stub = sandbox.stub(consoleMenuActions, 'autoIndent'); - const editor = doMount(); - const consoleMenuToggle = editor.find('[data-test-subj~="toggleConsoleMenu"]').last(); - consoleMenuToggle.simulate('click'); - - const autoIndentButton = editor.find('[data-test-subj~="consoleMenuAutoIndent"]').last(); - autoIndentButton.simulate('click'); - - expect(stub.callCount).toBe(1); - }); -}); diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx deleted file mode 100644 index a0119ac2ec8fa..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor.tsx +++ /dev/null @@ -1,343 +0,0 @@ -/* - * 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 { - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiLink, - EuiScreenReaderOnly, - EuiToolTip, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { debounce } from 'lodash'; -import { decompressFromEncodedURIComponent } from 'lz-string'; -import { parse } from 'query-string'; -import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react'; -import { ace } from '@kbn/es-ui-shared-plugin/public'; -import { ConsoleMenu } from '../../../../components'; -import { useEditorReadContext, useServicesContext } from '../../../../contexts'; -import { - useSaveCurrentTextObject, - useSendCurrentRequest, - useSetInputEditor, -} from '../../../../hooks'; -import * as senseEditor from '../../../../models/sense_editor'; -import { autoIndent, getDocumentation } from '../console_menu_actions'; -import { subscribeResizeChecker } from '../subscribe_console_resize_checker'; -import { applyCurrentSettings } from './apply_editor_settings'; -import { registerCommands } from './keyboard_shortcuts'; -import type { SenseEditor } from '../../../../models/sense_editor'; -import { StorageKeys } from '../../../../../services'; -import { DEFAULT_INPUT_VALUE } from '../../../../../../common/constants'; - -const { useUIAceKeyboardMode } = ace; - -export interface EditorProps { - initialTextValue: string; - setEditorInstance: (instance: SenseEditor) => void; -} - -interface QueryParams { - load_from: string; -} - -const abs: CSSProperties = { - position: 'absolute', - top: '0', - left: '0', - bottom: '0', - right: '0', -}; - -const inputId = 'ConAppInputTextarea'; - -function EditorUI({ initialTextValue, setEditorInstance }: EditorProps) { - const { - services: { - history, - notifications, - settings: settingsService, - esHostService, - http, - autocompleteInfo, - storage, - }, - docLinkVersion, - ...startServices - } = useServicesContext(); - - const { settings } = useEditorReadContext(); - const setInputEditor = useSetInputEditor(); - const sendCurrentRequest = useSendCurrentRequest(); - const saveCurrentTextObject = useSaveCurrentTextObject(); - - const editorRef = useRef(null); - const editorInstanceRef = useRef(null); - - const [textArea, setTextArea] = useState(null); - useUIAceKeyboardMode(textArea, startServices, settings.isAccessibilityOverlayEnabled); - - const openDocumentation = useCallback(async () => { - const documentation = await getDocumentation(editorInstanceRef.current!, docLinkVersion); - if (!documentation) { - return; - } - window.open(documentation, '_blank'); - }, [docLinkVersion]); - - useEffect(() => { - editorInstanceRef.current = senseEditor.create(editorRef.current!); - const editor = editorInstanceRef.current; - const textareaElement = editorRef.current!.querySelector('textarea'); - - if (textareaElement) { - textareaElement.setAttribute('id', inputId); - textareaElement.setAttribute('data-test-subj', 'console-textarea'); - } - - const readQueryParams = () => { - const [, queryString] = (window.location.hash || window.location.search || '').split('?'); - - return parse(queryString || '', { sort: false }) as Required; - }; - - const loadBufferFromRemote = (url: string) => { - const coreEditor = editor.getCoreEditor(); - // Normalize and encode the URL to avoid issues with spaces and other special characters. - const encodedUrl = new URL(url).toString(); - if (/^https?:\/\//.test(encodedUrl)) { - const loadFrom: Record = { - url, - // Having dataType here is required as it doesn't allow jQuery to `eval` content - // coming from the external source thereby preventing XSS attack. - dataType: 'text', - kbnXsrfToken: false, - }; - - if (/https?:\/\/api\.github\.com/.test(url)) { - loadFrom.headers = { Accept: 'application/vnd.github.v3.raw' }; - } - - // Fire and forget. - $.ajax(loadFrom).done(async (data) => { - // when we load data from another Api we also must pass history - await editor.update(`${initialTextValue}\n ${data}`, true); - editor.moveToNextRequestEdge(false); - coreEditor.clearSelection(); - editor.highlightCurrentRequestsAndUpdateActionBar(); - coreEditor.getContainer().focus(); - }); - } - - // If we have a data URI instead of HTTP, LZ-decode it. This enables - // opening requests in Console from anywhere in Kibana. - if (/^data:/.test(url)) { - const data = decompressFromEncodedURIComponent(url.replace(/^data:text\/plain,/, '')); - - // Show a toast if we have a failure - if (data === null || data === '') { - notifications.toasts.addWarning( - i18n.translate('console.loadFromDataUriErrorMessage', { - defaultMessage: 'Unable to load data from the load_from query parameter in the URL', - }) - ); - return; - } - - editor.update(data, true); - editor.moveToNextRequestEdge(false); - coreEditor.clearSelection(); - editor.highlightCurrentRequestsAndUpdateActionBar(); - coreEditor.getContainer().focus(); - } - }; - - // Support for loading a console snippet from a remote source, like support docs. - const onHashChange = debounce(() => { - const { load_from: url } = readQueryParams(); - if (!url) { - return; - } - loadBufferFromRemote(url); - }, 200); - window.addEventListener('hashchange', onHashChange); - - const initialQueryParams = readQueryParams(); - - if (initialQueryParams.load_from) { - loadBufferFromRemote(initialQueryParams.load_from); - } else { - editor.update(initialTextValue || DEFAULT_INPUT_VALUE); - } - - function setupAutosave() { - let timer: number; - const saveDelay = 500; - - editor.getCoreEditor().on('change', () => { - if (timer) { - clearTimeout(timer); - } - timer = window.setTimeout(saveCurrentState, saveDelay); - }); - } - - function saveCurrentState() { - try { - const content = editor.getCoreEditor().getValue(); - saveCurrentTextObject(content); - } catch (e) { - // Ignoring saving error - } - } - - function restoreFolds() { - if (editor) { - const foldRanges = storage.get(StorageKeys.FOLDS, []); - editor.getCoreEditor().addFoldsAtRanges(foldRanges); - } - } - - restoreFolds(); - - function saveFoldsOnChange() { - if (editor) { - editor.getCoreEditor().on('changeFold', () => { - const foldRanges = editor.getCoreEditor().getAllFoldRanges(); - storage.set(StorageKeys.FOLDS, foldRanges); - }); - } - } - - saveFoldsOnChange(); - - setInputEditor(editor); - setTextArea(editorRef.current!.querySelector('textarea')); - - autocompleteInfo.retrieve(settingsService, settingsService.getAutocomplete()); - - const unsubscribeResizer = subscribeResizeChecker(editorRef.current!, editor); - if (!initialQueryParams.load_from) { - // Don't setup autosaving editor content when we pre-load content - // This prevents losing the user's current console content when - // `loadFrom` query param is used for a console session - setupAutosave(); - } - - return () => { - unsubscribeResizer(); - autocompleteInfo.clearSubscriptions(); - window.removeEventListener('hashchange', onHashChange); - if (editorInstanceRef.current) { - // Close autocomplete popup on unmount - editorInstanceRef.current?.getCoreEditor().detachCompleter(); - editorInstanceRef.current.getCoreEditor().destroy(); - } - }; - }, [ - notifications.toasts, - saveCurrentTextObject, - initialTextValue, - history, - setInputEditor, - settingsService, - http, - autocompleteInfo, - storage, - ]); - - useEffect(() => { - const { current: editor } = editorInstanceRef; - applyCurrentSettings(editor!.getCoreEditor(), settings); - // Preserve legacy focus behavior after settings have updated. - editor!.getCoreEditor().getContainer().focus(); - }, [settings]); - - useEffect(() => { - const { isKeyboardShortcutsEnabled } = settings; - if (isKeyboardShortcutsEnabled) { - registerCommands({ - senseEditor: editorInstanceRef.current!, - sendCurrentRequest, - openDocumentation, - }); - } - }, [openDocumentation, settings, sendCurrentRequest]); - - useEffect(() => { - const { current: editor } = editorInstanceRef; - if (editor) { - setEditorInstance(editor); - } - }, [setEditorInstance]); - - return ( -
-
-
    - - - - - - - - - - { - return editorInstanceRef.current!.getRequestsAsCURL(esHostService.getHost()); - }} - getDocumentation={() => { - return getDocumentation(editorInstanceRef.current!, docLinkVersion); - }} - autoIndent={(event) => { - autoIndent(editorInstanceRef.current!, event); - }} - notifications={notifications} - /> - - - - - - -
    -
    -
- ); -} - -export const Editor = React.memo(EditorUI); diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx deleted file mode 100644 index 09cdf02cbab98..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 { VectorTile } from '@mapbox/vector-tile'; -import Protobuf from 'pbf'; -import { EuiScreenReaderOnly } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import React, { useEffect, useRef } from 'react'; -import { convertMapboxVectorTileToJson } from './mapbox_vector_tile'; -import { Mode } from '../../../../models/legacy_core_editor/mode/output'; - -// Ensure the modes we might switch to dynamically are available -import 'brace/mode/text'; -import 'brace/mode/hjson'; -import 'brace/mode/yaml'; - -import { - useEditorReadContext, - useRequestReadContext, - useServicesContext, -} from '../../../../contexts'; -import { createReadOnlyAceEditor, CustomAceEditor } from '../../../../models/legacy_core_editor'; -import { subscribeResizeChecker } from '../subscribe_console_resize_checker'; -import { applyCurrentSettings } from './apply_editor_settings'; -import { isJSONContentType, isMapboxVectorTile, safeExpandLiteralStrings } from '../../utilities'; - -function modeForContentType(contentType?: string) { - if (!contentType) { - return 'ace/mode/text'; - } - if (isJSONContentType(contentType) || isMapboxVectorTile(contentType)) { - // Using hjson will allow us to use comments in editor output and solves the problem with error markers - return 'ace/mode/hjson'; - } else if (contentType.indexOf('application/yaml') >= 0) { - return 'ace/mode/yaml'; - } - return 'ace/mode/text'; -} - -function EditorOutputUI() { - const editorRef = useRef(null); - const editorInstanceRef = useRef(null); - const { services } = useServicesContext(); - const { settings: readOnlySettings } = useEditorReadContext(); - const { - lastResult: { data, error }, - } = useRequestReadContext(); - const inputId = 'ConAppOutputTextarea'; - - useEffect(() => { - editorInstanceRef.current = createReadOnlyAceEditor(editorRef.current!); - const unsubscribe = subscribeResizeChecker(editorRef.current!, editorInstanceRef.current); - const textarea = editorRef.current!.querySelector('textarea')!; - textarea.setAttribute('id', inputId); - textarea.setAttribute('readonly', 'true'); - - return () => { - unsubscribe(); - editorInstanceRef.current!.destroy(); - }; - }, [services.settings]); - - useEffect(() => { - const editor = editorInstanceRef.current!; - if (data) { - const isMultipleRequest = data.length > 1; - const mode = isMultipleRequest - ? new Mode() - : modeForContentType(data[0].response.contentType); - editor.update( - data - .map((result) => { - const { value, contentType } = result.response; - - let editorOutput; - if (readOnlySettings.tripleQuotes && isJSONContentType(contentType)) { - editorOutput = safeExpandLiteralStrings(value as string); - } else if (isMapboxVectorTile(contentType)) { - const vectorTile = new VectorTile(new Protobuf(value as ArrayBuffer)); - const vectorTileJson = convertMapboxVectorTileToJson(vectorTile); - editorOutput = safeExpandLiteralStrings(vectorTileJson as string); - } else { - editorOutput = value; - } - - return editorOutput; - }) - .join('\n'), - mode - ); - } else if (error) { - const mode = modeForContentType(error.response.contentType); - editor.update(error.response.value as string, mode); - } else { - editor.update(''); - } - }, [readOnlySettings, data, error]); - - useEffect(() => { - applyCurrentSettings(editorInstanceRef.current!, readOnlySettings); - }, [readOnlySettings]); - - return ( - <> - - - -
-
-
- - ); -} - -export const EditorOutput = React.memo(EditorOutputUI); diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/keyboard_shortcuts.ts b/src/plugins/console/public/application/containers/editor/legacy/console_editor/keyboard_shortcuts.ts deleted file mode 100644 index daad4bbdb7dbd..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/keyboard_shortcuts.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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 { throttle } from 'lodash'; -import { SenseEditor } from '../../../../models/sense_editor'; - -interface Actions { - senseEditor: SenseEditor; - sendCurrentRequest: () => void; - openDocumentation: () => void; -} - -const COMMANDS = { - SEND_TO_ELASTICSEARCH: 'send to Elasticsearch', - OPEN_DOCUMENTATION: 'open documentation', - AUTO_INDENT_REQUEST: 'auto indent request', - MOVE_TO_PREVIOUS_REQUEST: 'move to previous request start or end', - MOVE_TO_NEXT_REQUEST: 'move to next request start or end', - GO_TO_LINE: 'gotoline', -}; - -export function registerCommands({ senseEditor, sendCurrentRequest, openDocumentation }: Actions) { - const throttledAutoIndent = throttle(() => senseEditor.autoIndent(), 500, { - leading: true, - trailing: true, - }); - const coreEditor = senseEditor.getCoreEditor(); - - coreEditor.registerKeyboardShortcut({ - keys: { win: 'Ctrl-Enter', mac: 'Command-Enter' }, - name: COMMANDS.SEND_TO_ELASTICSEARCH, - fn: () => { - sendCurrentRequest(); - }, - }); - - coreEditor.registerKeyboardShortcut({ - name: COMMANDS.OPEN_DOCUMENTATION, - keys: { win: 'Ctrl-/', mac: 'Command-/' }, - fn: () => { - openDocumentation(); - }, - }); - - coreEditor.registerKeyboardShortcut({ - name: COMMANDS.AUTO_INDENT_REQUEST, - keys: { win: 'Ctrl-I', mac: 'Command-I' }, - fn: () => { - throttledAutoIndent(); - }, - }); - - coreEditor.registerKeyboardShortcut({ - name: COMMANDS.MOVE_TO_PREVIOUS_REQUEST, - keys: { win: 'Ctrl-Up', mac: 'Command-Up' }, - fn: () => { - senseEditor.moveToPreviousRequestEdge(); - }, - }); - - coreEditor.registerKeyboardShortcut({ - name: COMMANDS.MOVE_TO_NEXT_REQUEST, - keys: { win: 'Ctrl-Down', mac: 'Command-Down' }, - fn: () => { - senseEditor.moveToNextRequestEdge(false); - }, - }); - - coreEditor.registerKeyboardShortcut({ - name: COMMANDS.GO_TO_LINE, - keys: { win: 'Ctrl-L', mac: 'Command-L' }, - fn: (editor) => { - const line = parseInt(prompt('Enter line number') ?? '', 10); - if (!isNaN(line)) { - editor.gotoLine(line); - } - }, - }); -} - -export function unregisterCommands(senseEditor: SenseEditor) { - const coreEditor = senseEditor.getCoreEditor(); - Object.values(COMMANDS).forEach((command) => { - coreEditor.unregisterKeyboardShortcut(command); - }); -} diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_menu_actions.ts b/src/plugins/console/public/application/containers/editor/legacy/console_menu_actions.ts deleted file mode 100644 index c65efbc0d82f5..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/console_menu_actions.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 { getEndpointFromPosition } from '../../../../lib/autocomplete/get_endpoint_from_position'; -import { SenseEditor } from '../../../models/sense_editor'; - -export async function autoIndent(editor: SenseEditor, event: React.MouseEvent) { - event.preventDefault(); - await editor.autoIndent(); - editor.getCoreEditor().getContainer().focus(); -} - -export function getDocumentation( - editor: SenseEditor, - docLinkVersion: string -): Promise { - return editor.getRequestsInRange().then((requests) => { - if (!requests || requests.length === 0) { - return null; - } - const position = requests[0].range.end; - position.column = position.column - 1; - const endpoint = getEndpointFromPosition(editor.getCoreEditor(), position, editor.parser); - if (endpoint && endpoint.documentation && endpoint.documentation.indexOf('http') !== -1) { - return endpoint.documentation - .replace('/master/', `/${docLinkVersion}/`) - .replace('/current/', `/${docLinkVersion}/`) - .replace('/{branch}/', `/${docLinkVersion}/`); - } else { - return null; - } - }); -} diff --git a/src/plugins/console/public/application/containers/editor/legacy/index.ts b/src/plugins/console/public/application/containers/editor/legacy/index.ts deleted file mode 100644 index 40e74e7b32e9e..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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". - */ - -export { EditorOutput, Editor } from './console_editor'; -export { getDocumentation, autoIndent } from './console_menu_actions'; diff --git a/src/plugins/console/public/application/containers/editor/legacy/subscribe_console_resize_checker.ts b/src/plugins/console/public/application/containers/editor/legacy/subscribe_console_resize_checker.ts deleted file mode 100644 index 6511d7ad3cc3b..0000000000000 --- a/src/plugins/console/public/application/containers/editor/legacy/subscribe_console_resize_checker.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 { ResizeChecker } from '@kbn/kibana-utils-plugin/public'; - -export function subscribeResizeChecker(el: HTMLElement, ...editors: any[]) { - const checker = new ResizeChecker(el); - checker.on('resize', () => - editors.forEach((e) => { - if (e.getCoreEditor) { - e.getCoreEditor().resize(); - } else { - e.resize(); - } - - if (e.updateActionsBar) { - e.updateActionsBar(); - } - }) - ); - return () => checker.destroy(); -} diff --git a/src/plugins/console/public/application/containers/editor/monaco/index.ts b/src/plugins/console/public/application/containers/editor/monaco/index.ts deleted file mode 100644 index b7b8576bbdf65..0000000000000 --- a/src/plugins/console/public/application/containers/editor/monaco/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * 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". - */ - -export { MonacoEditor } from './monaco_editor'; -export { MonacoEditorOutput } from './monaco_editor_output'; diff --git a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx b/src/plugins/console/public/application/containers/editor/monaco_editor.tsx similarity index 79% rename from src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx rename to src/plugins/console/public/application/containers/editor/monaco_editor.tsx index ca6e66a8ba66f..bc174b772bb1c 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor.tsx +++ b/src/plugins/console/public/application/containers/editor/monaco_editor.tsx @@ -8,18 +8,19 @@ */ import React, { CSSProperties, useCallback, useMemo, useRef, useState, useEffect } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiToolTip } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiButtonIcon, EuiToolTip } from '@elastic/eui'; import { css } from '@emotion/react'; import { CodeEditor } from '@kbn/code-editor'; import { CONSOLE_LANG_ID, CONSOLE_THEME_ID, monaco } from '@kbn/monaco'; import { i18n } from '@kbn/i18n'; -import { useSetInputEditor } from '../../../hooks'; +import { useSetInputEditor } from '../../hooks'; import { ContextMenu } from './components'; import { useServicesContext, useEditorReadContext, useRequestActionContext, -} from '../../../contexts'; + useEditorActionContext, +} from '../../contexts'; import { useSetInitialValue, useSetupAutocompletePolling, @@ -32,10 +33,12 @@ import { MonacoEditorActionsProvider } from './monaco_editor_actions_provider'; import { getSuggestionProvider } from './monaco_editor_suggestion_provider'; export interface EditorProps { - initialTextValue: string; + localStorageValue: string | undefined; + value: string; + setValue: (value: string) => void; } -export const MonacoEditor = ({ initialTextValue }: EditorProps) => { +export const MonacoEditor = ({ localStorageValue, value, setValue }: EditorProps) => { const context = useServicesContext(); const { services: { notifications, settings: settingsService, autocompleteInfo }, @@ -43,7 +46,11 @@ export const MonacoEditor = ({ initialTextValue }: EditorProps) => { config: { isDevMode }, } = context; const { toasts } = notifications; - const { settings } = useEditorReadContext(); + const { + settings, + restoreRequestFromHistory: requestToRestoreFromHistory, + fileToImport, + } = useEditorReadContext(); const [editorInstance, setEditorInstace] = useState< monaco.editor.IStandaloneCodeEditor | undefined >(); @@ -53,6 +60,7 @@ export const MonacoEditor = ({ initialTextValue }: EditorProps) => { const { registerKeyboardCommands, unregisterKeyboardCommands } = useKeyboardCommandsUtils(); const dispatch = useRequestActionContext(); + const editorDispatch = useEditorActionContext(); const actionsProvider = useRef(null); const [editorActionsCss, setEditorActionsCss] = useState({}); @@ -117,18 +125,40 @@ export const MonacoEditor = ({ initialTextValue }: EditorProps) => { const suggestionProvider = useMemo(() => { return getSuggestionProvider(actionsProvider); }, []); - const [value, setValue] = useState(initialTextValue); - useSetInitialValue({ initialTextValue, setValue, toasts }); + useSetInitialValue({ localStorageValue, setValue, toasts }); useSetupAutocompletePolling({ autocompleteInfo, settingsService }); useSetupAutosave({ value }); + // Restore the request from history if there is one + const updateEditor = useCallback(async () => { + if (requestToRestoreFromHistory) { + editorDispatch({ type: 'clearRequestToRestore' }); + await actionsProvider.current?.appendRequestToEditor( + requestToRestoreFromHistory, + dispatch, + context + ); + } + + // Import a request file if one is provided + if (fileToImport) { + editorDispatch({ type: 'setFileToImport', payload: null }); + await actionsProvider.current?.importRequestsToEditor(fileToImport); + } + }, [fileToImport, requestToRestoreFromHistory, dispatch, context, editorDispatch]); + + useEffect(() => { + updateEditor(); + }, [updateEditor]); + return (
{ - + - - - + iconSize={'s'} + /> - + { }; }); -jest.mock('../../../../services', () => { +jest.mock('../../../services', () => { return { getStorage: () => ({ get: () => [], @@ -40,7 +40,7 @@ jest.mock('../../../../services', () => { }; }); -jest.mock('../../../../lib/autocomplete/engine', () => { +jest.mock('../../../lib/autocomplete/engine', () => { return { populateContext: (...args: any) => { mockPopulateContext(args); diff --git a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_actions_provider.ts b/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts similarity index 86% rename from src/plugins/console/public/application/containers/editor/monaco/monaco_editor_actions_provider.ts rename to src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts index 14be049c8ab26..8c66d31b2b57e 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_actions_provider.ts +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_actions_provider.ts @@ -13,11 +13,11 @@ import { ConsoleParsedRequestsProvider, getParsedRequestsProvider, monaco } from import { i18n } from '@kbn/i18n'; import { toMountPoint } from '@kbn/react-kibana-mount'; import { XJson } from '@kbn/es-ui-shared-plugin/public'; -import { isQuotaExceededError } from '../../../../services/history'; -import { DEFAULT_VARIABLES } from '../../../../../common/constants'; -import { getStorage, StorageKeys } from '../../../../services'; -import { sendRequest } from '../../../hooks'; -import { Actions } from '../../../stores/request'; +import { isQuotaExceededError } from '../../../services/history'; +import { DEFAULT_VARIABLES } from '../../../../common/constants'; +import { getStorage, StorageKeys } from '../../../services'; +import { sendRequest } from '../../hooks'; +import { Actions } from '../../stores/request'; import { AutocompleteType, @@ -40,8 +40,9 @@ import { } from './utils'; import type { AdjustedParsedRequest } from './types'; -import { StorageQuotaError } from '../../../components/storage_quota_error'; -import { ContextValue } from '../../../contexts'; +import { type RequestToRestore, RestoreMethod } from '../../../types'; +import { StorageQuotaError } from '../../components/storage_quota_error'; +import { ContextValue } from '../../contexts'; import { containsComments, indentData } from './utils/requests_utils'; const AUTO_INDENTATION_ACTION_LABEL = 'Apply indentations'; @@ -120,7 +121,8 @@ export class MonacoEditorActionsProvider { const offset = this.editor.getTopForLineNumber(lineNumber) - this.editor.getScrollTop(); this.setEditorActionsCss({ visibility: 'visible', - top: offset, + // Move position down by 1 px so that the action buttons panel doesn't cover the top border of the selected block + top: offset + 1, }); } } @@ -147,7 +149,7 @@ export class MonacoEditorActionsProvider { range: selectedRange, options: { isWholeLine: true, - className: SELECTED_REQUESTS_CLASSNAME, + blockClassName: SELECTED_REQUESTS_CLASSNAME, }, }, ]); @@ -160,6 +162,11 @@ export class MonacoEditorActionsProvider { private async getSelectedParsedRequests(): Promise { const model = this.editor.getModel(); + + if (!model) { + return []; + } + const selection = this.editor.getSelection(); if (!model || !selection) { return Promise.resolve([]); @@ -173,6 +180,9 @@ export class MonacoEditorActionsProvider { startLineNumber: number, endLineNumber: number ): Promise { + if (!model) { + return []; + } const parsedRequests = await this.parsedRequestsProvider.getRequests(); const selectedRequests: AdjustedParsedRequest[] = []; for (const [index, parsedRequest] of parsedRequests.entries()) { @@ -243,9 +253,17 @@ export class MonacoEditorActionsProvider { const { toasts } = notifications; try { const allRequests = await this.getRequests(); - // if any request doesnt have a method then we gonna treat it as a non-valid - // request - const requests = allRequests.filter((request) => request.method); + const selectedRequests = await this.getSelectedParsedRequests(); + + const requests = allRequests + // if any request doesnt have a method then we gonna treat it as a non-valid + // request + .filter((request) => request.method) + // map the requests to the original line number + .map((request, index) => ({ + ...request, + lineNumber: selectedRequests[index].startLineNumber, + })); // If we do have requests but none have methods we are not sending the request if (allRequests.length > 0 && !requests.length) { @@ -479,9 +497,6 @@ export class MonacoEditorActionsProvider { return this.getSuggestions(model, position, context); } - /* - * This function inserts a request from the history into the editor - */ public async restoreRequestFromHistory(request: string) { const model = this.editor.getModel(); if (!model) { @@ -679,4 +694,82 @@ export class MonacoEditorActionsProvider { this.editor.trigger(TRIGGER_SUGGESTIONS_ACTION_LABEL, TRIGGER_SUGGESTIONS_HANDLER_ID, {}); } } + + /* + * This function cleares out the editor content and replaces it with the provided requests + */ + public async importRequestsToEditor(requestsToImport: string) { + const model = this.editor.getModel(); + + if (!model) { + return; + } + + const edit: monaco.editor.IIdentifiedSingleEditOperation = { + range: model.getFullModelRange(), + text: requestsToImport, + forceMoveMarkers: true, + }; + + this.editor.executeEdits('restoreFromHistory', [edit]); + } + + /* + * This function inserts a request after the last request in the editor + */ + public async appendRequestToEditor( + req: RequestToRestore, + dispatch: Dispatch, + context: ContextValue + ) { + const model = this.editor.getModel(); + + if (!model) { + return; + } + + // 1 - Create an edit operation to insert the request after the last request + const lastLineNumber = model.getLineCount(); + const column = model.getLineMaxColumn(lastLineNumber); + const edit: monaco.editor.IIdentifiedSingleEditOperation = { + range: { + startLineNumber: lastLineNumber, + startColumn: column, + endLineNumber: lastLineNumber, + endColumn: column, + }, + text: `\n\n${req.request}`, + forceMoveMarkers: true, + }; + this.editor.executeEdits('restoreFromHistory', [edit]); + + // 2 - Since we add two new lines, the cursor should be at the beginning of the new request + const beginningOfNewReq = lastLineNumber + 2; + const selectedRequests = await this.getRequestsBetweenLines( + model, + beginningOfNewReq, + beginningOfNewReq + ); + // We can assume that there is only one request given that we only add one + // request at a time. + const restoredRequest = selectedRequests[0]; + + // 3 - Set the cursor to the beginning of the new request, + this.editor.setSelection({ + startLineNumber: restoredRequest.startLineNumber, + startColumn: 1, + endLineNumber: restoredRequest.startLineNumber, + endColumn: 1, + }); + + // 4 - Scroll to the beginning of the new request + this.editor.setScrollPosition({ + scrollTop: this.editor.getTopForLineNumber(restoredRequest.startLineNumber), + }); + + // 5 - Optionally send the request + if (req.restoreMethod === RestoreMethod.RESTORE_AND_EXECUTE) { + this.sendRequests(dispatch, context); + } + } } diff --git a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx b/src/plugins/console/public/application/containers/editor/monaco_editor_output.tsx similarity index 60% rename from src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx rename to src/plugins/console/public/application/containers/editor/monaco_editor_output.tsx index 9de6748b62b6c..b9e3f3e6f9885 100644 --- a/src/plugins/console/public/application/containers/editor/monaco/monaco_editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/monaco_editor_output.tsx @@ -7,26 +7,44 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React, { FunctionComponent, useCallback, useEffect, useRef, useState } from 'react'; +import React, { + CSSProperties, + FunctionComponent, + useCallback, + useEffect, + useRef, + useState, +} from 'react'; import { CodeEditor } from '@kbn/code-editor'; import { css } from '@emotion/react'; import { VectorTile } from '@mapbox/vector-tile'; import Protobuf from 'pbf'; import { i18n } from '@kbn/i18n'; -import { EuiScreenReaderOnly } from '@elastic/eui'; +import { + EuiScreenReaderOnly, + EuiFlexGroup, + EuiFlexItem, + EuiButtonIcon, + EuiToolTip, +} from '@elastic/eui'; import { CONSOLE_THEME_ID, CONSOLE_OUTPUT_LANG_ID, monaco } from '@kbn/monaco'; -import { getStatusCodeDecorations } from './utils'; -import { useEditorReadContext, useRequestReadContext } from '../../../contexts'; -import { convertMapboxVectorTileToJson } from '../legacy/console_editor/mapbox_vector_tile'; import { + getStatusCodeDecorations, isJSONContentType, isMapboxVectorTile, safeExpandLiteralStrings, languageForContentType, -} from '../utilities'; + convertMapboxVectorTileToJson, +} from './utils'; +import { useEditorReadContext, useRequestReadContext, useServicesContext } from '../../contexts'; +import { MonacoEditorOutputActionsProvider } from './monaco_editor_output_actions_provider'; import { useResizeCheckerUtils } from './hooks'; export const MonacoEditorOutput: FunctionComponent = () => { + const context = useServicesContext(); + const { + services: { notifications }, + } = context; const { settings: readOnlySettings } = useEditorReadContext(); const { lastResult: { data }, @@ -37,8 +55,14 @@ export const MonacoEditorOutput: FunctionComponent = () => { const { setupResizeChecker, destroyResizeChecker } = useResizeCheckerUtils(); const lineDecorations = useRef(null); + const actionsProvider = useRef(null); + const [editorActionsCss, setEditorActionsCss] = useState({}); + const editorDidMountCallback = useCallback( (editor: monaco.editor.IStandaloneCodeEditor) => { + const provider = new MonacoEditorOutputActionsProvider(editor, setEditorActionsCss); + actionsProvider.current = provider; + setupResizeChecker(divRef.current!, editor); lineDecorations.current = editor.createDecorationsCollection(); }, @@ -83,19 +107,71 @@ export const MonacoEditorOutput: FunctionComponent = () => { // If there are multiple responses, add decorations for their status codes const decorations = getStatusCodeDecorations(data); lineDecorations.current?.set(decorations); + // Highlight first line of the output editor + actionsProvider.current?.selectFirstLine(); } } else { setValue(''); } }, [readOnlySettings, data, value]); + const copyOutputCallback = useCallback(async () => { + const selectedText = (await actionsProvider.current?.getParsedOutput()) as string; + + try { + if (!window.navigator?.clipboard) { + throw new Error('Could not copy to clipboard!'); + } + + await window.navigator.clipboard.writeText(selectedText); + + notifications.toasts.addSuccess({ + title: i18n.translate('console.outputPanel.copyOutputToast', { + defaultMessage: 'Selected output copied to clipboard', + }), + }); + } catch (e) { + notifications.toasts.addDanger({ + title: i18n.translate('console.outputPanel.copyOutputToastFailedMessage', { + defaultMessage: 'Could not copy selected output to clipboard', + }), + }); + } + }, [notifications.toasts]); + return (
+ + + + + + +