diff --git a/.buildkite/pipelines/es_serverless/verify_es_serverless_image.yml b/.buildkite/pipelines/es_serverless/verify_es_serverless_image.yml new file mode 100644 index 0000000000000..f6cb21abdb682 --- /dev/null +++ b/.buildkite/pipelines/es_serverless/verify_es_serverless_image.yml @@ -0,0 +1,58 @@ +# https://buildkite.com/elastic/kibana-elasticsearch-serverless-verify-and-promote/ +agents: + queue: kibana-default + +steps: + - label: "Annotate runtime parameters" + command: | + buildkite-agent annotate --context es-serverless-image --style info "ES Serverless image: $ES_SERVERLESS_IMAGE" + buildkite-agent annotate --context kibana-commit --style info "Kibana build hash: $BUILDKITE_BRANCH / $BUILDKITE_COMMIT" + + - group: "(:kibana: x :elastic:) Trigger Kibana Serverless suite" + if: "build.env('SKIP_VERIFICATION') != '1' && build.env('SKIP_VERIFICATION') != 'true'" + steps: + - label: "Pre-Build" + command: .buildkite/scripts/lifecycle/pre_build.sh + key: pre-build + timeout_in_minutes: 10 + agents: + queue: kibana-default + + - label: "Build Kibana Distribution and Plugins" + command: .buildkite/scripts/steps/build_kibana.sh + agents: + queue: n2-16-spot + key: build + depends_on: pre-build + if: "build.env('KIBANA_BUILD_ID') == null || build.env('KIBANA_BUILD_ID') == ''" + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + + - label: "Pick Test Group Run Order" + command: .buildkite/scripts/steps/test/pick_test_group_run_order.sh + agents: + queue: kibana-default + env: + FTR_CONFIGS_SCRIPT: 'TEST_ES_SERVERLESS_IMAGE=$ES_SERVERLESS_IMAGE .buildkite/scripts/steps/test/ftr_configs.sh' + FTR_CONFIG_PATTERNS: '**/test_serverless/**' + LIMIT_CONFIG_TYPE: 'functional' + retry: + automatic: + - exit_status: '*' + limit: 1 + + - wait: ~ + + - label: ":arrow_up::elastic::arrow_up: Promote docker image" + command: .buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh $ES_SERVERLESS_IMAGE + + - wait: ~ + + - label: 'Post-Build' + command: .buildkite/scripts/lifecycle/post_build.sh + timeout_in_minutes: 10 + agents: + queue: kibana-default diff --git a/.buildkite/pipelines/pull_request/base.yml b/.buildkite/pipelines/pull_request/base.yml index 158c22c0bb0c5..9c2527fcdd413 100644 --- a/.buildkite/pipelines/pull_request/base.yml +++ b/.buildkite/pipelines/pull_request/base.yml @@ -136,12 +136,13 @@ steps: - exit_status: '-1' limit: 3 - - command: .buildkite/scripts/steps/check_types.sh - label: 'Check Types' - agents: - queue: n2-16-spot - timeout_in_minutes: 60 - retry: - automatic: - - exit_status: '-1' - limit: 3 +# TODO: Enable in #166813 after fixing types +# - command: .buildkite/scripts/steps/check_types.sh +# label: 'Check Types' +# agents: +# queue: n2-16-spot +# timeout_in_minutes: 60 +# retry: +# automatic: +# - exit_status: '-1' +# limit: 3 diff --git a/.buildkite/pipelines/pull_request/type_check.yml b/.buildkite/pipelines/pull_request/type_check.yml new file mode 100644 index 0000000000000..dc6f8471ff1b2 --- /dev/null +++ b/.buildkite/pipelines/pull_request/type_check.yml @@ -0,0 +1,10 @@ +steps: + - command: .buildkite/scripts/steps/check_types.sh + label: 'Check Types' + agents: + queue: n2-16-spot + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 diff --git a/.buildkite/pipelines/pull_request/type_check_selective.yml b/.buildkite/pipelines/pull_request/type_check_selective.yml new file mode 100644 index 0000000000000..7d01f128aac3c --- /dev/null +++ b/.buildkite/pipelines/pull_request/type_check_selective.yml @@ -0,0 +1,10 @@ +steps: + - command: .buildkite/scripts/steps/check_types_commits.sh + label: 'Check Types Commit Diff' + agents: + queue: n2-16-spot + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.ts b/.buildkite/scripts/pipelines/pull_request/pipeline.ts index 80d1312af6e64..37bd89f2a75a7 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.ts +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.ts @@ -59,6 +59,12 @@ const uploadPipeline = (pipelineContent: string | object) => { pipeline.push(getPipeline('.buildkite/pipelines/pull_request/kbn_handlebars.yml')); } + if (GITHUB_PR_LABELS.includes('ci:hard-typecheck')) { + pipeline.push(getPipeline('.buildkite/pipelines/pull_request/type_check.yml')); + } else { + pipeline.push(getPipeline('.buildkite/pipelines/pull_request/type_check_selective.yml')); + } + if ( (await doAnyChangesMatch([ /^src\/plugins\/controls/, diff --git a/.buildkite/scripts/steps/build_api_docs.sh b/.buildkite/scripts/steps/build_api_docs.sh index f86032c902d1a..ba1c2ec7ec94d 100755 --- a/.buildkite/scripts/steps/build_api_docs.sh +++ b/.buildkite/scripts/steps/build_api_docs.sh @@ -4,8 +4,9 @@ set -euo pipefail .buildkite/scripts/bootstrap.sh -echo "--- Run scripts/type_check to ensure that all build available" -node scripts/type_check +# TODO: Enable in #166813 after fixing types +# echo "--- Run scripts/type_check to ensure that all build available" +# node scripts/type_check echo "--- Build API Docs" node --max-old-space-size=12000 scripts/build_api_docs diff --git a/.buildkite/scripts/steps/check_types_commits.sh b/.buildkite/scripts/steps/check_types_commits.sh new file mode 100644 index 0000000000000..0b76d3d8e089a --- /dev/null +++ b/.buildkite/scripts/steps/check_types_commits.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash + +set -euo pipefail + + +if [[ "${CI-}" == "true" ]]; then + .buildkite/scripts/bootstrap.sh + + sha1="${GITHUB_PR_TARGET_BRANCH-}" + sha2="${GITHUB_PR_TRIGGERED_SHA-}" +else + # Script take between 0 and 2 arguments representing two commit SHA's: + # If 0, it will diff HEAD and HEAD^ + # If 1 (SHA1), it will diff SHA1 and SHA1^ + # If 2 (SHA1, SHA2), it will diff SHA1 and SHA2 + sha1="${1-HEAD}" + sha2="${2-$sha1^}" +fi + +uniq_dirs=() +uniq_tsconfigs=() + +echo "Detecting files changed between $sha1 and $sha2..." + +files=($(git diff --name-only $sha1 $sha2)) + +add_dir () { + new_dir=$1 + + if [ ${#uniq_dirs[@]} -gt 0 ]; then + for dir in "${uniq_dirs[@]}" + do + if [[ "$new_dir" == "$dir" ]]; then + return + fi + done + fi + + uniq_dirs+=($new_dir) +} + +add_tsconfig () { + new_tsconfig=$1 + + if [ ${#uniq_tsconfigs[@]} -gt 0 ]; then + for tsconfig in "${uniq_tsconfigs[@]}" + do + if [[ "$new_tsconfig" == "$tsconfig" ]]; then + return + fi + done + fi + + echo " $new_tsconfig" + uniq_tsconfigs+=($new_tsconfig) +} + +contains_tsconfig () { + dir=$1 + tsconfig="$dir/tsconfig.json" + if [ -f "$tsconfig" ]; then + true + else + false + fi +} + +find_tsconfig () { + dir=$1 + + if [[ "$dir" == "." ]]; then + return + fi + + if contains_tsconfig $dir; then + add_tsconfig "$dir/tsconfig.json" + else + find_tsconfig $(dirname -- "$dir") + fi +} + +if [ ${#files[@]} -eq 0 ]; then + echo "No files found!" + exit +fi + +for file in "${files[@]}" +do + dir=$(dirname -- "$file") + + # Ignore buildkite dir because it traverses many kbn packages and emits incorrect results + if [[ "$dir" != .buildkite* ]]; then + add_dir $dir + fi +done + +echo "Looking for related tsconfig.json files..." + +for dir in "${uniq_dirs[@]}" +do + find_tsconfig $dir +done + +if [ ${#uniq_tsconfigs[@]} -eq 0 ]; then + echo "No tsconfig.json files found for changes in $sha1 $sha2" + exit +fi + +echo "Running scripts/type_check for each found tsconfig.json file..." + +for tsconfig in "${uniq_tsconfigs[@]}" +do + node scripts/type_check --project $tsconfig +done \ No newline at end of file diff --git a/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh b/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh new file mode 100755 index 0000000000000..c6bf1738fe144 --- /dev/null +++ b/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +set -euo pipefail + +source .buildkite/scripts/common/util.sh + +BASE_ES_SERVERLESS_REPO=docker.elastic.co/elasticsearch-ci/elasticsearch-serverless +TARGET_IMAGE=docker.elastic.co/kibana-ci/elasticsearch-serverless:latest-verified + +ES_SERVERLESS_BUCKET=kibana-ci-es-serverless-images +MANIFEST_FILE_NAME=latest-verified.json + +SOURCE_IMAGE_OR_TAG=$1 +if [[ $SOURCE_IMAGE_OR_TAG =~ :[a-zA-Z_-]+$ ]]; then + # $SOURCE_IMAGE_OR_TAG was a full image + SOURCE_IMAGE=$SOURCE_IMAGE_OR_TAG +else + # $SOURCE_IMAGE_OR_TAG was an image tag + SOURCE_IMAGE="$BASE_ES_SERVERLESS_REPO:$SOURCE_IMAGE_OR_TAG" +fi + +echo "--- Promoting ${SOURCE_IMAGE_OR_TAG} to ':latest-verified'" + +echo "Re-tagging $SOURCE_IMAGE -> $TARGET_IMAGE" + +echo "$KIBANA_DOCKER_PASSWORD" | docker login -u "$KIBANA_DOCKER_USERNAME" --password-stdin docker.elastic.co +docker pull "$SOURCE_IMAGE" +docker tag "$SOURCE_IMAGE" "$TARGET_IMAGE" +docker push "$TARGET_IMAGE" + +ORIG_IMG_DATA=$(docker inspect "$SOURCE_IMAGE") +ELASTIC_COMMIT_HASH=$(echo $ORIG_IMG_DATA | jq -r '.[].Config.Labels["org.opencontainers.image.revision"]') + +docker logout docker.elastic.co + +echo "Image push to $TARGET_IMAGE successful." +echo "Promotion successful! Henceforth, thou shall be named Sir $TARGET_IMAGE" + +MANIFEST_UPLOAD_PATH="Skipped" +if [[ "$UPLOAD_MANIFEST" =~ ^(1|true)$ && "$SOURCE_IMAGE_OR_TAG" =~ ^git-[0-9a-fA-F]{12}$ ]]; then + echo "--- Uploading latest-verified manifest to GCS" + cat << EOT >> $MANIFEST_FILE_NAME +{ + "build_url": "$BUILDKITE_BUILD_URL", + "kibana_commit": "$BUILDKITE_COMMIT", + "kibana_branch": "$BUILDKITE_BRANCH", + "elasticsearch_serverless_tag": "$SOURCE_IMAGE_OR_TAG", + "elasticsearch_serverless_image_url: "$SOURCE_IMAGE", + "elasticsearch_serverless_commit": "TODO: this currently can't be decided", + "elasticsearch_commit": "$ELASTIC_COMMIT_HASH", + "created_at": "`date`", + "timestamp": "`FORCE_COLOR=0 node -p 'Date.now()'`" +} +EOT + + gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" \ + cp $MANIFEST_FILE_NAME "gs://$ES_SERVERLESS_BUCKET/$MANIFEST_FILE_NAME" + gsutil acl ch -u AllUsers:R "gs://$ES_SERVERLESS_BUCKET/$MANIFEST_FILE_NAME" + MANIFEST_UPLOAD_PATH="$MANIFEST_FILE_NAME" + +elif [[ "$UPLOAD_MANIFEST" =~ ^(1|true)$ ]]; then + echo "--- Skipping upload of latest-verified manifest to GCS, ES Serverless build tag is not pointing to a hash" +elif [[ "$SOURCE_IMAGE_OR_TAG" =~ ^git-[0-9a-fA-F]{12}$ ]]; then + echo "--- Skipping upload of latest-verified manifest to GCS, flag was not provided" +fi + +echo "--- Annotating build with info" +cat << EOT | buildkite-agent annotate --style "success" +

Promotion successful!

+
New image: $TARGET_IMAGE +
Source image: $SOURCE_IMAGE +
Kibana commit: $BUILDKITE_COMMIT +
Elasticsearch commit: $ELASTIC_COMMIT_HASH +
Manifest file: $MANIFEST_UPLOAD_PATH +EOT diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b6a1c3e86c3e7..647de24ad4920 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -539,6 +539,7 @@ x-pack/plugins/observability @elastic/actionable-observability x-pack/plugins/observability_shared @elastic/observability-ui x-pack/test/security_api_integration/plugins/oidc_provider @elastic/kibana-security test/common/plugins/otel_metrics @elastic/infra-monitoring-ui +packages/kbn-openapi-generator @elastic/security-detection-engine packages/kbn-optimizer @elastic/kibana-operations packages/kbn-optimizer-webpack-helpers @elastic/kibana-operations packages/kbn-osquery-io-ts-types @elastic/security-asset-management diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 39c297a638f27..dab0da20342e7 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: 2023-09-23 +date: 2023-09-25 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 0faae24a8b94b..8cb0ef5bb4524 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index c5baeb0cb22b6..b226186c3d397 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: 2023-09-23 +date: 2023-09-25 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 ebf06c986dcff..796378d9cd4a5 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: 2023-09-23 +date: 2023-09-25 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 d23c9ecb57f96..0a39b5e552aaa 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: 2023-09-23 +date: 2023-09-25 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 e40d36a069eb1..63d16aa0e2bcf 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index ac64992ea455a..5d045c726d11b 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index f0d7089b28dec..9b498aefcc82c 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: 2023-09-23 +date: 2023-09-25 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 ba6854e641b92..ed8902cb5eab1 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: 2023-09-23 +date: 2023-09-25 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 5f35c75afcb6f..78c5c53d74bdd 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: 2023-09-23 +date: 2023-09-25 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 bdc5394cad81b..e5690d05becce 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: 2023-09-23 +date: 2023-09-25 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 e63df42601a6e..5ebd59d7b500f 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: 2023-09-23 +date: 2023-09-25 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 d07db03450288..5895b73947f55 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index e69eb9b03aedb..4eba8503139ab 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index f410339b45d8e..bec0cd2b78006 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 85744f1f164f8..ec788541a85bb 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: 2023-09-23 +date: 2023-09-25 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 cffb497135d51..9abc3551fb3e7 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: 2023-09-23 +date: 2023-09-25 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 8976cad89f07f..712dfc663997b 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: 2023-09-23 +date: 2023-09-25 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 0f9787fe11309..05f3ba75ce256 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: 2023-09-23 +date: 2023-09-25 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 21a78cec424be..10c18a585b964 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: 2023-09-23 +date: 2023-09-25 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 19e039f6d97f8..ed10bf00b57f4 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: 2023-09-23 +date: 2023-09-25 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 2744c1b24ed6b..b3f68a15ccdc9 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: 2023-09-23 +date: 2023-09-25 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 488ccad1de288..2bb12ec6c9fd8 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: 2023-09-23 +date: 2023-09-25 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 5345d51b10a7e..42f23759f1ed6 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: 2023-09-23 +date: 2023-09-25 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 2e81b7cb05cee..6e42e2694b4d7 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: 2023-09-23 +date: 2023-09-25 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 f8e13f109a9f1..698d91dce0dcd 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 56c7063e309eb..c7821d531f7c8 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: 2023-09-23 +date: 2023-09-25 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 5a73fdd5c982c..055894784f580 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: 2023-09-23 +date: 2023-09-25 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 68bfdb1b52157..82418c06b69d4 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: 2023-09-23 +date: 2023-09-25 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 b3806e94e8885..786031f8cc084 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: 2023-09-23 +date: 2023-09-25 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 e3cc4f687f990..4e36621ef1307 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: 2023-09-23 +date: 2023-09-25 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 84d53a40fbfe7..41381b90f8595 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: 2023-09-23 +date: 2023-09-25 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 85e9bedd3e90e..cc4bbc5a7e8fa 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 2f3d1ce6b6ef5..6f732a8e26478 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index ad4487487aa4b..0cc43997049d1 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 2a23f6adaa66a..f8a6e88eb34d3 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 399fdec476c1b..4dc67b1161cd9 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: 2023-09-23 +date: 2023-09-25 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 d5e1c0a7224c7..16b69231cdbe2 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: 2023-09-23 +date: 2023-09-25 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 7b42e812c5d4a..3e9f3e1df6efe 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 64b3268431998..a5dc05d2871de 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: 2023-09-23 +date: 2023-09-25 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 b21c6e5fdb9f0..ed94fe83ad391 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: 2023-09-23 +date: 2023-09-25 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 4b2f89c4c30f6..c10cb41ea3212 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: 2023-09-23 +date: 2023-09-25 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 7accd2a9ff906..3070470e2b5a5 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: 2023-09-23 +date: 2023-09-25 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 ed165823eeba5..b7d75a4c4ef33 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: 2023-09-23 +date: 2023-09-25 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 933a99513d24a..fee8429037ae7 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 06b56354ca7e5..07b97cfb592a5 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index fc36eccea87fa..b3d3515c4fa14 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: 2023-09-23 +date: 2023-09-25 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 834d438105a26..8839599be165d 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: 2023-09-23 +date: 2023-09-25 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 b0f61adb7b1d4..e85389d1f437b 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: 2023-09-23 +date: 2023-09-25 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 12fb004f20339..f7b509cbfdb1b 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: 2023-09-23 +date: 2023-09-25 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 2b19031586a33..7a4cda0d34010 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: 2023-09-23 +date: 2023-09-25 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 3f660f17600e3..49697cf849ee9 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: 2023-09-23 +date: 2023-09-25 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 033028fc9c101..c808902199715 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: 2023-09-23 +date: 2023-09-25 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 2285535bde98d..2d89902efab22 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: 2023-09-23 +date: 2023-09-25 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 e346a850e4bb7..9a9bf83a54734 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: 2023-09-23 +date: 2023-09-25 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 df093ab9e3b8f..4f3a80337aef0 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: 2023-09-23 +date: 2023-09-25 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 2cad8ad38455a..f6123702f5b80 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: 2023-09-23 +date: 2023-09-25 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 2067b09ebc2e3..fa8638f10728d 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: 2023-09-23 +date: 2023-09-25 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 09433ef3bc48c..97b46b486beb5 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: 2023-09-23 +date: 2023-09-25 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 95ff560b17c6f..9521040c51bc2 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: 2023-09-23 +date: 2023-09-25 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 0e7f4e8982ce3..3599dc7b2d1fb 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: 2023-09-23 +date: 2023-09-25 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 9a0a4e21546df..9392f76dd50c7 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: 2023-09-23 +date: 2023-09-25 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 418d5c10ae30c..86c39e2e588c3 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: 2023-09-23 +date: 2023-09-25 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 95dd0d3591c39..351ab76914882 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: 2023-09-23 +date: 2023-09-25 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 0338812903fa8..4392d8382ec87 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: 2023-09-23 +date: 2023-09-25 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 35ed198e2cdb3..dfc37187d7e65 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index b51307a7c4a03..84d266a5cc635 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 3ffaed46165ce..30fbc32a97c20 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: 2023-09-23 +date: 2023-09-25 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 342412b96cc1f..c88197cfa5273 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: 2023-09-23 +date: 2023-09-25 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 7fecad9e82b8a..e35b222d2d8e3 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: 2023-09-23 +date: 2023-09-25 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 be0e77b55c53c..1d12cd375c9e5 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: 2023-09-23 +date: 2023-09-25 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 529ef530c71ad..d5b03bb5f8721 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: 2023-09-23 +date: 2023-09-25 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 5f198bd156da7..0d09c64282018 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: 2023-09-23 +date: 2023-09-25 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 d00e10da03652..3c45419e1a621 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: 2023-09-23 +date: 2023-09-25 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 cdecb343560a9..ce70ab027ad8f 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index e57ae54f82a6d..a07570c8fd12b 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index e4d8c125588a6..7c299671369ad 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index fa0d8d034e450..4b7e5f2909a92 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 9ed572925e244..78aee62715069 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 625be92c362e1..79e1fe67e01f8 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index b3a40d401d4d0..a364d32cc3800 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 9d01c430462d1..a1843c6ed4e25 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index e2a7578651b2d..a31f9f33a9970 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: 2023-09-23 +date: 2023-09-25 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_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 0bb0368549761..10de8a7bdf4ac 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index f1430aef504ee..ae626493cf59c 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: 2023-09-23 +date: 2023-09-25 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_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 2f52122840520..91f44207566ab 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: 2023-09-23 +date: 2023-09-25 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 e0e1901bda520..d8a0804885a41 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 5c05b7a9b7071..c9b4b41ef5450 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 22546130c2b0b..b66284ebbb763 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 720989ea4211e..416721c3f0efb 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index a334b9a625595..2b41be28bb0f0 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 85dc4b00032d4..a44f2ab06e9a8 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 7a7a9d8f99151..9a25aeefe7ba6 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index a682f4923be11..f751bcef82a7c 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: 2023-09-23 +date: 2023-09-25 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_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index a35385986bbf0..14fdfd72f294e 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: 2023-09-23 +date: 2023-09-25 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 cde636d3154cc..c3b594a208989 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: 2023-09-23 +date: 2023-09-25 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_utils.mdx b/api_docs/kbn_apm_utils.mdx index b7c66640e9f48..9a5ce9ccd6e8d 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 42593fa6a3d38..efec62cb7205c 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 008b0b3994b4d..50d478a423436 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index a63477312c0e4..fe977a8118a46 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: 2023-09-23 +date: 2023-09-25 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 01863bd0a42de..fa7bfde0894e4 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: 2023-09-23 +date: 2023-09-25 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 ce8cf44cbfb40..5b42c177beaa4 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: 2023-09-23 +date: 2023-09-25 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 c15f21610b9fe..f3849f529fece 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: 2023-09-23 +date: 2023-09-25 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 ba50f72e8df1e..a0b8042ff4f07 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: 2023-09-23 +date: 2023-09-25 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 3c816936f38ad..0df628917ce8e 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: 2023-09-23 +date: 2023-09-25 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 d6aba69629bb5..a070f6f8921b1 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 7058e2916b5c3..e8e57d5fe77b4 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 4f5d975bfe593..1a3923308f23f 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 173dcdbe38fe8..2a93b76d2f81d 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: 2023-09-23 +date: 2023-09-25 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 5e18b4cfcaec8..706ddccf20a29 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: 2023-09-23 +date: 2023-09-25 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 24d57e1f2669c..eaad62dd612a4 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: 2023-09-23 +date: 2023-09-25 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 ea8d490158f92..4bee4fb17dc9b 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: 2023-09-23 +date: 2023-09-25 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 65a4ed0ca2ee9..e1c6270141d4a 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: 2023-09-23 +date: 2023-09-25 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_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index c00acaffe97f6..85b3f938ed466 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: 2023-09-23 +date: 2023-09-25 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 9d4a88a441c1b..8ba6e130f8559 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: 2023-09-23 +date: 2023-09-25 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_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 8b161315cf5b7..b132504f9ba9f 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: 2023-09-23 +date: 2023-09-25 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_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 769f6cd9fc988..4a0865321d666 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: 2023-09-23 +date: 2023-09-25 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.mdx b/api_docs/kbn_core_analytics_browser.mdx index f843605285324..486d9e6d99eec 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: 2023-09-23 +date: 2023-09-25 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 6da119646bdde..ab8479c1a2a60 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: 2023-09-23 +date: 2023-09-25 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 11ba0ceb6b1b3..6274a9e8285ad 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: 2023-09-23 +date: 2023-09-25 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.mdx b/api_docs/kbn_core_analytics_server.mdx index 42742cc506413..9f7d8792e7ccb 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: 2023-09-23 +date: 2023-09-25 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 2fc99d3c59289..032c2e0446aed 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: 2023-09-23 +date: 2023-09-25 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 15d0ea680fa90..3f62edcfc8116 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: 2023-09-23 +date: 2023-09-25 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 08cbab1d7d3cc..377133ce35c6f 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: 2023-09-23 +date: 2023-09-25 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 f4a29d396b4be..ee7455c60ea49 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: 2023-09-23 +date: 2023-09-25 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 2680b8b3105a4..75d7a269942cd 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: 2023-09-23 +date: 2023-09-25 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 3f4fb77959b56..02644f0ea4446 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: 2023-09-23 +date: 2023-09-25 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 0e9134f396486..98b55347ce49c 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: 2023-09-23 +date: 2023-09-25 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 a91d4c90e8479..ad97bce342d85 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: 2023-09-23 +date: 2023-09-25 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 7a8b15189c229..e31ec24b7ee60 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: 2023-09-23 +date: 2023-09-25 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 b9097c58ff75f..266447aca5bcb 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: 2023-09-23 +date: 2023-09-25 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 17438fdd12171..0de5243285882 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: 2023-09-23 +date: 2023-09-25 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 43971ae1ef5a4..d54c8fd1e5010 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: 2023-09-23 +date: 2023-09-25 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 a4b13fe2a192c..294552a92380e 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: 2023-09-23 +date: 2023-09-25 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 b09be70dc3d11..8b1a9a6db7717 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: 2023-09-23 +date: 2023-09-25 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 4ec4c3fab91ee..dc35497bcb73c 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: 2023-09-23 +date: 2023-09-25 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 fc42fa354eefb..d76a2e1196828 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: 2023-09-23 +date: 2023-09-25 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 2ad921c1e96fd..c962351f98150 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: 2023-09-23 +date: 2023-09-25 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 58ee2a0358778..b82a56c1c1d1c 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: 2023-09-23 +date: 2023-09-25 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 ffc0099aa1163..df98400bcd696 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: 2023-09-23 +date: 2023-09-25 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 5e4f99d7ac4b3..e64865579bf94 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: 2023-09-23 +date: 2023-09-25 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 ace8913888ab0..9c21384cbfa5f 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: 2023-09-23 +date: 2023-09-25 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 ffd27fa74c9b1..a56d1bb448b98 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: 2023-09-23 +date: 2023-09-25 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 493761a0f3ec9..ade289f45cd62 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: 2023-09-23 +date: 2023-09-25 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 5c43940ee3c73..a4efab50b7a76 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: 2023-09-23 +date: 2023-09-25 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 d7dee6ddc2236..6e052f7ad9df1 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: 2023-09-23 +date: 2023-09-25 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 e883a320fb6d1..7db1e51e24376 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: 2023-09-23 +date: 2023-09-25 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 7de20c95a5014..6941ae8a18d2d 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: 2023-09-23 +date: 2023-09-25 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 90f24d8d31093..ad46ffe5d8ca9 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: 2023-09-23 +date: 2023-09-25 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 efe4135f0e6f7..fda5530322e16 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: 2023-09-23 +date: 2023-09-25 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 7b6efb80d101f..7c32329e582ce 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: 2023-09-23 +date: 2023-09-25 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 bd668fba036a4..1e5a19b76e7ea 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: 2023-09-23 +date: 2023-09-25 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 707414989e98c..b6af67c9a3b40 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: 2023-09-23 +date: 2023-09-25 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 b65e3150755c0..49af6cacfa340 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: 2023-09-23 +date: 2023-09-25 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 c075cb87b151e..57071cac0ad33 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: 2023-09-23 +date: 2023-09-25 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 8eeb56fd8a2c2..686a273e1f787 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: 2023-09-23 +date: 2023-09-25 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 1df98e7a701a1..a304f961f707a 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: 2023-09-23 +date: 2023-09-25 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 b99262937075c..2c33c538d6e8e 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: 2023-09-23 +date: 2023-09-25 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 3034b6fadc5a5..6acf6c5b575d3 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: 2023-09-23 +date: 2023-09-25 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 22a11f8e4f179..f9144e0549052 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: 2023-09-23 +date: 2023-09-25 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 f561b8c511dc2..37fc49d00721d 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: 2023-09-23 +date: 2023-09-25 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 b1d3e9775cda7..d090edfd00361 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: 2023-09-23 +date: 2023-09-25 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 8ee539c5d8132..71272c7cef588 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: 2023-09-23 +date: 2023-09-25 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 44432149aea83..98905a17bb508 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: 2023-09-23 +date: 2023-09-25 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 f850dfc8bc439..f57fab3b88935 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: 2023-09-23 +date: 2023-09-25 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 5dffcb1cd39f5..2a99bab6c37e0 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: 2023-09-23 +date: 2023-09-25 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 a682822468c96..ca01eb8645aa8 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: 2023-09-23 +date: 2023-09-25 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 2d4bd1cf8609e..6257f0c5de560 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: 2023-09-23 +date: 2023-09-25 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 eb1dbe43dee64..acf845139f07a 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: 2023-09-23 +date: 2023-09-25 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 6fefef6375303..7fc0a0c12bd37 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: 2023-09-23 +date: 2023-09-25 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 c56c8b5582824..432db02afad4c 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: 2023-09-23 +date: 2023-09-25 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 2d4595cd49883..3f8f1196feac5 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: 2023-09-23 +date: 2023-09-25 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 32be5c82173a8..248c8e9e241bd 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: 2023-09-23 +date: 2023-09-25 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 ab36f400e20e0..9d42d519931e0 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: 2023-09-23 +date: 2023-09-25 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 767fcdd7c3735..fb856e2fed194 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: 2023-09-23 +date: 2023-09-25 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 0fb9b47f63cd8..4238bb71c5699 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: 2023-09-23 +date: 2023-09-25 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 872b841f3e976..3cf77226174c9 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: 2023-09-23 +date: 2023-09-25 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 7d5287d2ad7e5..5be59f3492e0a 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: 2023-09-23 +date: 2023-09-25 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 7467345cb383e..d38193be3ad91 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: 2023-09-23 +date: 2023-09-25 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 665742ca6ee65..f141e8844bc45 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: 2023-09-23 +date: 2023-09-25 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 89530b07848d1..5cc5834d042e9 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: 2023-09-23 +date: 2023-09-25 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 293a2a77e1103..5361d335a0d48 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: 2023-09-23 +date: 2023-09-25 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 04e3782c01b4c..922ec51d160fa 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: 2023-09-23 +date: 2023-09-25 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 ed45ee32cfe2b..6f2f000aebaf3 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: 2023-09-23 +date: 2023-09-25 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 b5bf1b91f66d9..7ca20544ec70a 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: 2023-09-23 +date: 2023-09-25 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 15d0615cf6b9e..6075f982b6c3b 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: 2023-09-23 +date: 2023-09-25 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.mdx b/api_docs/kbn_core_http_server.mdx index 02cbf77bcc365..970253280553e 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: 2023-09-23 +date: 2023-09-25 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 d54ea45429d7a..d30311b04fce5 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: 2023-09-23 +date: 2023-09-25 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 d88a4bcd5e888..168d2225d9d73 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: 2023-09-23 +date: 2023-09-25 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 23d4c2a2ef424..17fe4418b4669 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: 2023-09-23 +date: 2023-09-25 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 622c30d134fb3..a256d9364bfd1 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: 2023-09-23 +date: 2023-09-25 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 0d828f797502c..24a2af7d26e82 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: 2023-09-23 +date: 2023-09-25 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 ba5d96ea802d4..f006a6af78758 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: 2023-09-23 +date: 2023-09-25 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 5e041ebc1c40b..c392208b437e8 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: 2023-09-23 +date: 2023-09-25 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 b7521a3f05776..e4390d3797787 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: 2023-09-23 +date: 2023-09-25 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 02f1c2bdf66d3..317e84fb8c929 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: 2023-09-23 +date: 2023-09-25 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 f51a9f420fe39..eade3cf39f004 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: 2023-09-23 +date: 2023-09-25 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 8ca90d810440b..f07790eff7083 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: 2023-09-23 +date: 2023-09-25 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 a5884366be59f..737749f292e5c 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: 2023-09-23 +date: 2023-09-25 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 100c6cc8b88ec..713685bcd1482 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: 2023-09-23 +date: 2023-09-25 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 be2e19ee4ba36..245e26d3806c9 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: 2023-09-23 +date: 2023-09-25 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 c0b3bb0d072aa..bc624a5d19ab4 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: 2023-09-23 +date: 2023-09-25 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 5abafc85a7454..768901164de5d 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: 2023-09-23 +date: 2023-09-25 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 fd4b837db4504..8f22ed3890ae0 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: 2023-09-23 +date: 2023-09-25 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 f563ef394377f..19b7dacd488ca 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: 2023-09-23 +date: 2023-09-25 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 9e385d6bc9139..636caf98f68a0 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: 2023-09-23 +date: 2023-09-25 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 ae44afc1313bf..977b6d8a719d2 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: 2023-09-23 +date: 2023-09-25 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 dcd3a4e25fe68..deb572120287b 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: 2023-09-23 +date: 2023-09-25 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 eff9f5c749f6e..d88ff2994d574 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: 2023-09-23 +date: 2023-09-25 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 376250795f66b..e528c599dc84f 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: 2023-09-23 +date: 2023-09-25 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 6e818ee25694f..25beb062d5c04 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: 2023-09-23 +date: 2023-09-25 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 4b9aa4ee299db..84fbdd2cfcb6e 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: 2023-09-23 +date: 2023-09-25 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 9bd42d7e8345d..a35be2195ebd1 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: 2023-09-23 +date: 2023-09-25 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 8e78bd8b1f896..e62f569fb9778 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: 2023-09-23 +date: 2023-09-25 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 bdcbdd503afd2..bb499ed6d6aee 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: 2023-09-23 +date: 2023-09-25 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 45b3acc6cb17c..7183fe2e7661e 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: 2023-09-23 +date: 2023-09-25 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 8b6d36e23e460..ded66b5298d2e 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: 2023-09-23 +date: 2023-09-25 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 aacce3f31cd0c..dacafd5c07ea9 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: 2023-09-23 +date: 2023-09-25 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 bd42268ea9a35..44df6622c0612 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: 2023-09-23 +date: 2023-09-25 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 575fa8ebfb82f..45c728dd2212e 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: 2023-09-23 +date: 2023-09-25 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 e55417d2adf43..45a51da94d143 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: 2023-09-23 +date: 2023-09-25 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 720f3a8df48bb..656221274a163 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: 2023-09-23 +date: 2023-09-25 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 e50fa1f563de2..266a89924e2d2 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: 2023-09-23 +date: 2023-09-25 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_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 8ba18a347b60c..300ef65282260 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: 2023-09-23 +date: 2023-09-25 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 d82297ad029df..6ea7fb7d28df2 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: 2023-09-23 +date: 2023-09-25 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 facc525488e1e..dddd9131ec4a9 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: 2023-09-23 +date: 2023-09-25 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 8993b180e5414..6ef6c334f6c9f 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: 2023-09-23 +date: 2023-09-25 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 90ad4d9f09d8c..b4ebbd40acce0 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: 2023-09-23 +date: 2023-09-25 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 5d4a91771c5c3..8be246dd7c86a 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: 2023-09-23 +date: 2023-09-25 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 aed9735f05760..9c8aa99884803 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: 2023-09-23 +date: 2023-09-25 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 25ec601e57f85..50a284aea720e 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: 2023-09-23 +date: 2023-09-25 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 b7a88ccc39084..cbfa1a3be1252 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: 2023-09-23 +date: 2023-09-25 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 86a4b60f1a325..1807f6dd43bfe 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: 2023-09-23 +date: 2023-09-25 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 68ac467bd7f37..8ac7220435334 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: 2023-09-23 +date: 2023-09-25 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 fb7b39aaa0756..693e6123f8508 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: 2023-09-23 +date: 2023-09-25 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 08636f379961f..0035c74b068df 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: 2023-09-23 +date: 2023-09-25 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 d86d5cf432022..a97a1930db0e3 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: 2023-09-23 +date: 2023-09-25 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 e6912c8395ec8..25dc1e5630dc3 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: 2023-09-23 +date: 2023-09-25 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 993521798ba5b..001abf71565f8 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: 2023-09-23 +date: 2023-09-25 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 3cd4b871bdaed..eefb17d1ecb7e 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: 2023-09-23 +date: 2023-09-25 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 c95f032dd68e6..b86c754b683a4 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: 2023-09-23 +date: 2023-09-25 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 3831775770502..177d77c6d48e9 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: 2023-09-23 +date: 2023-09-25 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 103dbeb312120..ee67a1af3d9e9 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: 2023-09-23 +date: 2023-09-25 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 ad820da6dbabb..66be5deb12f6d 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: 2023-09-23 +date: 2023-09-25 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 5546b88646fc4..c8018095c9045 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: 2023-09-23 +date: 2023-09-25 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 bb23f5aea34d0..f801dcc750401 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: 2023-09-23 +date: 2023-09-25 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 b64c688ceedec..c0f0e1507d36b 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: 2023-09-23 +date: 2023-09-25 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 d7ac2ff92c3c9..99ff22c802e51 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: 2023-09-23 +date: 2023-09-25 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_status_common.mdx b/api_docs/kbn_core_status_common.mdx index c23f8977c589e..b7dea67aa296d 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: 2023-09-23 +date: 2023-09-25 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 5928a3b750b57..b84a9a5b10631 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: 2023-09-23 +date: 2023-09-25 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 a5c66906747a0..19077b75a7087 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: 2023-09-23 +date: 2023-09-25 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 8d0a1b8c2ee3d..8cee9aa6d96dc 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: 2023-09-23 +date: 2023-09-25 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 c658622aadc51..ac9655111b722 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: 2023-09-23 +date: 2023-09-25 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 dac178362cdbc..357b5a4428a6f 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: 2023-09-23 +date: 2023-09-25 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 1ed4ef1dd5f65..28cf4c55b2786 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: 2023-09-23 +date: 2023-09-25 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 9d4aa85d4ce09..cc00e1f527394 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: 2023-09-23 +date: 2023-09-25 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_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 31cdb38084c0e..74e8e5f1838a9 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: 2023-09-23 +date: 2023-09-25 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 a1b2fc98628c0..17fe928e96281 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: 2023-09-23 +date: 2023-09-25 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 89a23157099ca..ebd2bb1ad9fe5 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: 2023-09-23 +date: 2023-09-25 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 7a02c027cc5aa..7b6fc04762a3e 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: 2023-09-23 +date: 2023-09-25 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 f06fdca9d93c3..54b7e96f1172f 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: 2023-09-23 +date: 2023-09-25 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 9cd58b2114361..783594aa9d8cd 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: 2023-09-23 +date: 2023-09-25 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 5542650f4975d..1efaa87e91ced 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: 2023-09-23 +date: 2023-09-25 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 34da10a397ea5..a922b457f30ed 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: 2023-09-23 +date: 2023-09-25 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 800ef326ff69a..8740db46fd7de 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: 2023-09-23 +date: 2023-09-25 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 83ba249adab7e..47ec719e0404c 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: 2023-09-23 +date: 2023-09-25 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 0e31535a69a3a..4ca8b9188d0b2 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: 2023-09-23 +date: 2023-09-25 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 285184b814baf..4d100624512d7 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: 2023-09-23 +date: 2023-09-25 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 46e1134328301..9e4ce4251cb55 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: 2023-09-23 +date: 2023-09-25 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 f677337910592..1e513ea1fb1d9 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: 2023-09-23 +date: 2023-09-25 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_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index cb1162f3c8e9a..c5ad8b74ac186 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: 2023-09-23 +date: 2023-09-25 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_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 4c8a4b1f3e22f..b6a64a1eab115 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.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 ab21ebf5a8062..07fabb2446d55 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: 2023-09-23 +date: 2023-09-25 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 12af295c81a0c..c0ee403a2f79f 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: 2023-09-23 +date: 2023-09-25 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 db2067d3b8ec1..2dfd03b92465c 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index 1782e0a6b5cd6..c07f72fce212d 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: 2023-09-23 +date: 2023-09-25 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 622a12203b52b..f23e8c0f1fbd8 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index 58bfcdb9dae43..8d50a3b93bbf4 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 6311aee441fae..1a6dd93e3a571 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: 2023-09-23 +date: 2023-09-25 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 896c687f4180d..aebf2a9e4af82 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: 2023-09-23 +date: 2023-09-25 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 38569e61fde65..b6514e9a33253 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index f11cbd59a3054..29e4872352094 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: 2023-09-23 +date: 2023-09-25 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 4d78ee68f0928..168d7906e53e9 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: 2023-09-23 +date: 2023-09-25 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 8797d23c5c5ca..c45567aa80526 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: 2023-09-23 +date: 2023-09-25 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 736a3eb4d2e22..05048e4e6052e 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 94d30fd3f54da..960657f98b0ed 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: 2023-09-23 +date: 2023-09-25 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 06cf330de003d..ab3f1edcd62bc 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: 2023-09-23 +date: 2023-09-25 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 2af0f18325667..3a15b52e304ef 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: 2023-09-23 +date: 2023-09-25 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 f25a10d836d91..c49781680b955 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: 2023-09-23 +date: 2023-09-25 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 1167baa62f8cd..2c57401c9245d 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: 2023-09-23 +date: 2023-09-25 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 316795e950137..155ea894b65ca 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: 2023-09-23 +date: 2023-09-25 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 e54d9451a52f0..2aaa075f7037c 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: 2023-09-23 +date: 2023-09-25 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 56c355c8a1d9b..e8d8ec623e806 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: 2023-09-23 +date: 2023-09-25 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 46fbd75b541b9..93f6c59c4acd3 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index a4e687d893727..0d079b84e7b1e 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: 2023-09-23 +date: 2023-09-25 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 b2685d90479a6..d93f7bf0216ce 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: 2023-09-23 +date: 2023-09-25 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 805c85e2e5d23..8916af4df9fb2 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: 2023-09-23 +date: 2023-09-25 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 09f9faa15eff0..014c18a8cbda5 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 7c80d15acba3c..44125b1345abf 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 88181aab0a495..11c9c4c666074 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: 2023-09-23 +date: 2023-09-25 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_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 053c3891f1da5..625952ef85ad0 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 891d5c75de7b6..dba47e1f237fb 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: 2023-09-23 +date: 2023-09-25 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 60a06c9f3ae3c..d18fd02ff7f45 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: 2023-09-23 +date: 2023-09-25 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 5a96d603d9b67..6dbc74478590d 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: 2023-09-23 +date: 2023-09-25 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 1522b31958f9e..d02c064539f07 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: 2023-09-23 +date: 2023-09-25 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 6ef1097ef4ceb..11c7eb5df7999 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: 2023-09-23 +date: 2023-09-25 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 a7049cee31050..04717e9eb912d 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 820452718ecc1..2a3a1828159c4 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: 2023-09-23 +date: 2023-09-25 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 a5915d78cf2b7..42750a0453395 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: 2023-09-23 +date: 2023-09-25 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.mdx b/api_docs/kbn_expandable_flyout.mdx index df75973fa6437..d82e33e0b9d44 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: 2023-09-23 +date: 2023-09-25 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 111a404ec0af5..9b5d782319fba 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index ce3961c46e3e4..a85eddf18ee15 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: 2023-09-23 +date: 2023-09-25 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_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index d678181b08eda..64b1c2f280233 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 0f3d7636cd487..41e2065d3afbc 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: 2023-09-23 +date: 2023-09-25 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 99cb25bd70b8b..c4aa464f5ad50 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: 2023-09-23 +date: 2023-09-25 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 e51c83fca0c01..d658eeb8b2af9 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index f18cc442d3cc7..c454fe5b04c2e 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index a48ea36d35693..0541492651bb6 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: 2023-09-23 +date: 2023-09-25 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 bce960e115fda..14f64f21aba6d 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: 2023-09-23 +date: 2023-09-25 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 23901e6ea68fa..112dbaea3447b 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: 2023-09-23 +date: 2023-09-25 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 0d6a9bd32d921..001d6acc2fa6d 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: 2023-09-23 +date: 2023-09-25 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 385264a2e6b16..d8ce739a1bc15 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: 2023-09-23 +date: 2023-09-25 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 0121496b73758..1857796753c32 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: 2023-09-23 +date: 2023-09-25 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 d2cdf79ebdadf..e35341e4a6138 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: 2023-09-23 +date: 2023-09-25 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 31ce3940b0e79..0b68e1641af45 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: 2023-09-23 +date: 2023-09-25 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 f1ca34f4ab5f6..f476b2ec1fc4d 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 2cf5bfcc189ec..e86d57f05bde6 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: 2023-09-23 +date: 2023-09-25 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 5e1d7a35e9f35..1eb782fb97a7a 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 9ab73c011fdd4..3ff5c27cea928 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index bd4cb84b2cb66..de08cea9a52ea 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: 2023-09-23 +date: 2023-09-25 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 dbb59734e20d0..b83426b8881f6 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: 2023-09-23 +date: 2023-09-25 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 4b55dec03361d..047032d25cb1c 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 6d6c9e7aa85fd..0e2b9839031d2 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: 2023-09-23 +date: 2023-09-25 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 ba46fb07f940b..dbef273cea48b 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: 2023-09-23 +date: 2023-09-25 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 aee78de462594..c5c5681e3012a 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/lens-embeddable-utils'] --- import kbnLensEmbeddableUtilsObj from './kbn_lens_embeddable_utils.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index a76a3418d8a93..743dfd6613d16 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: 2023-09-23 +date: 2023-09-25 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 33aa75b1b4cf1..5f11011b0bf7a 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 0545116d9d3d7..c9433e41a126e 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: 2023-09-23 +date: 2023-09-25 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 c9dbb000f43b7..e0d6919349ad7 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: 2023-09-23 +date: 2023-09-25 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_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index e836f1c8bf680..b9a73ffc4f5d4 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: 2023-09-23 +date: 2023-09-25 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 f965a76d287be..8e8ea4b103db1 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: 2023-09-23 +date: 2023-09-25 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_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index d3b03594b9b45..b2f42e0616125 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: 2023-09-23 +date: 2023-09-25 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.mdx b/api_docs/kbn_management_settings_ids.mdx index 5021dc7a7ee0c..893d2328b22fa 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-ids'] --- import kbnManagementSettingsIdsObj from './kbn_management_settings_ids.devdocs.json'; diff --git a/api_docs/kbn_management_settings_section_registry.mdx b/api_docs/kbn_management_settings_section_registry.mdx index fc6d1c1b1591d..ed99fa80766c4 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: 2023-09-23 +date: 2023-09-25 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 9e5640274cf6e..a403ae48283b7 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: 2023-09-23 +date: 2023-09-25 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 1314872894a9d..49ba997e4f681 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: 2023-09-23 +date: 2023-09-25 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 a420eccf9169a..bb2582bad4a12 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: 2023-09-23 +date: 2023-09-25 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 6f648ebe29fa3..bc5b83226c36a 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 3edc6f4a1735e..83c17a794e6bb 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index ad4426470d765..25c2ba0d5d608 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: 2023-09-23 +date: 2023-09-25 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 2017de9727638..b83a4d4a6614d 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: 2023-09-23 +date: 2023-09-25 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_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 00185fa1f0e84..4658a091d165e 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: 2023-09-23 +date: 2023-09-25 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_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index b6f7304ab758b..3e748a58c2008 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: 2023-09-23 +date: 2023-09-25 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 83345deaa87d4..00ff6cd26b022 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: 2023-09-23 +date: 2023-09-25 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 44a2568694569..4d7a4aa29a9ef 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: 2023-09-23 +date: 2023-09-25 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 36633c07de0c6..e0ab84aa0a179 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: 2023-09-23 +date: 2023-09-25 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 01dd9fac8e8f9..3a12f3c49aa48 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: 2023-09-23 +date: 2023-09-25 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 6335986895acb..f06bc6d9963ae 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: 2023-09-23 +date: 2023-09-25 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 955a97f998d49..daacad5e7f5ca 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: 2023-09-23 +date: 2023-09-25 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 82a192d8b1ea7..464622aa3d617 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: 2023-09-23 +date: 2023-09-25 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 c1bc2fd19f2b9..f9a9bc821e106 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: 2023-09-23 +date: 2023-09-25 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 2803fa8d518d9..ad7313b831f6a 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: 2023-09-23 +date: 2023-09-25 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 c944c8412d8a1..403a7969d5e64 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: 2023-09-23 +date: 2023-09-25 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 22d2d68b3bb81..82b8dfff78846 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: 2023-09-23 +date: 2023-09-25 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 692e708afcbc8..3e94c66746972 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: 2023-09-23 +date: 2023-09-25 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 1aba662f6d98f..e647e7cbf750b 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: 2023-09-23 +date: 2023-09-25 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 bfe42610fc618..e2acd8ef3b8be 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: 2023-09-23 +date: 2023-09-25 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 cc81c1cb6715f..dd1e17aff3e6d 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: 2023-09-23 +date: 2023-09-25 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 dca6deeb5ecde..4ae8ec2d9dc65 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: 2023-09-23 +date: 2023-09-25 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_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index b9e911af51cfa..c54e0d15eb6bd 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: 2023-09-23 +date: 2023-09-25 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_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 2dcb5623c1d43..fb0a0c56e0c6a 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 153eb6c6d1eb6..e6e6002c5160d 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: 2023-09-23 +date: 2023-09-25 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 ee7ac731ab68d..87e4107c558a8 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 3bf29cc5849e5..9233358b2e19c 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 5d0755568b1df..a292fa3b74e96 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: 2023-09-23 +date: 2023-09-25 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 6ccfeb627960c..fb1356fac73e3 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: 2023-09-23 +date: 2023-09-25 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 c12966cdc6688..6c9ee72777eed 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: 2023-09-23 +date: 2023-09-25 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_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index e4ddfffe78d86..f1e1597883753 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: 2023-09-23 +date: 2023-09-25 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_generator.mdx b/api_docs/kbn_plugin_generator.mdx index ac12cc6994281..24bfb029d6109 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: 2023-09-23 +date: 2023-09-25 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 4065e1097d916..953511e39f2e3 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index bb73bee427a5f..0514e6150c891 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: 2023-09-23 +date: 2023-09-25 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 a34ef52489a68..c7ec2b6a93603 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: 2023-09-23 +date: 2023-09-25 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 df48fd5af39f5..0507895dffd49 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 2e0e0ff1b1ced..704735f466ae5 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: 2023-09-23 +date: 2023-09-25 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 a75c3a7a55abb..e88986d3607aa 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: 2023-09-23 +date: 2023-09-25 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 d1ad70321c8f5..11e05f741a2ac 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: 2023-09-23 +date: 2023-09-25 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 82e70aa86723f..5ddab41b46838 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: 2023-09-23 +date: 2023-09-25 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 bdc791e102b11..83de93e3369ea 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: 2023-09-23 +date: 2023-09-25 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 3429f820ccbeb..dca37ad6e56a4 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index 878dabfe115b0..a68d4f826eb98 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: 2023-09-23 +date: 2023-09-25 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 b47c0999360f1..6f879cf7898a8 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: 2023-09-23 +date: 2023-09-25 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 7e5b49ac0ed61..2f36028277cef 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: 2023-09-23 +date: 2023-09-25 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 cfcfdd3b9e0b3..f227b7022b7f5 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: 2023-09-23 +date: 2023-09-25 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 eb3f91bc91c66..d6e4e4237cff5 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 364bd31cba8b4..f34844fc311aa 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 6787a0ef49689..8ae853ee7e2f8 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: 2023-09-23 +date: 2023-09-25 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 42a047ccb94fc..6d85dcea07a21 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: 2023-09-23 +date: 2023-09-25 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 e97382f501235..cc68470fb7074 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 01cc29dc3cb0e..4ebf980f79a2c 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: 2023-09-23 +date: 2023-09-25 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 a72e945074f3e..5d1e79818fbf6 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_response_warnings.mdx b/api_docs/kbn_search_response_warnings.mdx index ce95ffee30181..f90b75127bafd 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index eb4259d79ade9..dd6bac00eed15 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: 2023-09-23 +date: 2023-09-25 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 9d3b726a9d7b0..5491a100b92a0 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: 2023-09-23 +date: 2023-09-25 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 0d240152069ce..d8f757a466198 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: 2023-09-23 +date: 2023-09-25 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 87ad6e7de54f3..441d2d7deec6d 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: 2023-09-23 +date: 2023-09-25 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_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 1e0d90f27eb63..4a9fe5e16d8f4 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: 2023-09-23 +date: 2023-09-25 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 75f55ea78e82e..06739a953d8e0 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: 2023-09-23 +date: 2023-09-25 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 2af904ee99196..1b55f4c3a1b2c 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: 2023-09-23 +date: 2023-09-25 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 574567749acfd..4e877404e8766 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: 2023-09-23 +date: 2023-09-25 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 e3bf7a8555508..04c83082210b3 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: 2023-09-23 +date: 2023-09-25 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_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 657a050867c8f..33fad620f2896 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index f594bf99ec0e2..0bfe2641b5252 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: 2023-09-23 +date: 2023-09-25 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 0360db046213c..06ff94f2f2df1 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: 2023-09-23 +date: 2023-09-25 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 267277d8e01f4..f44b472ee21c7 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: 2023-09-23 +date: 2023-09-25 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 7776609174299..4188e79322446 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: 2023-09-23 +date: 2023-09-25 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 86db91f73ecab..93000e4766bb0 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: 2023-09-23 +date: 2023-09-25 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 48b48b5d756a3..c212829becd91 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: 2023-09-23 +date: 2023-09-25 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 a57b252c37165..382577a5efb66 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: 2023-09-23 +date: 2023-09-25 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 17ba14e6701f6..d65169c1c9390 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: 2023-09-23 +date: 2023-09-25 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 e840b207dfbcd..0bcf950f45f42 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: 2023-09-23 +date: 2023-09-25 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 4e1eee26a7c9a..0f5d7f30b2d6c 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: 2023-09-23 +date: 2023-09-25 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 88040aa1a5251..18a139185788c 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: 2023-09-23 +date: 2023-09-25 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 f824ae5a30210..07abe26b21359 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: 2023-09-23 +date: 2023-09-25 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 bfe722d2df6a7..9d29584068169 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: 2023-09-23 +date: 2023-09-25 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 b043f07019d40..792ca2d60f366 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 8f3fb4643bc11..fad26aae0a9e1 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: 2023-09-23 +date: 2023-09-25 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 75f1f6315e9e4..d373b4544a069 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: 2023-09-23 +date: 2023-09-25 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 4289663d99710..d6f26b34962b4 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: 2023-09-23 +date: 2023-09-25 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 558711296d143..ba2ddcb00c7dc 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: 2023-09-23 +date: 2023-09-25 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 dd67f8fbee30b..78786e5912b76 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: 2023-09-23 +date: 2023-09-25 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 020e98a931537..071f541430312 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: 2023-09-23 +date: 2023-09-25 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 8d77c464587d6..32fcd923b17a5 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: 2023-09-23 +date: 2023-09-25 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 fe360560e11dd..9a631df590073 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: 2023-09-23 +date: 2023-09-25 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_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index d2163ae69d79f..71fdec9587e9c 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.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 e5f8d8e4b8d7b..271ceb24e9dfd 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: 2023-09-23 +date: 2023-09-25 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_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index ee0d6e66bf934..6579ae10abdea 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index ec62fd5c15d0c..67467d7465aca 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: 2023-09-23 +date: 2023-09-25 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 b6133ff64ead5..d8ba221beb0b6 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: 2023-09-23 +date: 2023-09-25 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 cacd38dfae6ff..e9ded083fa890 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: 2023-09-23 +date: 2023-09-25 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 72291787db539..36ea7df717cb8 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: 2023-09-23 +date: 2023-09-25 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_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index cf90e4d9ffe6d..88224c82e199e 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: 2023-09-23 +date: 2023-09-25 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 dd75d4f47b38b..50bd414ea40b0 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: 2023-09-23 +date: 2023-09-25 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 3cad36293b67a..e75dafb426bec 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: 2023-09-23 +date: 2023-09-25 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 e0c24de02f9ae..40c537aba7b4d 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: 2023-09-23 +date: 2023-09-25 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 55bed3a0b7666..aacf200fcf4a8 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: 2023-09-23 +date: 2023-09-25 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 6569e4c9d47f7..5ed875f5a62f7 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: 2023-09-23 +date: 2023-09-25 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 5f488f21294dc..411ecb70ef47d 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: 2023-09-23 +date: 2023-09-25 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 a9348ca456aed..32bf1d99be571 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: 2023-09-23 +date: 2023-09-25 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 b35e70341ea39..e2a54169e14bb 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: 2023-09-23 +date: 2023-09-25 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 a18cccc415e70..3420d3cc9c0ee 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: 2023-09-23 +date: 2023-09-25 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 f543036c819b8..f9bec4c5c3117 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: 2023-09-23 +date: 2023-09-25 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 e10bb42e67b5b..030f61acf6948 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: 2023-09-23 +date: 2023-09-25 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 6e210e381c60f..9306d1e357d48 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: 2023-09-23 +date: 2023-09-25 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 497e23c1a028c..49cd5ffa47422 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: 2023-09-23 +date: 2023-09-25 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 6948d6527a79d..5f1ee64b5911f 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: 2023-09-23 +date: 2023-09-25 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 4cdf732da642e..007b4ff76e63f 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: 2023-09-23 +date: 2023-09-25 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 f36bfbc2161a3..6235595b793a3 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: 2023-09-23 +date: 2023-09-25 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 1a5aabdc7f0f8..c9c60681c8e6c 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: 2023-09-23 +date: 2023-09-25 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 d512d76f7041b..d46851bdd71c2 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: 2023-09-23 +date: 2023-09-25 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 e868836b66c23..95c352d2c50a9 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: 2023-09-23 +date: 2023-09-25 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 1f27f7af88fd0..66ca7436ee8f3 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: 2023-09-23 +date: 2023-09-25 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 2f5ac19c3dbb9..2417eb0bda622 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: 2023-09-23 +date: 2023-09-25 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 4f44f287f34b0..e13dee86891a6 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: 2023-09-23 +date: 2023-09-25 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 cada6a29e7b2c..8d04826f4fb12 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: 2023-09-23 +date: 2023-09-25 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 0a5e0e5c432f8..c5927aa75edd9 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: 2023-09-23 +date: 2023-09-25 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 578df5b945c57..c78b891291bf0 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: 2023-09-23 +date: 2023-09-25 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 8b88c92c82471..35b2a26610cbc 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: 2023-09-23 +date: 2023-09-25 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 2aecaae5e64c6..954f26c3d143c 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: 2023-09-23 +date: 2023-09-25 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 80ca056909c49..5957345b21b31 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: 2023-09-23 +date: 2023-09-25 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 fbf59005aec3d..0ecd6e2c5dda3 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: 2023-09-23 +date: 2023-09-25 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_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index fd548c469f2bb..6754b62d97334 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: 2023-09-23 +date: 2023-09-25 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 4202163b650dc..43593f0fccb25 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: 2023-09-23 +date: 2023-09-25 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 6a4b3dd2cea57..53c388e42aae3 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 7bd3683788a61..67e81a160f3c8 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: 2023-09-23 +date: 2023-09-25 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 a5a5c8df08e7d..a3ce537041e5f 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: 2023-09-23 +date: 2023-09-25 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 0d86376b619ab..84ca7e10eb8c5 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_subscription_tracking.mdx b/api_docs/kbn_subscription_tracking.mdx index 505403bb41c1d..fe0bb888f443b 100644 --- a/api_docs/kbn_subscription_tracking.mdx +++ b/api_docs/kbn_subscription_tracking.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-subscription-tracking title: "@kbn/subscription-tracking" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/subscription-tracking plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/subscription-tracking'] --- import kbnSubscriptionTrackingObj from './kbn_subscription_tracking.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 0d675d07b9e83..3cc441b24deff 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: 2023-09-23 +date: 2023-09-25 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 b3ea15ccce2d3..6496939d9eedc 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 6678758a224d5..b34d60d6b550d 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: 2023-09-23 +date: 2023-09-25 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 f458d73b5f5ee..ef1373e4e04a3 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: 2023-09-23 +date: 2023-09-25 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 4f356458e26ce..e645d678a63ea 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 11b9a36b2e677..1d2a423a9e246 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 79bf3d05de6a6..decbd00deb337 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: 2023-09-23 +date: 2023-09-25 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 e8bd5d2c01030..2537e0dc1b876 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: 2023-09-23 +date: 2023-09-25 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 45238562c5a06..d993114d9030e 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: 2023-09-23 +date: 2023-09-25 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 2365cbd72e3f3..038fc61ec1777 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: 2023-09-23 +date: 2023-09-25 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 814b0b74d2d1d..e463b7fe240d5 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: 2023-09-23 +date: 2023-09-25 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 015d1a5e957a1..3d0d1c5c4f2d1 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: 2023-09-23 +date: 2023-09-25 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 bc4ca5a09e92f..a5fdd13cb1cd6 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: 2023-09-23 +date: 2023-09-25 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 990bef17347d1..e05758c82150a 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 3c9c4989bd9b7..2ce6f5decf7b2 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index 5419aabdbd406..48d0dd44260c3 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: 2023-09-23 +date: 2023-09-25 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 58496c15529e6..062a1d9c6a56b 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: 2023-09-23 +date: 2023-09-25 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 061730770d477..1a13b648d4c67 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: 2023-09-23 +date: 2023-09-25 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 bbb70219e9643..f0a30cbc64ba1 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: 2023-09-23 +date: 2023-09-25 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 500691a05c22d..4cbcfbedb9188 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: 2023-09-23 +date: 2023-09-25 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 b55ae3dd26b7d..1c531f6930ab8 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_xstate_utils.mdx b/api_docs/kbn_xstate_utils.mdx index 6749bc0acdc04..79d878c81029a 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: 2023-09-23 +date: 2023-09-25 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 57d0eb2a54f66..ea2dba80cb34e 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 64c71738fd1ff..bdedbca270552 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: 2023-09-23 +date: 2023-09-25 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 b8bbb57aa9a7d..e6e6d1c79f399 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: 2023-09-23 +date: 2023-09-25 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 857ff08f707eb..7b8bd82e4b379 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: 2023-09-23 +date: 2023-09-25 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 a49bd3a46bccc..56e303a369da9 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: 2023-09-23 +date: 2023-09-25 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 9c8779f969fcf..d7c5ee36cf544 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: 2023-09-23 +date: 2023-09-25 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 7a3e53173e0a4..b75acced2933b 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: 2023-09-23 +date: 2023-09-25 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 04f5742dad19d..6be041ab64094 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: 2023-09-23 +date: 2023-09-25 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 88b702a5c12f3..34e62db8ad621 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index a43be54407c42..5d4a9833c3f67 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/log_explorer.mdx b/api_docs/log_explorer.mdx index 79cc70e760856..4458359118c0c 100644 --- a/api_docs/log_explorer.mdx +++ b/api_docs/log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logExplorer title: "logExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the logExplorer plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logExplorer'] --- import logExplorerObj from './log_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index bb51b4616fc98..53896af7ca3ae 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: 2023-09-23 +date: 2023-09-25 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 ced5bb2f102a2..dec665821074d 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: 2023-09-23 +date: 2023-09-25 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 135f42c298236..f786984d06688 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index b7abe55668f45..4080f96be52d9 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/metrics_data_access.mdx b/api_docs/metrics_data_access.mdx index 7764bf0eef124..43e2f158d86d2 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: 2023-09-23 +date: 2023-09-25 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 6637d787668b1..c44412e6d97dd 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 53739e45d3b60..88ae35bb39820 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: 2023-09-23 +date: 2023-09-25 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 92a2b519cd04d..8858bcb67fa2a 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: 2023-09-23 +date: 2023-09-25 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 73cbab3dec857..d6f70e87f6b38 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: 2023-09-23 +date: 2023-09-25 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 43165dd1d71cd..da3b147d0c5cd 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: 2023-09-23 +date: 2023-09-25 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 3b38deb200392..9b8982d43d4d4 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: 2023-09-23 +date: 2023-09-25 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 02a59e803253e..6af21d9d02bbf 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 5b43e6d514445..26b0dfe884c06 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 1bd1869ad42b5..c242ea33b84a3 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_log_explorer.mdx b/api_docs/observability_log_explorer.mdx index 6c42cfbc22d63..efbf8d8ef6964 100644 --- a/api_docs/observability_log_explorer.mdx +++ b/api_docs/observability_log_explorer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityLogExplorer title: "observabilityLogExplorer" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityLogExplorer plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityLogExplorer'] --- import observabilityLogExplorerObj from './observability_log_explorer.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index f7a4e637f015b..ebea39421d24e 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: 2023-09-23 +date: 2023-09-25 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 e3a7a10013991..734af78596c5a 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: 2023-09-23 +date: 2023-09-25 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 f3a2b1408b783..3858846b4cc04 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: 2023-09-23 +date: 2023-09-25 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 1ee005b501640..6796e6142c2df 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: 2023-09-23 +date: 2023-09-25 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 2ad725a1934a1..e581d99af5289 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index ad19848e50526..927abbbb3ee13 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: 2023-09-23 +date: 2023-09-25 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 884a3554ca0c0..47827bb20466e 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: 2023-09-23 +date: 2023-09-25 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 1dfb5832656e1..ff0a1e375d4da 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: 2023-09-23 +date: 2023-09-25 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 9862cbc5b0509..5159030cfa617 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: 2023-09-23 +date: 2023-09-25 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 c705cf7f8d7b8..488642c6f8e01 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: 2023-09-23 +date: 2023-09-25 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 4ce648de64def..4b61f0e98d41f 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: 2023-09-23 +date: 2023-09-25 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 bf8a899db8dde..40ba43446183a 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: 2023-09-23 +date: 2023-09-25 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 e1d5f8fecec35..616ca2ba498b8 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: 2023-09-23 +date: 2023-09-25 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 9816b9d2d9909..703a7351a6a16 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: 2023-09-23 +date: 2023-09-25 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 6a61178b8aa14..73360ea45e933 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: 2023-09-23 +date: 2023-09-25 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 96af1bb9b15db..99bfb91df0e6f 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: 2023-09-23 +date: 2023-09-25 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 eda8a9da84e17..de4d4be113027 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: 2023-09-23 +date: 2023-09-25 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 48cca1b108b26..0e6c7c151cb33 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: 2023-09-23 +date: 2023-09-25 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 d87ecedc28316..6dc1bacc404b9 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: 2023-09-23 +date: 2023-09-25 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 4f328bc7bd5f7..18be4227f6605 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: 2023-09-23 +date: 2023-09-25 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 3f16f0169ec9f..38761b32e479c 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index e75e47bf15d54..98d5fffabba4a 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index c924ab9027dbc..c68539310812e 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 348ca865dcf41..cc41316aed3ff 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: 2023-09-23 +date: 2023-09-25 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 be0ca0dac9f22..8ef81c1dfca95 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: 2023-09-23 +date: 2023-09-25 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 d81e296dd56ac..41a6ccc0869ef 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: 2023-09-23 +date: 2023-09-25 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 1b605273ccb54..50d9d52e50c73 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: 2023-09-23 +date: 2023-09-25 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 8a63db8aa513d..01d50142e9ce9 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: 2023-09-23 +date: 2023-09-25 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 a37ed08840860..cb13977aa0474 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: 2023-09-23 +date: 2023-09-25 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 dcabe79c18dd6..84f7168288c65 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index f9611d7acee4a..f6981f2ac3afc 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: 2023-09-23 +date: 2023-09-25 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 33593c4889e5e..c60ccfacf2789 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: 2023-09-23 +date: 2023-09-25 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 a7d4157f6102d..8a51514e1c06e 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: 2023-09-23 +date: 2023-09-25 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 f636bcd4a2541..40b967ce8965a 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: 2023-09-23 +date: 2023-09-25 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 de16d064fef8e..b96ec3d7afc73 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: 2023-09-23 +date: 2023-09-25 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 d6012d578f44f..978da104cf14b 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: 2023-09-23 +date: 2023-09-25 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 9a5e847d97e00..b05b5cbc2f13b 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: 2023-09-23 +date: 2023-09-25 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 6f90198ee9cc9..96f0f4ceb59d6 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: 2023-09-23 +date: 2023-09-25 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 0f4d84995c105..a0a03154ba4a3 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 526d95c009997..102620c30738e 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 4a7d57c0f47f7..3101b46e527b7 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: 2023-09-23 +date: 2023-09-25 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 80980b11aabb1..6df86f6405a46 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: 2023-09-23 +date: 2023-09-25 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 be3bec59ef21c..b2abf3b5a7fbd 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: 2023-09-23 +date: 2023-09-25 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 348681df6e29b..c71f65522d050 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: 2023-09-23 +date: 2023-09-25 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 e1de16dbd83a3..6732a7c289ec6 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: 2023-09-23 +date: 2023-09-25 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 7ee2c69dc27eb..59462b448fcdc 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: 2023-09-23 +date: 2023-09-25 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 8b8ac9cdd8826..250bdf0cd888d 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: 2023-09-23 +date: 2023-09-25 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 85469f96379f3..1146ce60ba21b 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: 2023-09-23 +date: 2023-09-25 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 8b7624a11694e..b64502052bb92 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: 2023-09-23 +date: 2023-09-25 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 8ad7ec4dae49b..83ef9b6a1b3ba 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: 2023-09-23 +date: 2023-09-25 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 d82f4d5363ecc..482d11bcd7144 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: 2023-09-23 +date: 2023-09-25 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 1cbc0ffb1e847..2777090c13a13 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: 2023-09-23 +date: 2023-09-25 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 ec03d4608c88c..57957d3e2c797 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: 2023-09-23 +date: 2023-09-25 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 0fe50b76863e6..4044e6cbe18d5 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: 2023-09-23 +date: 2023-09-25 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 7e2fa4442fef0..228fb2a2daefc 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: 2023-09-23 +date: 2023-09-25 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 52f1108fbe6ba..52cec1def36a2 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: 2023-09-23 +date: 2023-09-25 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 23b33abf54108..41d0ec04429c0 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: 2023-09-23 +date: 2023-09-25 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 0751478a2b754..b80f235179cc5 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: 2023-09-23 +date: 2023-09-25 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 e81ec0007dd37..dded79de20576 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: 2023-09-23 +date: 2023-09-25 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 bfe5de9e16e9f..9a8a28291e8eb 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: 2023-09-23 +date: 2023-09-25 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 0c753e47ad050..fcf9330494758 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: 2023-09-23 +date: 2023-09-25 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 cf9efdd4381ae..e676666e890e9 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: 2023-09-23 +date: 2023-09-25 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 7f1909e9edcc8..fa7a9edf9e366 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: 2023-09-23 +date: 2023-09-25 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 e86a5d985c5f3..2065f8dfddf38 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: 2023-09-23 +date: 2023-09-25 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 c3d44e19ea066..b24038325797e 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: 2023-09-23 +date: 2023-09-25 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/docs/api-generated/connectors/connector-apis-passthru.asciidoc b/docs/api-generated/connectors/connector-apis-passthru.asciidoc index a8b429e0b5ae4..fb1a9b87dbcda 100644 --- a/docs/api-generated/connectors/connector-apis-passthru.asciidoc +++ b/docs/api-generated/connectors/connector-apis-passthru.asciidoc @@ -1015,6 +1015,8 @@ Any modifications made to this file will be overwritten.
  • config_properties_servicenow - Connector request properties for a ServiceNow ITSM connector
  • config_properties_servicenow_itom - Connector request properties for a ServiceNow ITSM connector
  • config_properties_swimlane - Connector request properties for a Swimlane connector
  • +
  • config_properties_tines - Connector request properties for a Tines connector
  • +
  • config_properties_torq - Connector request properties for a Torq connector
  • config_properties_webhook - Connector request properties for a Webhook connector
  • config_properties_xmatters - Connector request properties for an xMatters connector
  • connector_response_properties - Connector response properties
  • @@ -1035,6 +1037,7 @@ Any modifications made to this file will be overwritten.
  • connector_response_properties_swimlane - Connector response properties for a Swimlane connector
  • connector_response_properties_teams - Connector response properties for a Microsoft Teams connector
  • connector_response_properties_tines - Connector response properties for a Tines connector
  • +
  • connector_response_properties_torq - Connector response properties for a Torq connector
  • connector_response_properties_webhook - Connector response properties for a Webhook connector
  • connector_response_properties_xmatters - Connector response properties for an xMatters connector
  • connector_types - Connector types
  • @@ -1056,6 +1059,7 @@ Any modifications made to this file will be overwritten.
  • create_connector_request_swimlane - Create Swimlane connector request
  • create_connector_request_teams - Create Microsoft Teams connector request
  • create_connector_request_tines - Create Tines connector request
  • +
  • create_connector_request_torq - Create Torq connector request
  • create_connector_request_webhook - Create Webhook connector request
  • create_connector_request_xmatters - Create xMatters connector request
  • features -
  • @@ -1106,6 +1110,8 @@ Any modifications made to this file will be overwritten.
  • secrets_properties_slack_webhook - Connector secrets properties for a Webhook Slack connector
  • secrets_properties_swimlane - Connector secrets properties for a Swimlane connector
  • secrets_properties_teams - Connector secrets properties for a Microsoft Teams connector
  • +
  • secrets_properties_tines - Connector secrets properties for a Tines connector
  • +
  • secrets_properties_torq - Connector secrets properties for a Torq connector
  • secrets_properties_webhook - Connector secrets properties for a Webhook connector
  • secrets_properties_xmatters - Connector secrets properties for an xMatters connector
  • updateConnector_400_response -
  • @@ -1124,6 +1130,8 @@ Any modifications made to this file will be overwritten.
  • update_connector_request_slack_webhook - Update Slack connector request
  • update_connector_request_swimlane - Update Swimlane connector request
  • update_connector_request_teams - Update Microsoft Teams connector request
  • +
  • update_connector_request_tines - Update Tines connector request
  • +
  • update_connector_request_torq - Update Torq connector request
  • update_connector_request_webhook - Update Webhook connector request
  • update_connector_request_xmatters - Update xMatters connector request
  • @@ -1529,6 +1537,20 @@ Any modifications made to this file will be overwritten.
    mappings (optional)
    Connector_mappings_properties_for_a_Swimlane_connector
    +
    +

    config_properties_tines - Connector request properties for a Tines connector Up

    +
    Defines properties for connectors when type is .tines.
    +
    +
    url
    String The Tines tenant URL. If you are using the xpack.actions.allowedHosts setting, make sure this hostname is added to the allowed hosts.
    +
    +
    +
    +

    config_properties_torq - Connector request properties for a Torq connector Up

    +
    Defines properties for connectors when type is .torq.
    +
    +
    webhookIntegrationUrl
    String The endpoint URL of the Elastic Security integration in Torq.
    +
    +

    config_properties_webhook - Connector request properties for a Webhook connector Up

    Defines properties for connectors when type is .webhook.
    @@ -1833,7 +1855,7 @@ Any modifications made to this file will be overwritten.

    connector_response_properties_tines - Connector response properties for a Tines connector Up

    -
    config
    map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .tines.
    +
    config
    connector_type_id
    String The type of connector.
    Enum:
    .tines
    @@ -1842,6 +1864,22 @@ Any modifications made to this file will be overwritten.
    is_missing_secrets (optional)
    Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
    is_preconfigured
    Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
    is_system_action (optional)
    Boolean Indicates whether the connector is used for system actions.
    +
    name
    String The display name for the connector.
    +
    +
    +
    +

    connector_response_properties_torq - Connector response properties for a Torq connector Up

    +
    +
    +
    config
    +
    connector_type_id
    String The type of connector.
    +
    Enum:
    +
    .torq
    +
    id
    String The identifier for the connector.
    +
    is_deprecated
    Boolean Indicates whether the connector type is deprecated.
    +
    is_missing_secrets (optional)
    Boolean Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.
    +
    is_preconfigured
    Boolean Indicates whether it is a preconfigured connector. If true, the config and is_missing_secrets properties are omitted from the response.
    +
    is_system_action (optional)
    Boolean Indicates whether the connector is used for system actions.
    name
    String The display name for the connector.
    @@ -2085,12 +2123,24 @@ Any modifications made to this file will be overwritten.

    create_connector_request_tines - Create Tines connector request Up

    The Tines connector uses Tines Webhook actions to send events via POST request.
    -
    config
    map[String, oas_any_type_not_mapped] Defines properties for connectors when type is .tines.
    +
    config
    config_properties_tines
    connector_type_id
    String The type of connector.
    Enum:
    .tines
    name
    String The display name for the connector.
    -
    secrets
    map[String, oas_any_type_not_mapped] Defines secrets for connectors when type is .tines.
    +
    secrets
    secrets_properties_tines
    +
    + +
    +

    create_connector_request_torq - Create Torq connector request Up

    +
    The Torq connector uses a Torq webhook to trigger workflows with Kibana actions.
    +
    +
    config
    +
    connector_type_id
    String The type of connector.
    +
    Enum:
    +
    .torq
    +
    name
    String The display name for the connector.
    +
    secrets
    @@ -2560,6 +2610,21 @@ Any modifications made to this file will be overwritten.
    webhookUrl
    String The URL of the incoming webhook. If you are using the xpack.actions.allowedHosts setting, add the hostname to the allowed hosts.
    +
    +

    secrets_properties_tines - Connector secrets properties for a Tines connector Up

    +
    Defines secrets for connectors when type is .tines.
    +
    +
    email
    String The email used to sign in to Tines.
    +
    token
    String The Tines API token.
    +
    +
    +
    +

    secrets_properties_torq - Connector secrets properties for a Torq connector Up

    +
    Defines secrets for connectors when type is .torq.
    +
    +
    token
    String The secret of the webhook authentication header.
    +
    +

    secrets_properties_webhook - Connector secrets properties for a Webhook connector Up

    Defines secrets for connectors when type is .webhook.
    @@ -2718,6 +2783,24 @@ Any modifications made to this file will be overwritten.
    secrets
    secrets_properties_teams
    +
    +

    update_connector_request_tines - Update Tines connector request Up

    +
    +
    +
    config
    +
    name
    String The display name for the connector.
    +
    secrets
    +
    +
    +
    +

    update_connector_request_torq - Update Torq connector request Up

    +
    +
    +
    config
    +
    name
    String The display name for the connector.
    +
    secrets
    +
    +

    update_connector_request_webhook - Update Webhook connector request Up

    diff --git a/docs/api/osquery-manager/packs/create.asciidoc b/docs/api/osquery-manager/packs/create.asciidoc index 2fcfc58d43dba..280f6a1d9fe75 100644 --- a/docs/api/osquery-manager/packs/create.asciidoc +++ b/docs/api/osquery-manager/packs/create.asciidoc @@ -33,7 +33,7 @@ experimental[] Create packs. `policy_ids`:: (Optional, array) A list of agents policy IDs. -`shards`:: (Required, object) An object with shard configuration for policies included in the pack. For each policy, set the shard configuration to a percentage (1–100) of target hosts. +`shards`:: (Optional, object) An object with shard configuration for policies included in the pack. For each policy, set the shard configuration to a percentage (1–100) of target hosts. `queries`:: (Required, object) An object of queries. diff --git a/docs/management/action-types.asciidoc b/docs/management/action-types.asciidoc index bbaba806386e2..28aa218f3b6c8 100644 --- a/docs/management/action-types.asciidoc +++ b/docs/management/action-types.asciidoc @@ -7,10 +7,18 @@ Connectors provide a central place to store connection information for services [cols="2"] |=== +a| <> + +| Send a request to D3 Security. + a| <> | Send email from your server. +a| <> + +| Send a request to OpenAI. + a| <> | Create an incident in {ibm-r}. @@ -63,6 +71,10 @@ a| <> | Send events to a Tines Story. +a| <> + +| Trigger a Torq workflow. + a| <> | Send a request to a web service. @@ -75,18 +87,6 @@ a| <> | Send actionable alerts to on-call xMatters resources. -a| <> - -| Trigger a Torq workflow. - -a| <> - -| Send a request to OpenAI. - -a| <> - -| Send a request to D3 Security. - |=== [NOTE] diff --git a/docs/management/connectors/action-types/gen-ai.asciidoc b/docs/management/connectors/action-types/gen-ai.asciidoc index 5e1b3553309ac..6388a483e7fc3 100644 --- a/docs/management/connectors/action-types/gen-ai.asciidoc +++ b/docs/management/connectors/action-types/gen-ai.asciidoc @@ -27,10 +27,11 @@ image::management/connectors/images/gen-ai-connector.png[Generative AI connector Generative AI connectors have the following configuration properties: -Name:: The name of the connector. -API Provider:: The OpenAI API provider, either OpenAI or Azure OpenAI. -API URL:: The OpenAI request URL. -API Key:: The OpenAI or Azure OpenAI API key for authentication. +Name:: The name of the connector. +OpenAI provider:: The OpenAI API provider, either OpenAI or Azure OpenAI. +URL:: The OpenAI request URL. +Default model:: (optional) The default model to use for requests. This option is available only when the provider is `OpenAI`. +API key:: The OpenAI or Azure OpenAI API key for authentication. [float] [[gen-ai-action-configuration]] diff --git a/docs/management/connectors/action-types/tines.asciidoc b/docs/management/connectors/action-types/tines.asciidoc index 218de7cb960f2..cdaf56912d0f0 100644 --- a/docs/management/connectors/action-types/tines.asciidoc +++ b/docs/management/connectors/action-types/tines.asciidoc @@ -3,6 +3,10 @@ ++++ Tines ++++ +:frontmatter-description: Add a connector that can use Tines to send events. +:frontmatter-tags-products: [kibana] +:frontmatter-tags-content-type: [how-to] +:frontmatter-tags-user-goals: [configure] The Tines connector uses Tines's https://www.tines.com/docs/actions/types/webhook[Webhook actions] to send events via POST request. @@ -26,37 +30,6 @@ URL:: The Tines tenant URL. If you are using the <Torq ++++ +:frontmatter-description: Add a connector that can use Torq to trigger workflows. +:frontmatter-tags-products: [kibana] +:frontmatter-tags-content-type: [how-to] +:frontmatter-tags-user-goals: [configure] The Torq connector uses a Torq webhook to trigger workflows with Kibana actions. @@ -27,34 +31,6 @@ Torq endpoint URL:: Endpoint URL (webhook) of the Elastic Security integration y Torq authentication header secret:: Secret of the webhook authentication header. -[float] -[[preconfigured-torq-configuration]] -=== Create preconfigured connectors - -If you are running {kib} on-prem, you can define connectors by -adding `xpack.actions.preconfigured` settings to your `kibana.yml` file. -For example: - -[source,yaml] --- -xpack.actions.preconfigured: - my-torq: - name: preconfigured-torq-connector-type - actionTypeId: .torq - config: - webhookIntegrationUrl: https://hooks.torq.io/v1/somehook - secrets: - token: mytorqtoken --- - -Config defines information for the connector type. - -`webhookIntegrationUrl`:: An address that corresponds to **Torq endpoint URL**. - -Secrets defines sensitive information for the connector type. - -`token`:: A string that corresponds to **Torq authentication header secret**. - [float] [[torq-action-configuration]] === Test connectors diff --git a/docs/management/connectors/images/gen-ai-connector.png b/docs/management/connectors/images/gen-ai-connector.png index e84205723d7cd..4c737414d4e72 100644 Binary files a/docs/management/connectors/images/gen-ai-connector.png and b/docs/management/connectors/images/gen-ai-connector.png differ diff --git a/docs/management/connectors/index.asciidoc b/docs/management/connectors/index.asciidoc index 63de5aca67dca..a30bc26ca2511 100644 --- a/docs/management/connectors/index.asciidoc +++ b/docs/management/connectors/index.asciidoc @@ -1,4 +1,6 @@ +include::action-types/d3security.asciidoc[leveloffset=+1] include::action-types/email.asciidoc[leveloffset=+1] +include::action-types/gen-ai.asciidoc[leveloffset=+1] include::action-types/resilient.asciidoc[leveloffset=+1] include::action-types/index.asciidoc[leveloffset=+1] include::action-types/jira.asciidoc[leveloffset=+1] @@ -16,6 +18,4 @@ include::action-types/torq.asciidoc[leveloffset=+1] include::action-types/webhook.asciidoc[leveloffset=+1] include::action-types/cases-webhook.asciidoc[leveloffset=+1] include::action-types/xmatters.asciidoc[leveloffset=+1] -include::action-types/gen-ai.asciidoc[leveloffset=+1] -include::action-types/d3security.asciidoc[leveloffset=+1] include::pre-configured-connectors.asciidoc[leveloffset=+1] diff --git a/docs/management/connectors/pre-configured-connectors.asciidoc b/docs/management/connectors/pre-configured-connectors.asciidoc index 72f5f78f6e728..8f40554d5bbf3 100644 --- a/docs/management/connectors/pre-configured-connectors.asciidoc +++ b/docs/management/connectors/pre-configured-connectors.asciidoc @@ -113,11 +113,14 @@ Index names must start with `kibana-alert-history-` to take advantage of the pre * <> * <> * <> +* <> * <> * <> * <> * <> * <> +* <> +* <> * <> * <> * <> @@ -528,6 +531,48 @@ xpack.actions.preconfigured: <3> Field mappings for properties such as the alert identifer, severity, and rule name. <4> The API authentication token for HTTP basic authentication. NOTE: This value should be stored in the <>. +[float] +[[preconfigured-tines-configuration]] +==== Tines connectors + +The following example creates a <>: + +[source,text] +-- +xpack.actions.preconfigured: +my-tines: + name: preconfigured-tines-connector-type + actionTypeId: .tines + config: + url: https://some-tenant-2345.tines.com <1> + secrets: + email: some.address@test.com <2> + token: ausergeneratedapitoken <3> +-- +<1> The Tines tenant URL. +<2> The email used to sign in to Tines. +<3> The Tines API token. + +[float] +[[preconfigured-torq-configuration]] +==== Torq connectors + +The following example creates a <>: + +[source,yaml] +-- +xpack.actions.preconfigured: + my-torq: + name: preconfigured-torq-connector-type + actionTypeId: .torq + config: + webhookIntegrationUrl: https://hooks.torq.io/v1/somehook <1> + secrets: + token: mytorqtoken <2> +-- +<1> The endpoint URL of the Elastic Security integration in Torq. +<2> The secret of the webhook authentication header. + [float] [[preconfigured-webhook-configuration]] ==== Webhook connectors diff --git a/docs/management/upgrade-assistant.asciidoc b/docs/management/upgrade-assistant.asciidoc index a44afa4474a7b..ed9093ded2846 100644 --- a/docs/management/upgrade-assistant.asciidoc +++ b/docs/management/upgrade-assistant.asciidoc @@ -26,4 +26,4 @@ The Upgrade assistant pulls information about deprecations from the following so * Elasticsearch deprecation logs * Kibana deprecations API -For more information about the API's the Upgraed assistant provides, refer to <>. +For more information about Upgrade Assistant APIs, refer to <>. diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index c9880bdade4dc..8b05c3108df00 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -420,7 +420,8 @@ NOTE: If you are using the `xpack.actions.allowedHosts` setting, make sure the h A configuration URL that varies by connector: + -- -* For a <>, specifies the D3 Security API request URL. +* For a <>, specifies the D3 Security API request URL. +* For a <>, specifies the Tines tenant URL. * For a <>, specifies the web service request URL. NOTE: If you are using the `xpack.actions.allowedHosts` setting, make sure this hostname is added to the allowed hosts. @@ -432,6 +433,9 @@ For an <>, specifies whether it uses HT `xpack.actions.preconfigured..config.viewIncidentUrl`:: For a <>, specifies a URL string with either the external service ID or external service title Mustache variable to view a case in the external system. +`xpack.actions.preconfigured..config.webhookIntegrationUrl`:: +For a <>, specifies the endpoint URL of the Elastic Security integration in Torq. + `xpack.actions.preconfigured..name`:: The name of the preconfigured connector. @@ -467,7 +471,12 @@ NOTE: The client secret must be URL-encoded. -- `xpack.actions.preconfigured..secrets.email`:: -For a <>, specifies the account email for HTTP basic authentication. +An email address that varies by connector: ++ +-- +* For a <>, specifies the account email for HTTP basic authentication. +* For a <>, specifies the email used to sign in to Tines. +-- `xpack.actions.preconfigured..secrets.password`:: A password secret that varies by connector: @@ -492,6 +501,8 @@ A token secret that varies by connector: -- * For a <>, specifies the D3 Security token. * For a <>, specifies the Slack bot user OAuth token. +* For a <>, specifies the Tines API token. +* For a <>, specifies the secret of the webhook authentication header. -- `xpack.actions.preconfigured..secrets.user`:: diff --git a/package.json b/package.json index eaafb301c5dfc..2749e9b2143c4 100644 --- a/package.json +++ b/package.json @@ -16,9 +16,9 @@ "types": "./kibana.d.ts", "tsdocMetadata": "./build/tsdoc-metadata.json", "build": { + "date": "2023-05-15T23:12:09+0000", "number": 8467, - "sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9", - "date": "2023-05-15T23:12:09+0000" + "sha": "6cb7fec4e154faa0a4a3fee4b33dfef91b9870d9" }, "homepage": "https://www.elastic.co/products/kibana", "bugs": { @@ -66,7 +66,8 @@ "test:ftr:runner": "node scripts/functional_test_runner", "test:ftr:server": "node scripts/functional_tests_server", "test:jest": "node scripts/jest", - "test:jest_integration": "node scripts/jest_integration" + "test:jest_integration": "node scripts/jest_integration", + "test:type_check": "node scripts/type_check" }, "repository": { "type": "git", @@ -1205,6 +1206,7 @@ "@kbn/managed-vscode-config": "link:packages/kbn-managed-vscode-config", "@kbn/managed-vscode-config-cli": "link:packages/kbn-managed-vscode-config-cli", "@kbn/management-storybook-config": "link:packages/kbn-management/storybook/config", + "@kbn/openapi-generator": "link:packages/kbn-openapi-generator", "@kbn/optimizer": "link:packages/kbn-optimizer", "@kbn/optimizer-webpack-helpers": "link:packages/kbn-optimizer-webpack-helpers", "@kbn/peggy": "link:packages/kbn-peggy", diff --git a/packages/kbn-dev-cli-runner/src/flags.ts b/packages/kbn-dev-cli-runner/src/flags.ts index 595205c3e0333..d7b352333ae1b 100644 --- a/packages/kbn-dev-cli-runner/src/flags.ts +++ b/packages/kbn-dev-cli-runner/src/flags.ts @@ -27,6 +27,7 @@ export interface FlagOptions { allowUnexpected?: boolean; guessTypesForUnexpectedFlags?: boolean; help?: string; + examples?: string; alias?: { [key: string]: string | string[] }; boolean?: string[]; string?: string[]; @@ -47,6 +48,7 @@ export function mergeFlagOptions(global: FlagOptions = {}, local: FlagOptions = }, help: local.help, + examples: local.examples, allowUnexpected: !!(global.allowUnexpected || local.allowUnexpected), guessTypesForUnexpectedFlags: !!(global.allowUnexpected || local.allowUnexpected), diff --git a/packages/kbn-dev-cli-runner/src/help.ts b/packages/kbn-dev-cli-runner/src/help.ts index a7dc17aa43f17..f3e0e2c78e97f 100644 --- a/packages/kbn-dev-cli-runner/src/help.ts +++ b/packages/kbn-dev-cli-runner/src/help.ts @@ -36,11 +36,13 @@ export function getHelp({ usage, flagHelp, defaultLogLevel, + examples, }: { description?: string; usage?: string; flagHelp?: string; defaultLogLevel?: string; + examples?: string; }) { const optionHelp = joinAndTrimLines( dedent(flagHelp || ''), @@ -48,13 +50,17 @@ export function getHelp({ GLOBAL_FLAGS ); + const examplesHelp = examples ? joinAndTrimLines('Examples:', examples) : ''; + return ` ${dedent(usage || '') || DEFAULT_GLOBAL_USAGE} ${indent(dedent(description || 'Runs a dev task'), 2)} Options: - ${indent(optionHelp, 4)}\n\n`; + ${indent(optionHelp, 4)} +${examplesHelp ? `\n ${indent(examplesHelp, 4)}` : ''} +`; } export function getCommandLevelHelp({ diff --git a/packages/kbn-dev-cli-runner/src/run.ts b/packages/kbn-dev-cli-runner/src/run.ts index 08457caaebfd4..2ef90c2e2c27a 100644 --- a/packages/kbn-dev-cli-runner/src/run.ts +++ b/packages/kbn-dev-cli-runner/src/run.ts @@ -50,6 +50,7 @@ export async function run(fn: RunFn, options: RunOptions = {}) { usage: options.usage, flagHelp: options.flags?.help, defaultLogLevel: options.log?.defaultLevel, + examples: options.flags?.examples, }); if (flags.help) { diff --git a/packages/kbn-dev-proc-runner/src/proc.ts b/packages/kbn-dev-proc-runner/src/proc.ts index d30a893ae4c75..472d43d66e70d 100644 --- a/packages/kbn-dev-proc-runner/src/proc.ts +++ b/packages/kbn-dev-proc-runner/src/proc.ts @@ -13,7 +13,7 @@ import stripAnsi from 'strip-ansi'; import execa from 'execa'; import * as Rx from 'rxjs'; -import { tap, share, take, mergeMap, map, ignoreElements } from 'rxjs/operators'; +import { tap, share, take, mergeMap, map, ignoreElements, filter } from 'rxjs/operators'; import chalk from 'chalk'; import treeKill from 'tree-kill'; import { ToolingLog } from '@kbn/tooling-log'; @@ -87,13 +87,23 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { const outcome$: Rx.Observable = Rx.race( // observe first exit event - Rx.fromEvent<[number]>(childProcess, 'exit').pipe( + Rx.fromEvent<[number, string]>(childProcess, 'exit').pipe( + filter(([code]) => { + if (stopCalled) { + // when stop was already called, that's a graceful exit, let those events pass. + return true; + } else { + // filtering out further interruption events to prevent `take()` from closing the stream. + return code !== null; + } + }), take(1), map(([code]) => { if (stopCalled) { return null; } - // JVM exits with 143 on SIGTERM and 130 on SIGINT, dont' treat then as errors + + // JVM exits with 143 on SIGTERM and 130 on SIGINT, don't treat them as errors if (code > 0 && !(code === 143 || code === 130)) { throw createFailError(`[${name}] exited with code ${code}`, { exitCode: code, @@ -108,6 +118,12 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { Rx.fromEvent(childProcess, 'error').pipe( take(1), mergeMap((err) => Rx.throwError(err)) + ), + + // observe a promise rejection + Rx.from(childProcess).pipe( + take(1), + mergeMap((err) => Rx.throwError(err)) ) ).pipe(share()); @@ -132,7 +148,7 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { share() ); - const outcomePromise = Rx.merge(lines$.pipe(ignoreElements()), outcome$).toPromise(); + const outcomePromise = Rx.firstValueFrom(Rx.merge(lines$.pipe(ignoreElements()), outcome$)); async function stop(signal: NodeJS.Signals) { if (stopCalled) { diff --git a/packages/kbn-dev-proc-runner/src/proc_runner.ts b/packages/kbn-dev-proc-runner/src/proc_runner.ts index 1226cbeb3eef1..510a96dc043be 100644 --- a/packages/kbn-dev-proc-runner/src/proc_runner.ts +++ b/packages/kbn-dev-proc-runner/src/proc_runner.ts @@ -135,6 +135,9 @@ export class ProcRunner { // wait for process to complete await proc.outcomePromise; } + } catch (e) { + this.log.error(e); + throw e; } finally { // while the procRunner closes promises will resolve/reject because // processes and stopping, but consumers of run() shouldn't have to diff --git a/packages/kbn-es/src/cli_commands/serverless.ts b/packages/kbn-es/src/cli_commands/serverless.ts index 7ee4f08fb94fe..c8b3018e6f669 100644 --- a/packages/kbn-es/src/cli_commands/serverless.ts +++ b/packages/kbn-es/src/cli_commands/serverless.ts @@ -13,9 +13,8 @@ import { getTimeReporter } from '@kbn/ci-stats-reporter'; import { Cluster } from '../cluster'; import { - SERVERLESS_REPO, - SERVERLESS_TAG, - SERVERLESS_IMG, + ES_SERVERLESS_REPO_ELASTICSEARCH, + ES_SERVERLESS_DEFAULT_IMAGE, DEFAULT_PORT, ServerlessOptions, } from '../utils'; @@ -28,9 +27,8 @@ export const serverless: Command = { return dedent` Options: - --tag Image tag of ES serverless to run from ${SERVERLESS_REPO} [default: ${SERVERLESS_TAG}] - --image Full path of ES serverless image to run, has precedence over tag. [default: ${SERVERLESS_IMG}] - + --tag Image tag of ES serverless to run from ${ES_SERVERLESS_REPO_ELASTICSEARCH} + --image Full path of ES serverless image to run, has precedence over tag. [default: ${ES_SERVERLESS_DEFAULT_IMAGE}] --background Start ES serverless without attaching to the first node's logs --basePath Path to the directory where the ES cluster will store data --clean Remove existing file system object store before running @@ -39,14 +37,14 @@ export const serverless: Command = { --ssl Enable HTTP SSL on the ES cluster --skipTeardown If this process exits, leave the ES cluster running in the background --waitForReady Wait for the ES cluster to be ready to serve requests - + -E Additional key=value settings to pass to ES -F Absolute paths for files to mount into containers Examples: - es serverless --tag git-fec36430fba2-x86_64 - es serverless --image docker.elastic.co/repo:tag + es serverless --tag git-fec36430fba2-x86_64 # loads ${ES_SERVERLESS_REPO_ELASTICSEARCH}:git-fec36430fba2-x86_64 + es serverless --image docker.elastic.co/kibana-ci/elasticsearch-serverless:latest-verified `; }, run: async (defaults = {}) => { diff --git a/packages/kbn-es/src/utils/docker.test.ts b/packages/kbn-es/src/utils/docker.test.ts index d48cddd6fdb6d..08edc2a17521d 100644 --- a/packages/kbn-es/src/utils/docker.test.ts +++ b/packages/kbn-es/src/utils/docker.test.ts @@ -23,7 +23,7 @@ import { runDockerContainer, runServerlessCluster, runServerlessEsNode, - SERVERLESS_IMG, + ES_SERVERLESS_DEFAULT_IMAGE, setupServerlessVolumes, stopServerlessCluster, teardownServerlessClusterSync, @@ -451,7 +451,7 @@ describe('runServerlessEsNode()', () => { const node = { params: ['--env', 'foo=bar', '--volume', 'foo/bar'], name: 'es01', - image: SERVERLESS_IMG, + image: ES_SERVERLESS_DEFAULT_IMAGE, }; test('should call the correct Docker command', async () => { @@ -462,7 +462,7 @@ describe('runServerlessEsNode()', () => { expect(execa.mock.calls[0][0]).toEqual('docker'); expect(execa.mock.calls[0][1]).toEqual( expect.arrayContaining([ - SERVERLESS_IMG, + ES_SERVERLESS_DEFAULT_IMAGE, ...node.params, '--name', node.name, @@ -530,7 +530,9 @@ describe('teardownServerlessClusterSync()', () => { teardownServerlessClusterSync(log, defaultOptions); expect(execa.commandSync.mock.calls).toHaveLength(2); - expect(execa.commandSync.mock.calls[0][0]).toEqual(expect.stringContaining(SERVERLESS_IMG)); + expect(execa.commandSync.mock.calls[0][0]).toEqual( + expect.stringContaining(ES_SERVERLESS_DEFAULT_IMAGE) + ); expect(execa.commandSync.mock.calls[1][0]).toEqual(`docker kill ${nodes.join(' ')}`); }); diff --git a/packages/kbn-es/src/utils/docker.ts b/packages/kbn-es/src/utils/docker.ts index 00a1d7ce9dc54..5ed22e094e6f8 100644 --- a/packages/kbn-es/src/utils/docker.ts +++ b/packages/kbn-es/src/utils/docker.ts @@ -38,9 +38,12 @@ import { import { SYSTEM_INDICES_SUPERUSER } from './native_realm'; import { waitUntilClusterReady } from './wait_until_cluster_ready'; -interface BaseOptions { - tag?: string; +interface ImageOptions { image?: string; + tag?: string; +} + +interface BaseOptions extends ImageOptions { port?: number; ssl?: boolean; /** Kill running cluster before starting a new cluster */ @@ -106,9 +109,10 @@ export const DOCKER_REPO = `${DOCKER_REGISTRY}/elasticsearch/elasticsearch`; export const DOCKER_TAG = `${pkg.version}-SNAPSHOT`; export const DOCKER_IMG = `${DOCKER_REPO}:${DOCKER_TAG}`; -export const SERVERLESS_REPO = `${DOCKER_REGISTRY}/elasticsearch-ci/elasticsearch-serverless`; -export const SERVERLESS_TAG = 'latest'; -export const SERVERLESS_IMG = `${SERVERLESS_REPO}:${SERVERLESS_TAG}`; +export const ES_SERVERLESS_REPO_KIBANA = `${DOCKER_REGISTRY}/kibana-ci/elasticsearch-serverless`; +export const ES_SERVERLESS_REPO_ELASTICSEARCH = `${DOCKER_REGISTRY}/elasticsearch-ci/elasticsearch-serverless`; +export const ES_SERVERLESS_LATEST_VERIFIED_TAG = 'latest-verified'; +export const ES_SERVERLESS_DEFAULT_IMAGE = `${ES_SERVERLESS_REPO_KIBANA}:${ES_SERVERLESS_LATEST_VERIFIED_TAG}`; // See for default cluster settings // https://github.com/elastic/elasticsearch-serverless/blob/main/serverless-build-tools/src/main/kotlin/elasticsearch.serverless-run.gradle.kts @@ -275,7 +279,12 @@ export function resolveDockerImage({ image, repo, defaultImg, -}: (ServerlessOptions | DockerOptions) & { repo: string; defaultImg: string }) { +}: { + tag?: string; + image?: string; + repo: string; + defaultImg: string; +}) { if (image) { if (!image.includes(DOCKER_REGISTRY)) { throw createCliError( @@ -525,11 +534,12 @@ export async function setupServerlessVolumes(log: ToolingLog, options: Serverles /** * Resolve the Serverless ES image based on defaults and CLI options */ -function getServerlessImage(options: ServerlessOptions) { +function getServerlessImage({ image, tag }: ImageOptions) { return resolveDockerImage({ - ...options, - repo: SERVERLESS_REPO, - defaultImg: SERVERLESS_IMG, + image, + tag, + repo: ES_SERVERLESS_REPO_ELASTICSEARCH, + defaultImg: ES_SERVERLESS_DEFAULT_IMAGE, }); } @@ -573,7 +583,10 @@ function getESClient(clientOptions: ClientOptions): Client { * Runs an ES Serverless Cluster through Docker */ export async function runServerlessCluster(log: ToolingLog, options: ServerlessOptions) { - const image = getServerlessImage(options); + const image = getServerlessImage({ + image: options.image, + tag: options.tag, + }); await setupDocker({ log, image, options }); const volumeCmd = await setupServerlessVolumes(log, options); @@ -686,8 +699,13 @@ export function teardownServerlessClusterSync(log: ToolingLog, options: Serverle /** * Resolve the Elasticsearch image based on defaults and CLI options */ -function getDockerImage(options: DockerOptions) { - return resolveDockerImage({ ...options, repo: DOCKER_REPO, defaultImg: DOCKER_IMG }); +function getDockerImage({ image, tag }: ImageOptions) { + return resolveDockerImage({ + image, + tag, + repo: DOCKER_REPO, + defaultImg: DOCKER_IMG, + }); } /** @@ -713,7 +731,10 @@ export async function runDockerContainer(log: ToolingLog, options: DockerOptions let image; if (!options.dockerCmd) { - image = getDockerImage(options); + image = getDockerImage({ + image: options.image, + tag: options.tag, + }); await setupDocker({ log, image, options }); } diff --git a/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_cards.test.tsx.snap b/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_cards.test.tsx.snap index ba2969ab4a0b3..f971ca2c40bbb 100644 --- a/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_cards.test.tsx.snap +++ b/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_cards.test.tsx.snap @@ -18,14 +18,20 @@ exports[`guide cards snapshots should render all cards 1`] = ` activeFilter="all" card={ Object { - "icon": "vector", - "navigateTo": Object { - "appId": "enterpriseSearchVectorSearch", - }, + "guideId": "databaseSearch", + "icon": "database", "order": 1, "solution": "search", - "telemetryId": "onboarding--search--vector", - "title": "Set up vector search", + "telemetryId": "onboarding--search--database", + "title": , + } + } + />, } } guidesState={Array []} @@ -44,14 +50,14 @@ exports[`guide cards snapshots should render all cards 1`] = ` activeFilter="all" card={ Object { - "icon": "magnifyWithPlus", + "icon": "vector", "navigateTo": Object { - "appId": "enterpriseSearchAISearch", + "appId": "enterpriseSearchVectorSearch", }, "order": 4, "solution": "search", - "telemetryId": "onboarding--search--semantic", - "title": "Build a semantic search experience", + "telemetryId": "onboarding--search--vector", + "title": "Set up vector search", } } guidesState={Array []} @@ -70,20 +76,14 @@ exports[`guide cards snapshots should render all cards 1`] = ` activeFilter="all" card={ Object { - "guideId": "appSearch", - "icon": "wrench", + "icon": "magnifyWithPlus", + "navigateTo": Object { + "appId": "enterpriseSearchAISearch", + }, "order": 7, "solution": "search", - "telemetryId": "onboarding--search--application", - "title": , - } - } - />, + "telemetryId": "onboarding--search--ai", + "title": "Build an AI-powered search experience", } } guidesState={Array []} @@ -102,12 +102,20 @@ exports[`guide cards snapshots should render all cards 1`] = ` activeFilter="all" card={ Object { - "guideId": "websiteSearch", - "icon": "search", + "guideId": "appSearch", + "icon": "wrench", "order": 10, "solution": "search", - "telemetryId": "onboarding--search--website", - "title": "Add search to my website", + "telemetryId": "onboarding--search--application", + "title": , + } + } + />, } } guidesState={Array []} @@ -126,20 +134,12 @@ exports[`guide cards snapshots should render all cards 1`] = ` activeFilter="all" card={ Object { - "guideId": "databaseSearch", - "icon": "database", + "guideId": "websiteSearch", + "icon": "search", "order": 13, "solution": "search", - "telemetryId": "onboarding--search--database", - "title": , - } - } - />, + "telemetryId": "onboarding--search--website", + "title": "Add search to my website", } } guidesState={Array []} diff --git a/packages/kbn-guided-onboarding/src/components/landing_page/guide_cards.constants.tsx b/packages/kbn-guided-onboarding/src/components/landing_page/guide_cards.constants.tsx index c624f31d2848a..f570f5ea3b87b 100644 --- a/packages/kbn-guided-onboarding/src/components/landing_page/guide_cards.constants.tsx +++ b/packages/kbn-guided-onboarding/src/components/landing_page/guide_cards.constants.tsx @@ -31,6 +31,22 @@ export interface GuideCardConstants { } export const guideCards: GuideCardConstants[] = [ + { + solution: 'search', + icon: 'database', + title: ( + , + }} + /> + ), + guideId: 'databaseSearch', + telemetryId: 'onboarding--search--database', + order: 1, + }, { solution: 'search', icon: 'vector', @@ -41,19 +57,19 @@ export const guideCards: GuideCardConstants[] = [ appId: 'enterpriseSearchVectorSearch', }, telemetryId: 'onboarding--search--vector', - order: 1, + order: 4, }, { solution: 'search', icon: 'magnifyWithPlus', title: i18n.translate('guidedOnboardingPackage.gettingStarted.cards.aiSearch.title', { - defaultMessage: 'Build a semantic search experience', + defaultMessage: 'Build an AI-powered search experience', }), navigateTo: { appId: 'enterpriseSearchAISearch', }, - telemetryId: 'onboarding--search--semantic', - order: 4, + telemetryId: 'onboarding--search--ai', + order: 7, }, { solution: 'search', @@ -69,7 +85,7 @@ export const guideCards: GuideCardConstants[] = [ ), guideId: 'appSearch', telemetryId: 'onboarding--search--application', - order: 7, + order: 10, }, { solution: 'search', @@ -79,22 +95,6 @@ export const guideCards: GuideCardConstants[] = [ }), guideId: 'websiteSearch', telemetryId: 'onboarding--search--website', - order: 10, - }, - { - solution: 'search', - icon: 'database', - title: ( - , - }} - /> - ), - guideId: 'databaseSearch', - telemetryId: 'onboarding--search--database', order: 13, }, { diff --git a/packages/kbn-openapi-generator/README.md b/packages/kbn-openapi-generator/README.md new file mode 100644 index 0000000000000..fc75a76827934 --- /dev/null +++ b/packages/kbn-openapi-generator/README.md @@ -0,0 +1,201 @@ +# OpenAPI Code Generator for Kibana + +This code generator could be used to generate runtime types, documentation, server stub implementations, clients, and much more given OpenAPI specification. + +## Getting started + +To start with code generation you should have OpenAPI specification describing your API endpoint request and response schemas along with common types used in your API. The code generation script supports OpenAPI 3.1.0, refer to https://swagger.io/specification/ for more details. + +OpenAPI specification should be in YAML format and have `.schema.yaml` extension. Here's a simple example of OpenAPI specification: + +```yaml +openapi: 3.0.0 +info: + title: Install Prebuilt Rules API endpoint + version: 2023-10-31 +paths: + /api/detection_engine/rules/prepackaged: + put: + operationId: InstallPrebuiltRules + x-codegen-enabled: true + summary: Installs all Elastic prebuilt rules and timelines + tags: + - Prebuilt Rules API + responses: + 200: + description: Indicates a successful call + content: + application/json: + schema: + type: object + properties: + rules_installed: + type: integer + description: The number of rules installed + minimum: 0 + rules_updated: + type: integer + description: The number of rules updated + minimum: 0 + timelines_installed: + type: integer + description: The number of timelines installed + minimum: 0 + timelines_updated: + type: integer + description: The number of timelines updated + minimum: 0 + required: + - rules_installed + - rules_updated + - timelines_installed + - timelines_updated +``` + +Put it anywhere in your plugin, the code generation script will traverse the whole plugin directory and find all `.schema.yaml` files. + +Then to generate code run the following command: + +```bash +node scripts/generate_openapi --rootDir ./x-pack/plugins/security_solution +``` + +![Generator command output](image.png) + +By default it uses the `zod_operation_schema` template which produces runtime types for request and response schemas described in OpenAPI specification. The generated code will be placed adjacent to the `.schema.yaml` file and will have `.gen.ts` extension. + +Example of generated code: + +```ts +import { z } from 'zod'; + +/* + * NOTICE: Do not edit this file manually. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. + */ + +export type InstallPrebuiltRulesResponse = z.infer; +export const InstallPrebuiltRulesResponse = z.object({ + /** + * The number of rules installed + */ + rules_installed: z.number().int().min(0), + /** + * The number of rules updated + */ + rules_updated: z.number().int().min(0), + /** + * The number of timelines installed + */ + timelines_installed: z.number().int().min(0), + /** + * The number of timelines updated + */ + timelines_updated: z.number().int().min(0), +}); +``` +## Programmatic API + +Alternatively, you can use the code generator programmatically. You can create a script file and run it with `node` command. This could be useful if you want to set up code generation in your CI pipeline. Here's an example of such script: + +```ts +require('../../../../../src/setup_node_env'); +const { generate } = require('@kbn/openapi-generator'); +const { resolve } = require('path'); + +const SECURITY_SOLUTION_ROOT = resolve(__dirname, '../..'); + +generate({ + rootDir: SECURITY_SOLUTION_ROOT, // Path to the plugin root directory + sourceGlob: './**/*.schema.yaml', // Glob pattern to find OpenAPI specification files + templateName: 'zod_operation_schema', // Name of the template to use +}); +``` + +## CI integration + +To make sure that generated code is always in sync with its OpenAPI specification it is recommended to add a command to your CI pipeline that will run code generation on every pull request and commit the changes if there are any. + +First, create a script that will run code generation and commit the changes. See `.buildkite/scripts/steps/code_generation/security_solution_codegen.sh` for an example: + +```bash +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/common/util.sh + +.buildkite/scripts/bootstrap.sh + +echo --- Security Solution OpenAPI Code Generation + +(cd x-pack/plugins/security_solution && yarn openapi:generate) +check_for_changed_files "yarn openapi:generate" true +``` + +This scripts sets up the minimal environment required fro code generation and runs the code generation script. Then it checks if there are any changes and commits them if there are any using the `check_for_changed_files` function. + +Then add the code generation script to your plugin build pipeline. Open your plugin build pipeline, for example `.buildkite/pipelines/pull_request/security_solution.yml`, and add the following command to the steps list adjusting the path to your code generation script: + +```yaml + - command: .buildkite/scripts/steps/code_generation/security_solution_codegen.sh + label: 'Security Solution OpenAPI codegen' + agents: + queue: n2-2-spot + timeout_in_minutes: 60 + parallelism: 1 +``` + +Now on every pull request the code generation script will run and commit the changes if there are any. + +## OpenAPI Schema + +The code generator supports the OpenAPI definitions described in the request, response, and component sections of the document. + +For every API operation (GET, POST, etc) it is required to specify the `operationId` field. This field is used to generate the name of the generated types. For example, if the `operationId` is `InstallPrebuiltRules` then the generated types will be named `InstallPrebuiltRulesResponse` and `InstallPrebuiltRulesRequest`. If the `operationId` is not specified then the code generation will throw an error. + +The `x-codegen-enabled` field is used to enable or disable code generation for the operation. If it is not specified then code generation is disabled by default. This field could be also used to disable code generation of common components described in the `components` section of the OpenAPI specification. + +Keep in mind that disabling code generation for common components that are referenced by external OpenAPI specifications could lead to errors during code generation. + +### Schema files organization + +It is recommended to limit the number of operations and components described in a single OpenAPI specification file. Having one HTTP operation in a single file will make it easier to maintain and will keep the generated artifacts granular for ease of reuse and better tree shaking. You can have as many OpenAPI specification files as you want. + +### Common components + +It is common to have shared types that are used in multiple API operations. To avoid code duplication you can define common components in the `components` section of the OpenAPI specification and put them in a separate file. Then you can reference these components in the `parameters` and `responses` sections of the API operations. + +Here's an example of the schema that references common components: + +```yaml +openapi: 3.0.0 +info: + title: Delete Rule API endpoint + version: 2023-10-31 +paths: + /api/detection_engine/rules: + delete: + operationId: DeleteRule + description: Deletes a single rule using the `rule_id` or `id` field. + parameters: + - name: id + in: query + required: false + description: The rule's `id` value. + schema: + $ref: '../../../model/rule_schema/common_attributes.schema.yaml#/components/schemas/RuleSignatureId' + - name: rule_id + in: query + required: false + description: The rule's `rule_id` value. + schema: + $ref: '../../../model/rule_schema/common_attributes.schema.yaml#/components/schemas/RuleObjectId' + responses: + 200: + description: Indicates a successful call. + content: + application/json: + schema: + $ref: '../../../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/RuleResponse' +``` diff --git a/packages/kbn-openapi-generator/image.png b/packages/kbn-openapi-generator/image.png new file mode 100644 index 0000000000000..e8710d78b80b6 Binary files /dev/null and b/packages/kbn-openapi-generator/image.png differ diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_config_page/index.tsx b/packages/kbn-openapi-generator/index.ts similarity index 79% rename from src/plugins/kibana_react/public/page_template/no_data_page/no_data_config_page/index.tsx rename to packages/kbn-openapi-generator/index.ts index 0bdde40021398..eeaad5343dc9f 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_config_page/index.tsx +++ b/packages/kbn-openapi-generator/index.ts @@ -6,4 +6,5 @@ * Side Public License, v 1. */ -export { NoDataConfigPage, NoDataConfigPageWithSolutionNavBar } from './no_data_config_page'; +export * from './src/openapi_generator'; +export * from './src/cli'; diff --git a/src/plugins/kibana_react/public/page_template/util/constants.ts b/packages/kbn-openapi-generator/jest.config.js similarity index 52% rename from src/plugins/kibana_react/public/page_template/util/constants.ts rename to packages/kbn-openapi-generator/jest.config.js index 159a6d0d8d4c1..6b5b1fce1c4d4 100644 --- a/src/plugins/kibana_react/public/page_template/util/constants.ts +++ b/packages/kbn-openapi-generator/jest.config.js @@ -6,15 +6,8 @@ * Side Public License, v 1. */ -import { KibanaPageTemplateProps } from '../page_template'; - -export const NO_DATA_PAGE_MAX_WIDTH = 950; - -export const NO_DATA_PAGE_TEMPLATE_PROPS: KibanaPageTemplateProps = { - restrictWidth: NO_DATA_PAGE_MAX_WIDTH, - template: 'centeredBody', - pageContentProps: { - hasShadow: false, - color: 'transparent', - }, +module.exports = { + preset: '@kbn/test', + rootDir: '../..', + roots: ['/packages/kbn-openapi-generator'], }; diff --git a/packages/kbn-openapi-generator/kibana.jsonc b/packages/kbn-openapi-generator/kibana.jsonc new file mode 100644 index 0000000000000..b507d94ec022d --- /dev/null +++ b/packages/kbn-openapi-generator/kibana.jsonc @@ -0,0 +1,6 @@ +{ + "devOnly": true, + "id": "@kbn/openapi-generator", + "owner": "@elastic/security-detection-engine", + "type": "shared-common" +} diff --git a/packages/kbn-openapi-generator/package.json b/packages/kbn-openapi-generator/package.json new file mode 100644 index 0000000000000..5847d729d025c --- /dev/null +++ b/packages/kbn-openapi-generator/package.json @@ -0,0 +1,10 @@ +{ + "bin": { + "openapi-generator": "./bin/openapi-generator.js" + }, + "description": "OpenAPI code generator for Kibana", + "license": "SSPL-1.0 OR Elastic License 2.0", + "name": "@kbn/openapi-generator", + "private": true, + "version": "1.0.0" +} diff --git a/packages/kbn-openapi-generator/src/cli.ts b/packages/kbn-openapi-generator/src/cli.ts new file mode 100644 index 0000000000000..9eb91dd9bba94 --- /dev/null +++ b/packages/kbn-openapi-generator/src/cli.ts @@ -0,0 +1,44 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ +import yargs from 'yargs/yargs'; +import { generate } from './openapi_generator'; +import { AVAILABLE_TEMPLATES } from './template_service/template_service'; + +export function runCli() { + yargs(process.argv.slice(2)) + .command( + '*', + 'Generate code artifacts from OpenAPI specifications', + (y) => + y + .option('rootDir', { + describe: 'Root directory to search for OpenAPI specs', + demandOption: true, + string: true, + }) + .option('sourceGlob', { + describe: 'Elasticsearch target', + default: './**/*.schema.yaml', + string: true, + }) + .option('templateName', { + describe: 'Template to use for code generation', + default: 'zod_operation_schema' as const, + choices: AVAILABLE_TEMPLATES, + }) + .showHelpOnFail(false), + (argv) => { + generate(argv).catch((err) => { + // eslint-disable-next-line no-console + console.error(err); + process.exit(1); + }); + } + ) + .parse(); +} diff --git a/x-pack/plugins/security_solution/scripts/openapi/lib/fix_eslint.ts b/packages/kbn-openapi-generator/src/lib/fix_eslint.ts similarity index 62% rename from x-pack/plugins/security_solution/scripts/openapi/lib/fix_eslint.ts rename to packages/kbn-openapi-generator/src/lib/fix_eslint.ts index 23d8bf540f731..c205dbcebf164 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/lib/fix_eslint.ts +++ b/packages/kbn-openapi-generator/src/lib/fix_eslint.ts @@ -1,19 +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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import execa from 'execa'; -import { resolve } from 'path'; - -const KIBANA_ROOT = resolve(__dirname, '../../../../../../'); +import { REPO_ROOT } from '@kbn/repo-info'; export async function fixEslint(path: string) { await execa('npx', ['eslint', '--fix', path], { // Need to run eslint from the Kibana root directory, otherwise it will not // be able to pick up the right config - cwd: KIBANA_ROOT, + cwd: REPO_ROOT, }); } diff --git a/x-pack/plugins/security_solution/scripts/openapi/lib/format_output.ts b/packages/kbn-openapi-generator/src/lib/format_output.ts similarity index 61% rename from x-pack/plugins/security_solution/scripts/openapi/lib/format_output.ts rename to packages/kbn-openapi-generator/src/lib/format_output.ts index 6c374aa1f06d2..7b50b0732009b 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/lib/format_output.ts +++ b/packages/kbn-openapi-generator/src/lib/format_output.ts @@ -1,8 +1,9 @@ /* * 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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import execa from 'execa'; diff --git a/packages/kbn-openapi-generator/src/lib/get_generated_file_path.ts b/packages/kbn-openapi-generator/src/lib/get_generated_file_path.ts new file mode 100644 index 0000000000000..4139d3610d8b6 --- /dev/null +++ b/packages/kbn-openapi-generator/src/lib/get_generated_file_path.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 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 or the Server + * Side Public License, v 1. + */ + +export function getGeneratedFilePath(sourcePath: string) { + return sourcePath.replace(/\..+$/, '.gen.ts'); +} diff --git a/x-pack/plugins/security_solution/scripts/openapi/lib/remove_gen_artifacts.ts b/packages/kbn-openapi-generator/src/lib/remove_gen_artifacts.ts similarity index 75% rename from x-pack/plugins/security_solution/scripts/openapi/lib/remove_gen_artifacts.ts rename to packages/kbn-openapi-generator/src/lib/remove_gen_artifacts.ts index 3cbf421b8c94b..45933864faf8f 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/lib/remove_gen_artifacts.ts +++ b/packages/kbn-openapi-generator/src/lib/remove_gen_artifacts.ts @@ -1,8 +1,9 @@ /* * 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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import fs from 'fs/promises'; diff --git a/packages/kbn-openapi-generator/src/openapi_generator.ts b/packages/kbn-openapi-generator/src/openapi_generator.ts new file mode 100644 index 0000000000000..539994a258126 --- /dev/null +++ b/packages/kbn-openapi-generator/src/openapi_generator.ts @@ -0,0 +1,77 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +/* eslint-disable no-console */ + +import SwaggerParser from '@apidevtools/swagger-parser'; +import chalk from 'chalk'; +import fs from 'fs/promises'; +import globby from 'globby'; +import { resolve } from 'path'; +import { fixEslint } from './lib/fix_eslint'; +import { formatOutput } from './lib/format_output'; +import { getGeneratedFilePath } from './lib/get_generated_file_path'; +import { removeGenArtifacts } from './lib/remove_gen_artifacts'; +import { getGenerationContext } from './parser/get_generation_context'; +import type { OpenApiDocument } from './parser/openapi_types'; +import { initTemplateService, TemplateName } from './template_service/template_service'; + +export interface GeneratorConfig { + rootDir: string; + sourceGlob: string; + templateName: TemplateName; +} + +export const generate = async (config: GeneratorConfig) => { + const { rootDir, sourceGlob, templateName } = config; + + console.log(chalk.bold(`Generating API route schemas`)); + console.log(chalk.bold(`Working directory: ${chalk.underline(rootDir)}`)); + + console.log(`👀 Searching for source files`); + const sourceFilesGlob = resolve(rootDir, sourceGlob); + const schemaPaths = await globby([sourceFilesGlob]); + + console.log(`🕵️‍♀️ Found ${schemaPaths.length} schemas, parsing`); + const parsedSources = await Promise.all( + schemaPaths.map(async (sourcePath) => { + const parsedSchema = (await SwaggerParser.parse(sourcePath)) as OpenApiDocument; + return { sourcePath, parsedSchema }; + }) + ); + + console.log(`🧹 Cleaning up any previously generated artifacts`); + await removeGenArtifacts(rootDir); + + console.log(`🪄 Generating new artifacts`); + const TemplateService = await initTemplateService(); + await Promise.all( + parsedSources.map(async ({ sourcePath, parsedSchema }) => { + const generationContext = getGenerationContext(parsedSchema); + + // If there are no operations or components to generate, skip this file + const shouldGenerate = + generationContext.operations.length > 0 || generationContext.components !== undefined; + if (!shouldGenerate) { + return; + } + + const result = TemplateService.compileTemplate(templateName, generationContext); + + // Write the generation result to disk + await fs.writeFile(getGeneratedFilePath(sourcePath), result); + }) + ); + + // Format the output folder using prettier as the generator produces + // unformatted code and fix any eslint errors + console.log(`💅 Formatting output`); + const generatedArtifactsGlob = resolve(rootDir, './**/*.gen.ts'); + await formatOutput(generatedArtifactsGlob); + await fixEslint(generatedArtifactsGlob); +}; diff --git a/packages/kbn-openapi-generator/src/parser/get_generation_context.ts b/packages/kbn-openapi-generator/src/parser/get_generation_context.ts new file mode 100644 index 0000000000000..14a3b8eb2e178 --- /dev/null +++ b/packages/kbn-openapi-generator/src/parser/get_generation_context.ts @@ -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 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 or the Server + * Side Public License, v 1. + */ + +import { OpenAPIV3 } from 'openapi-types'; +import { getApiOperationsList } from './lib/get_api_operations_list'; +import { getComponents } from './lib/get_components'; +import { getImportsMap, ImportsMap } from './lib/get_imports_map'; +import { normalizeSchema } from './lib/normalize_schema'; +import { NormalizedOperation, OpenApiDocument } from './openapi_types'; + +export interface GenerationContext { + components: OpenAPIV3.ComponentsObject | undefined; + operations: NormalizedOperation[]; + imports: ImportsMap; +} + +export function getGenerationContext(document: OpenApiDocument): GenerationContext { + const normalizedDocument = normalizeSchema(document); + + const components = getComponents(normalizedDocument); + const operations = getApiOperationsList(normalizedDocument); + const imports = getImportsMap(normalizedDocument); + + return { + components, + operations, + imports, + }; +} diff --git a/x-pack/plugins/security_solution/scripts/openapi/parsers/get_api_operations_list.ts b/packages/kbn-openapi-generator/src/parser/lib/get_api_operations_list.ts similarity index 87% rename from x-pack/plugins/security_solution/scripts/openapi/parsers/get_api_operations_list.ts rename to packages/kbn-openapi-generator/src/parser/lib/get_api_operations_list.ts index c9d9a75c07854..ac63820555419 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/parsers/get_api_operations_list.ts +++ b/packages/kbn-openapi-generator/src/parser/lib/get_api_operations_list.ts @@ -1,12 +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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import { OpenAPIV3 } from 'openapi-types'; -import type { NormalizedOperation, ObjectSchema, OpenApiDocument } from './openapi_types'; +import type { + NormalizedOperation, + NormalizedSchemaItem, + ObjectSchema, + OpenApiDocument, +} from '../openapi_types'; const HTTP_METHODS = Object.values(OpenAPIV3.HttpMethods); @@ -61,14 +67,12 @@ export function getApiOperationsList(parsedSchema: OpenApiDocument): NormalizedO `Cannot generate response for ${method} ${path}: $ref in response is not supported` ); } - const response = operation.responses?.['200']?.content?.['application/json']?.schema; if (operation.requestBody && '$ref' in operation.requestBody) { throw new Error( `Cannot generate request for ${method} ${path}: $ref in request body is not supported` ); } - const requestBody = operation.requestBody?.content?.['application/json']?.schema; const { operationId, description, tags, deprecated } = operation; @@ -78,7 +82,13 @@ export function getApiOperationsList(parsedSchema: OpenApiDocument): NormalizedO throw new Error(`Missing operationId for ${method} ${path}`); } - return { + const response = operation.responses?.['200']?.content?.['application/json']?.schema as + | NormalizedSchemaItem + | undefined; + const requestBody = operation.requestBody?.content?.['application/json']?.schema as + | NormalizedSchemaItem + | undefined; + const normalizedOperation: NormalizedOperation = { path, method, operationId, @@ -90,6 +100,8 @@ export function getApiOperationsList(parsedSchema: OpenApiDocument): NormalizedO requestBody, response, }; + + return normalizedOperation; }); } ); diff --git a/x-pack/plugins/security_solution/scripts/openapi/parsers/get_components.ts b/packages/kbn-openapi-generator/src/parser/lib/get_components.ts similarity index 59% rename from x-pack/plugins/security_solution/scripts/openapi/parsers/get_components.ts rename to packages/kbn-openapi-generator/src/parser/lib/get_components.ts index 5b3fef72905c0..6e98793de1afb 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/parsers/get_components.ts +++ b/packages/kbn-openapi-generator/src/parser/lib/get_components.ts @@ -1,15 +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. + * 2.0 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 or the Server + * Side Public License, v 1. */ -import type { OpenApiDocument } from './openapi_types'; +import type { OpenApiDocument } from '../openapi_types'; export function getComponents(parsedSchema: OpenApiDocument) { if (parsedSchema.components?.['x-codegen-enabled'] === false) { return undefined; } + return parsedSchema.components; } diff --git a/x-pack/plugins/security_solution/scripts/openapi/parsers/get_imports_map.ts b/packages/kbn-openapi-generator/src/parser/lib/get_imports_map.ts similarity index 76% rename from x-pack/plugins/security_solution/scripts/openapi/parsers/get_imports_map.ts rename to packages/kbn-openapi-generator/src/parser/lib/get_imports_map.ts index 8e068b61ba034..c2259052e0cb6 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/parsers/get_imports_map.ts +++ b/packages/kbn-openapi-generator/src/parser/lib/get_imports_map.ts @@ -1,12 +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; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 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 or the Server + * Side Public License, v 1. */ import { uniq } from 'lodash'; -import type { OpenApiDocument } from './openapi_types'; +import type { OpenApiDocument } from '../openapi_types'; +import { traverseObject } from './traverse_object'; export interface ImportsMap { [importPath: string]: string[]; @@ -55,23 +57,11 @@ const hasRef = (obj: unknown): obj is { $ref: string } => { function findRefs(obj: unknown): string[] { const refs: string[] = []; - function search(element: unknown) { - if (typeof element === 'object' && element !== null) { - if (hasRef(element)) { - refs.push(element.$ref); - } - - Object.values(element).forEach((value) => { - if (Array.isArray(value)) { - value.forEach(search); - } else { - search(value); - } - }); + traverseObject(obj, (element) => { + if (hasRef(element)) { + refs.push(element.$ref); } - } - - search(obj); + }); return refs; } diff --git a/packages/kbn-openapi-generator/src/parser/lib/normalize_schema.ts b/packages/kbn-openapi-generator/src/parser/lib/normalize_schema.ts new file mode 100644 index 0000000000000..0ea2062e369c3 --- /dev/null +++ b/packages/kbn-openapi-generator/src/parser/lib/normalize_schema.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 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 or the Server + * Side Public License, v 1. + */ + +import { OpenAPIV3 } from 'openapi-types'; +import { NormalizedReferenceObject } from '../openapi_types'; +import { traverseObject } from './traverse_object'; + +/** + * Check if an object has a $ref property + * + * @param obj Any object + * @returns True if the object has a $ref property + */ +const hasRef = (obj: unknown): obj is NormalizedReferenceObject => { + return typeof obj === 'object' && obj !== null && '$ref' in obj; +}; + +export function normalizeSchema(schema: OpenAPIV3.Document) { + traverseObject(schema, (element) => { + if (hasRef(element)) { + const referenceName = element.$ref.split('/').pop(); + if (!referenceName) { + throw new Error(`Cannot parse reference name: ${element.$ref}`); + } + + element.referenceName = referenceName; + } + }); + + return schema; +} diff --git a/packages/kbn-openapi-generator/src/parser/lib/traverse_object.ts b/packages/kbn-openapi-generator/src/parser/lib/traverse_object.ts new file mode 100644 index 0000000000000..2049465e0753b --- /dev/null +++ b/packages/kbn-openapi-generator/src/parser/lib/traverse_object.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 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 or the Server + * Side Public License, v 1. + */ + +/** + * A generic function to traverse an object or array of objects recursively + * + * @param obj The object to traverse + * @param onVisit A function that will be called for each traversed node in the object + */ +export function traverseObject(obj: unknown, onVisit: (element: object) => void) { + function search(element: unknown) { + if (typeof element === 'object' && element !== null) { + onVisit(element); + + Object.values(element).forEach((value) => { + if (Array.isArray(value)) { + value.forEach(search); + } else { + search(value); + } + }); + } + } + + search(obj); +} diff --git a/x-pack/plugins/security_solution/scripts/openapi/parsers/openapi_types.ts b/packages/kbn-openapi-generator/src/parser/openapi_types.ts similarity index 62% rename from x-pack/plugins/security_solution/scripts/openapi/parsers/openapi_types.ts rename to packages/kbn-openapi-generator/src/parser/openapi_types.ts index 2449f34fa4b76..c8b1e4f715345 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/parsers/openapi_types.ts +++ b/packages/kbn-openapi-generator/src/parser/openapi_types.ts @@ -1,8 +1,9 @@ /* * 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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import type { OpenAPIV3 } from 'openapi-types'; @@ -27,6 +28,21 @@ declare module 'openapi-types' { } } +export type NormalizedReferenceObject = OpenAPIV3.ReferenceObject & { + referenceName: string; +}; + +export interface UnknownType { + type: 'unknown'; +} + +export type NormalizedSchemaObject = + | OpenAPIV3.ArraySchemaObject + | OpenAPIV3.NonArraySchemaObject + | UnknownType; + +export type NormalizedSchemaItem = OpenAPIV3.SchemaObject | NormalizedReferenceObject; + /** * OpenAPI types do not have a dedicated type for objects, so we need to create * to use for path and query parameters @@ -36,7 +52,7 @@ export interface ObjectSchema { required: string[]; description?: string; properties: { - [name: string]: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject; + [name: string]: NormalizedSchemaItem; }; } @@ -50,8 +66,8 @@ export interface NormalizedOperation { description?: string; tags?: string[]; deprecated?: boolean; - requestParams?: ObjectSchema; - requestQuery?: ObjectSchema; - requestBody?: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject; - response?: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject; + requestParams?: NormalizedSchemaItem; + requestQuery?: NormalizedSchemaItem; + requestBody?: NormalizedSchemaItem; + response?: NormalizedSchemaItem; } diff --git a/x-pack/plugins/security_solution/scripts/openapi/template_service/register_helpers.ts b/packages/kbn-openapi-generator/src/template_service/register_helpers.ts similarity index 75% rename from x-pack/plugins/security_solution/scripts/openapi/template_service/register_helpers.ts rename to packages/kbn-openapi-generator/src/template_service/register_helpers.ts index b3bb02f7743c8..1431dafcdfba9 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/template_service/register_helpers.ts +++ b/packages/kbn-openapi-generator/src/template_service/register_helpers.ts @@ -1,8 +1,9 @@ /* * 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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import type Handlebars from '@kbn/handlebars'; @@ -13,9 +14,6 @@ export function registerHelpers(handlebarsInstance: typeof Handlebars) { const values = args.slice(0, -1) as unknown[]; return values.join(''); }); - handlebarsInstance.registerHelper('parseRef', (refName: string) => { - return refName.split('/').pop(); - }); handlebarsInstance.registerHelper('snakeCase', snakeCase); handlebarsInstance.registerHelper('camelCase', camelCase); handlebarsInstance.registerHelper('toJSON', (value: unknown) => { @@ -43,13 +41,4 @@ export function registerHelpers(handlebarsInstance: typeof Handlebars) { handlebarsInstance.registerHelper('isUnknown', (val: object) => { return !('type' in val || '$ref' in val || 'anyOf' in val || 'oneOf' in val || 'allOf' in val); }); - handlebarsInstance.registerHelper('isEmpty', (val) => { - if (Array.isArray(val)) { - return val.length === 0; - } - if (typeof val === 'object') { - return Object.keys(val).length === 0; - } - return val === undefined || val === null || val === ''; - }); } diff --git a/x-pack/plugins/security_solution/scripts/openapi/template_service/register_templates.ts b/packages/kbn-openapi-generator/src/template_service/register_templates.ts similarity index 83% rename from x-pack/plugins/security_solution/scripts/openapi/template_service/register_templates.ts rename to packages/kbn-openapi-generator/src/template_service/register_templates.ts index fa39b52d99471..b8f9711ecb1a6 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/template_service/register_templates.ts +++ b/packages/kbn-openapi-generator/src/template_service/register_templates.ts @@ -1,8 +1,9 @@ /* * 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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import type Handlebars from '@kbn/handlebars'; diff --git a/x-pack/plugins/security_solution/scripts/openapi/template_service/template_service.ts b/packages/kbn-openapi-generator/src/template_service/template_service.ts similarity index 60% rename from x-pack/plugins/security_solution/scripts/openapi/template_service/template_service.ts rename to packages/kbn-openapi-generator/src/template_service/template_service.ts index becb02bb54ebe..9980282bbfdc3 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/template_service/template_service.ts +++ b/packages/kbn-openapi-generator/src/template_service/template_service.ts @@ -1,28 +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. + * 2.0 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 or the Server + * Side Public License, v 1. */ import Handlebars from 'handlebars'; -import type { OpenAPIV3 } from 'openapi-types'; import { resolve } from 'path'; -import type { ImportsMap } from '../parsers/get_imports_map'; -import type { NormalizedOperation } from '../parsers/openapi_types'; +import { GenerationContext } from '../parser/get_generation_context'; import { registerHelpers } from './register_helpers'; import { registerTemplates } from './register_templates'; -export interface TemplateContext { - importsMap: ImportsMap; - apiOperations: NormalizedOperation[]; - components: OpenAPIV3.ComponentsObject | undefined; -} +export const AVAILABLE_TEMPLATES = ['zod_operation_schema'] as const; -export type TemplateName = 'schemas'; +export type TemplateName = typeof AVAILABLE_TEMPLATES[number]; export interface ITemplateService { - compileTemplate: (templateName: TemplateName, context: TemplateContext) => string; + compileTemplate: (templateName: TemplateName, context: GenerationContext) => string; } /** @@ -36,7 +31,7 @@ export const initTemplateService = async (): Promise => { const templates = await registerTemplates(resolve(__dirname, './templates'), handlebars); return { - compileTemplate: (templateName: TemplateName, context: TemplateContext) => { + compileTemplate: (templateName: TemplateName, context: GenerationContext) => { return handlebars.compile(templates[templateName])(context); }, }; diff --git a/x-pack/plugins/security_solution/scripts/openapi/template_service/templates/disclaimer.handlebars b/packages/kbn-openapi-generator/src/template_service/templates/disclaimer.handlebars similarity index 81% rename from x-pack/plugins/security_solution/scripts/openapi/template_service/templates/disclaimer.handlebars rename to packages/kbn-openapi-generator/src/template_service/templates/disclaimer.handlebars index 4be0a93d1b79e..403a5b54f09b3 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/template_service/templates/disclaimer.handlebars +++ b/packages/kbn-openapi-generator/src/template_service/templates/disclaimer.handlebars @@ -1,5 +1,5 @@ /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ \ No newline at end of file diff --git a/x-pack/plugins/security_solution/scripts/openapi/template_service/templates/schemas.handlebars b/packages/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars similarity index 75% rename from x-pack/plugins/security_solution/scripts/openapi/template_service/templates/schemas.handlebars rename to packages/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars index a6df5d96b124f..0b129b3aa13ed 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/template_service/templates/schemas.handlebars +++ b/packages/kbn-openapi-generator/src/template_service/templates/zod_operation_schema.handlebars @@ -9,7 +9,7 @@ import { z } from "zod"; {{> disclaimer}} -{{#each importsMap}} +{{#each imports}} import { {{#each this}}{{.}},{{/each}} } from "{{@key}}" @@ -22,11 +22,15 @@ import { */ {{/description}} export type {{@key}} = z.infer; -export const {{@key}} = {{> schema_item}}; +export const {{@key}} = {{> zod_schema_item}}; +{{#if enum}} +export const {{@key}}Enum = {{@key}}.enum; +export type {{@key}}Enum = typeof {{@key}}.enum; +{{/if}} {{/each}} -{{#each apiOperations}} +{{#each operations}} {{#if requestQuery}} {{#if requestQuery.description}} /** @@ -34,7 +38,7 @@ export const {{@key}} = {{> schema_item}}; */ {{/if}} export type {{operationId}}RequestQuery = z.infer; -export const {{operationId}}RequestQuery = {{> schema_item requestQuery }}; +export const {{operationId}}RequestQuery = {{> zod_query_item requestQuery }}; export type {{operationId}}RequestQueryInput = z.input; {{/if}} @@ -45,7 +49,7 @@ export type {{operationId}}RequestQueryInput = z.input; -export const {{operationId}}RequestParams = {{> schema_item requestParams }}; +export const {{operationId}}RequestParams = {{> zod_schema_item requestParams }}; export type {{operationId}}RequestParamsInput = z.input; {{/if}} @@ -56,7 +60,7 @@ export type {{operationId}}RequestParamsInput = z.input; -export const {{operationId}}RequestBody = {{> schema_item requestBody }}; +export const {{operationId}}RequestBody = {{> zod_schema_item requestBody }}; export type {{operationId}}RequestBodyInput = z.input; {{/if}} @@ -67,6 +71,6 @@ export type {{operationId}}RequestBodyInput = z.input; -export const {{operationId}}Response = {{> schema_item response }}; +export const {{operationId}}Response = {{> zod_schema_item response }}; {{/if}} {{/each}} diff --git a/packages/kbn-openapi-generator/src/template_service/templates/zod_query_item.handlebars b/packages/kbn-openapi-generator/src/template_service/templates/zod_query_item.handlebars new file mode 100644 index 0000000000000..0b718d941cbed --- /dev/null +++ b/packages/kbn-openapi-generator/src/template_service/templates/zod_query_item.handlebars @@ -0,0 +1,51 @@ +{{~#if $ref~}} + {{referenceName}} + {{~#if nullable}}.nullable(){{/if~}} + {{~#if (eq requiredBool false)}}.optional(){{/if~}} + {{~#if (defined default)}}.default({{{toJSON default}}}){{/if~}} +{{~/if~}} + +{{~#if (eq type "object")}} + z.object({ + {{#each properties}} + {{#if description}} + /** + * {{{description}}} + */ + {{/if}} + {{@key}}: {{> zod_query_item requiredBool=(includes ../required @key)}}, + {{/each}} + }) +{{~/if~}} + +{{~#if (eq type "array")}} + z.preprocess( + (value: unknown) => (typeof value === "string") ? value === '' ? [] : value.split(",") : value, + z.array({{~> zod_schema_item items ~}}) + ) + {{~#if minItems}}.min({{minItems}}){{/if~}} + {{~#if maxItems}}.max({{maxItems}}){{/if~}} + {{~#if (eq requiredBool false)}}.optional(){{/if~}} + {{~#if (defined default)}}.default({{{toJSON default}}}){{/if~}} +{{~/if~}} + +{{~#if (eq type "boolean")}} + z.preprocess( + (value: unknown) => (typeof value === "boolean") ? String(value) : value, + z.enum(["true", "false"]) + {{~#if (defined default)}}.default("{{{toJSON default}}}"){{/if~}} + .transform((value) => value === "true") + ) +{{~/if~}} + +{{~#if (eq type "string")}} +{{> zod_schema_item}} +{{~/if~}} + +{{~#if (eq type "integer")}} +{{> zod_schema_item}} +{{~/if~}} + +{{~#if (eq type "number")}} +{{> zod_schema_item}} +{{~/if~}} diff --git a/x-pack/plugins/security_solution/scripts/openapi/template_service/templates/schema_item.handlebars b/packages/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars similarity index 79% rename from x-pack/plugins/security_solution/scripts/openapi/template_service/templates/schema_item.handlebars rename to packages/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars index 2d544a702ac00..dbf156b6a7b12 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/template_service/templates/schema_item.handlebars +++ b/packages/kbn-openapi-generator/src/template_service/templates/zod_schema_item.handlebars @@ -6,7 +6,7 @@ {{~/if~}} {{~#if $ref~}} - {{parseRef $ref}} + {{referenceName}} {{~#if nullable}}.nullable(){{/if~}} {{~#if (eq requiredBool false)}}.optional(){{/if~}} {{~#if (defined default)}}.default({{{toJSON default}}}){{/if~}} @@ -15,9 +15,9 @@ {{~#if allOf~}} {{~#each allOf~}} {{~#if @first~}} - {{> schema_item }} + {{> zod_schema_item }} {{~else~}} - .and({{> schema_item }}) + .and({{> zod_schema_item }}) {{~/if~}} {{~/each~}} {{~/if~}} @@ -25,7 +25,7 @@ {{~#if anyOf~}} z.union([ {{~#each anyOf~}} - {{~> schema_item ~}}, + {{~> zod_schema_item ~}}, {{~/each~}} ]) {{~/if~}} @@ -33,7 +33,7 @@ {{~#if oneOf~}} z.union([ {{~#each oneOf~}} - {{~> schema_item ~}}, + {{~> zod_schema_item ~}}, {{~/each~}} ]) {{~/if~}} @@ -43,11 +43,7 @@ z.unknown() {{/if}} {{~#*inline "type_array"~}} - {{~#if x-preprocess}} - z.preprocess({{x-preprocess}}, z.array({{~> schema_item items ~}})) - {{else}} - z.array({{~> schema_item items ~}}) - {{~/if~}} + z.array({{~> zod_schema_item items ~}}) {{~#if minItems}}.min({{minItems}}){{/if~}} {{~#if maxItems}}.max({{maxItems}}){{/if~}} {{~/inline~}} @@ -58,11 +54,13 @@ z.unknown() {{~/inline~}} {{~#*inline "type_integer"~}} - {{~#if x-coerce}} - z.coerce.number() - {{~else~}} + z.number().int() + {{~#if minimum includeZero=true}}.min({{minimum}}){{/if~}} + {{~#if maximum includeZero=true}}.max({{maximum}}){{/if~}} +{{~/inline~}} + +{{~#*inline "type_number"~}} z.number() - {{~/if~}} {{~#if minimum includeZero=true}}.min({{minimum}}){{/if~}} {{~#if maximum includeZero=true}}.max({{maximum}}){{/if~}} {{~/inline~}} @@ -75,7 +73,7 @@ z.unknown() * {{{description}}} */ {{/if}} - {{@key}}: {{> schema_item requiredBool=(includes ../required @key)}}, + {{@key}}: {{> zod_schema_item requiredBool=(includes ../required @key)}}, {{/each}} }) {{#if (eq additionalProperties false)}}.strict(){{/if}} diff --git a/packages/kbn-openapi-generator/tsconfig.json b/packages/kbn-openapi-generator/tsconfig.json new file mode 100644 index 0000000000000..465b739262cf8 --- /dev/null +++ b/packages/kbn-openapi-generator/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "outDir": "target/types", + "types": ["jest", "node"] + }, + "exclude": ["target/**/*"], + "extends": "../../tsconfig.base.json", + "include": ["**/*.ts"], + "kbn_references": [ + "@kbn/repo-info", + "@kbn/handlebars", + ] +} diff --git a/packages/kbn-search-api-panels/components/code_box.tsx b/packages/kbn-search-api-panels/components/code_box.tsx index ca3dd4d8b52c5..08fdd4cdf33ab 100644 --- a/packages/kbn-search-api-panels/components/code_box.tsx +++ b/packages/kbn-search-api-panels/components/code_box.tsx @@ -87,7 +87,7 @@ export const CodeBox: React.FC = ({ return ( - + = ({ {(copy) => ( - + {i18n.translate('searchApiPanels.welcomeBanner.codeBox.copyButtonLabel', { defaultMessage: 'Copy', })} @@ -127,6 +127,7 @@ export const CodeBox: React.FC = ({ transparentBackground fontSize="m" language={languageType || selectedLanguage.languageStyling || selectedLanguage.id} + overflowHeight={500} > {codeSnippet} diff --git a/packages/kbn-search-api-panels/components/github_link.tsx b/packages/kbn-search-api-panels/components/github_link.tsx index d0b41e21daeaf..9f5a2ee700c1b 100644 --- a/packages/kbn-search-api-panels/components/github_link.tsx +++ b/packages/kbn-search-api-panels/components/github_link.tsx @@ -18,7 +18,7 @@ export const GithubLink: React.FC<{ return ( - + diff --git a/packages/kbn-search-api-panels/components/ingest_data.tsx b/packages/kbn-search-api-panels/components/ingest_data.tsx index d25f7a74d05e3..0b0e11b13618d 100644 --- a/packages/kbn-search-api-panels/components/ingest_data.tsx +++ b/packages/kbn-search-api-panels/components/ingest_data.tsx @@ -93,6 +93,7 @@ export const IngestData: React.FC = ({ defaultMessage: 'Ingest data', })} > + = ({ /> - - - - {i18n.translate('searchApiPanels.welcomeBanner.apiCallout.content', { - defaultMessage: - 'Console enables you to call Elasticsearch and Kibana REST APIs directly, without needing to install a language client.', - })} - - ); return ( diff --git a/packages/kbn-search-api-panels/components/integrations_panel.tsx b/packages/kbn-search-api-panels/components/integrations_panel.tsx index 6f612be4dd101..dc4c472477578 100644 --- a/packages/kbn-search-api-panels/components/integrations_panel.tsx +++ b/packages/kbn-search-api-panels/components/integrations_panel.tsx @@ -35,20 +35,19 @@ export const IntegrationsPanel: React.FC = ({ return ( - + - +

    {i18n.translate('searchApiPanels.welcomeBanner.ingestData.logstashTitle', { defaultMessage: 'Logstash', })}

    - - +

    {i18n.translate('searchApiPanels.welcomeBanner.ingestData.logstashDescription', { @@ -57,16 +56,16 @@ export const IntegrationsPanel: React.FC = ({ })}

    - - - + + + {LEARN_MORE_LABEL} - + = ({ - + - +

    {i18n.translate('searchApiPanels.welcomeBanner.ingestData.beatsTitle', { defaultMessage: 'Beats', })}

    - + {i18n.translate('searchApiPanels.welcomeBanner.ingestData.beatsDescription', { defaultMessage: 'Lightweight, single-purpose data shippers for Elasticsearch. Use Beats to send operational data from your servers.', })} - - - + + + {LEARN_MORE_LABEL} - + @@ -119,36 +118,36 @@ export const IntegrationsPanel: React.FC = ({ - - + + - +

    {i18n.translate('searchApiPanels.welcomeBanner.ingestData.connectorsTitle', { defaultMessage: 'Connector Client', })}

    - + {i18n.translate('searchApiPanels.welcomeBanner.ingestData.connectorsDescription', { defaultMessage: 'Specialized integrations for syncing data from third-party sources to Elasticsearch. Use Elastic Connectors to sync content from a range of databases and object stores.', })} - - - + + + {LEARN_MORE_LABEL} - + = ({ return ( <> - + {leftPanelContent && {leftPanelContent}} - - + +

    {title}

    - + {description && {description}} {children} {links && links.length > 0 ? ( @@ -59,11 +59,14 @@ export const OverviewPanel: React.FC = ({
    {links.map(({ label, href }, index) => ( - - - {label} - - + + + + {label} + + + + ))} ) : null} diff --git a/packages/kbn-search-api-panels/components/try_in_console_button.tsx b/packages/kbn-search-api-panels/components/try_in_console_button.tsx index 35f6ef5d00184..93012c58a036d 100644 --- a/packages/kbn-search-api-panels/components/try_in_console_button.tsx +++ b/packages/kbn-search-api-panels/components/try_in_console_button.tsx @@ -40,7 +40,7 @@ export const TryInConsoleButton = ({ if (!consolePreviewLink) return null; return ( - + = ({ image, showDescription = true, }) => ( - - - {/* Reversing column direction here so screenreaders keep h1 as the first element */} - - - -

    - {i18n.translate('searchApiPanels.welcomeBanner.header.title', { - defaultMessage: 'Get started with Elasticsearch', - })} -

    -
    -
    - {Boolean(user) && ( + <> + + + + {/* Reversing column direction here so screenreaders keep h1 as the first element */} + - -

    - {user - ? i18n.translate('searchApiPanels.welcomeBanner.header.greeting.customTitle', { - defaultMessage: 'Hi {name}!', - values: { name: user.full_name || user.username }, - }) - : i18n.translate('searchApiPanels.welcomeBanner.header.greeting.defaultTitle', { - defaultMessage: 'Hi!', - })} -

    + +

    + {i18n.translate('searchApiPanels.welcomeBanner.header.title', { + defaultMessage: 'Get started with Elasticsearch', + })} +

    + {Boolean(user) && ( + + +

    + {user + ? i18n.translate('searchApiPanels.welcomeBanner.header.greeting.customTitle', { + defaultMessage: 'Hi {name}!', + values: { name: user.full_name || user.username }, + }) + : i18n.translate('searchApiPanels.welcomeBanner.header.greeting.defaultTitle', { + defaultMessage: 'Hi!', + })} +

    +
    +
    + )} +
    + + {showDescription && ( + + {i18n.translate('searchApiPanels.welcomeBanner.header.description', { + defaultMessage: + "Set up your programming language client, ingest some data, and you'll be ready to start searching within minutes.", + })} + )} -
    - - {showDescription && ( - - {i18n.translate('searchApiPanels.welcomeBanner.header.description', { - defaultMessage: - "Set up your programming language client, ingest some data, and you'll be ready to start searching within minutes.", - })} - - )} - -
    +
    - - - -
    + + + +
    + + ); diff --git a/packages/kbn-test/src/es/es_test_config.ts b/packages/kbn-test/src/es/es_test_config.ts index c31728b0fd7d8..26827558b7bd3 100644 --- a/packages/kbn-test/src/es/es_test_config.ts +++ b/packages/kbn-test/src/es/es_test_config.ts @@ -27,6 +27,10 @@ class EsTestConfig { return process.env.TEST_ES_FROM || 'snapshot'; } + getESServerlessImage() { + return process.env.TEST_ES_SERVERLESS_IMAGE; + } + getTransportPort() { return process.env.TEST_ES_TRANSPORT_PORT || '9300-9400'; } diff --git a/packages/kbn-test/src/es/test_es_cluster.ts b/packages/kbn-test/src/es/test_es_cluster.ts index 3cd90d21d1d91..3c63960bdc0e5 100644 --- a/packages/kbn-test/src/es/test_es_cluster.ts +++ b/packages/kbn-test/src/es/test_es_cluster.ts @@ -70,6 +70,10 @@ export interface CreateTestEsClusterOptions { */ esArgs?: string[]; esFrom?: string; + esServerlessOptions?: { + image?: string; + tag?: string; + }; esJavaOpts?: string; /** * License to run your cluster under. Keep in mind that a `trial` license @@ -164,6 +168,7 @@ export function createTestEsCluster< writeLogsToPath, basePath = Path.resolve(REPO_ROOT, '.es'), esFrom = esTestConfig.getBuildFrom(), + esServerlessOptions, dataArchive, nodes = [{ name: 'node-01' }], esArgs: customEsArgs = [], @@ -236,9 +241,11 @@ export function createTestEsCluster< } else if (esFrom === 'snapshot') { installPath = (await firstNode.installSnapshot(config)).installPath; } else if (esFrom === 'serverless') { - return await firstNode.runServerless({ + await firstNode.runServerless({ basePath, esArgs: customEsArgs, + image: esServerlessOptions?.image, + tag: esServerlessOptions?.tag, port, clean: true, background: true, @@ -247,6 +254,7 @@ export function createTestEsCluster< kill: true, // likely don't need this but avoids any issues where the ESS cluster wasn't cleaned up waitForReady: true, }); + return; } else if (Path.isAbsolute(esFrom)) { installPath = esFrom; } else { @@ -275,9 +283,9 @@ export function createTestEsCluster< }); } - nodeStartPromises.push(async () => { + nodeStartPromises.push(() => { log.info(`[es] starting node ${node.name} on port ${nodePort}`); - return await this.nodes[i].start(installPath, { + return this.nodes[i].start(installPath, { password: config.password, esArgs: assignArgs(esArgs, overriddenArgs), esJavaOpts, @@ -292,7 +300,7 @@ export function createTestEsCluster< }); } - await Promise.all(extractDirectoryPromises.map(async (extract) => await extract())); + await Promise.all(extractDirectoryPromises.map((extract) => extract())); for (const start of nodeStartPromises) { await start(); } 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 f9c83161b521b..d298a1c1abaa4 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts +++ b/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts @@ -12,11 +12,12 @@ import getPort from 'get-port'; import { REPO_ROOT } from '@kbn/repo-info'; import type { ArtifactLicense } from '@kbn/es'; import type { Config } from '../../functional_test_runner'; -import { createTestEsCluster } from '../../es'; +import { createTestEsCluster, esTestConfig } from '../../es'; interface RunElasticsearchOptions { log: ToolingLog; esFrom?: string; + esServerlessImage?: string; config: Config; onEarlyExit?: (msg: string) => void; logsDir?: string; @@ -32,6 +33,7 @@ type EsConfig = ReturnType; function getEsConfig({ config, esFrom = config.get('esTestCluster.from'), + esServerlessImage, }: RunElasticsearchOptions) { const ssl = !!config.get('esTestCluster.ssl'); const license: ArtifactLicense = config.get('esTestCluster.license'); @@ -50,6 +52,8 @@ function getEsConfig({ const serverless: boolean = config.get('serverless'); const files: string[] | undefined = config.get('esTestCluster.files'); + const esServerlessOptions = getESServerlessOptions(esServerlessImage, config); + return { ssl, license, @@ -57,6 +61,7 @@ function getEsConfig({ esJavaOpts, isSecurityEnabled, esFrom, + esServerlessOptions, port, password, dataArchive, @@ -129,6 +134,7 @@ async function startEsNode({ clusterName: `cluster-${name}`, esArgs: config.esArgs, esFrom: config.esFrom, + esServerlessOptions: config.esServerlessOptions, esJavaOpts: config.esJavaOpts, license: config.license, password: config.password, @@ -153,3 +159,23 @@ async function startEsNode({ return cluster; } + +function getESServerlessOptions(esServerlessImageFromArg: string | undefined, config: Config) { + const esServerlessImageUrlOrTag = + esServerlessImageFromArg || + esTestConfig.getESServerlessImage() || + (config.has('esTestCluster.esServerlessImage') && + config.get('esTestCluster.esServerlessImage')); + + if (esServerlessImageUrlOrTag) { + if (esServerlessImageUrlOrTag.includes(':')) { + return { + image: esServerlessImageUrlOrTag, + }; + } else { + return { + tag: esServerlessImageUrlOrTag, + }; + } + } +} diff --git a/packages/kbn-test/src/functional_tests/run_tests/cli.ts b/packages/kbn-test/src/functional_tests/run_tests/cli.ts index 19a003dd973cf..40a711ca9f6c2 100644 --- a/packages/kbn-test/src/functional_tests/run_tests/cli.ts +++ b/packages/kbn-test/src/functional_tests/run_tests/cli.ts @@ -26,6 +26,7 @@ export function runTestsCli() { { description: `Run Functional Tests`, usage: ` + Usage: node scripts/functional_tests --help node scripts/functional_tests [--config [--config ...]] node scripts/functional_tests [options] [-- --] diff --git a/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts b/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts index 0c9dae3a25794..77399605b29f4 100644 --- a/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts +++ b/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts @@ -42,6 +42,7 @@ describe('parse runTest flags', () => { ], "dryRun": false, "esFrom": undefined, + "esServerlessImage": undefined, "esVersion": , "grep": undefined, "installDir": undefined, diff --git a/packages/kbn-test/src/functional_tests/run_tests/flags.ts b/packages/kbn-test/src/functional_tests/run_tests/flags.ts index f4dd6beb26e80..3ba86999d3802 100644 --- a/packages/kbn-test/src/functional_tests/run_tests/flags.ts +++ b/packages/kbn-test/src/functional_tests/run_tests/flags.ts @@ -23,6 +23,7 @@ export const FLAG_OPTIONS: FlagOptions = { 'config', 'journey', 'esFrom', + 'esServerlessImage', 'kibana-install-dir', 'grep', 'include-tag', @@ -37,6 +38,7 @@ export const FLAG_OPTIONS: FlagOptions = { --config Define a FTR config that should be executed. Can be specified multiple times --journey Define a Journey that should be executed. Can be specified multiple times --esFrom Build Elasticsearch from source or run snapshot or serverless. Default: $TEST_ES_FROM or "snapshot" + --esServerlessImage When 'esFrom' is "serverless", this argument will be interpreted either as a tag within the ES Serverless repo, OR a full docker image path. --include-tag Tags that suites must include to be run, can be included multiple times --exclude-tag Tags that suites must NOT include to be run, can be included multiple times --include Files that must included to be run, can be included multiple times @@ -50,6 +52,13 @@ export const FLAG_OPTIONS: FlagOptions = { --updateSnapshots Replace inline and file snapshots with whatever is generated from the test --updateAll, -u Replace both baseline screenshots and snapshots `, + examples: ` +Run the latest verified, kibana-compatible ES Serverless image: + node scripts/functional_tests --config ./config.ts --esFrom serverless --esServerlessImage docker.elastic.co/kibana-ci/elasticsearch-serverless:latest-verified + +Run with a specific ES Serverless tag from the docker.elastic.co/elasticsearch-ci/elasticsearch-serverless repo: + node scripts/functional_tests --config ./config.ts --esFrom serverless --esServerlessImage git-fec36430fba2 + `, }; export function parseFlags(flags: FlagsReader) { @@ -75,6 +84,7 @@ export function parseFlags(flags: FlagsReader) { ? Path.resolve(REPO_ROOT, 'data/ftr_servers_logs', uuidV4()) : undefined, esFrom: flags.enum('esFrom', ['snapshot', 'source', 'serverless']), + esServerlessImage: flags.string('esServerlessImage'), installDir: flags.path('kibana-install-dir'), grep: flags.string('grep'), suiteTags: { diff --git a/packages/kbn-text-based-editor/src/helpers.test.ts b/packages/kbn-text-based-editor/src/helpers.test.ts index 5f1546ccc138e..f7b100419b2c7 100644 --- a/packages/kbn-text-based-editor/src/helpers.test.ts +++ b/packages/kbn-text-based-editor/src/helpers.test.ts @@ -5,8 +5,14 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - -import { parseErrors, parseWarning, getInlineEditorText, getWrappedInPipesCode } from './helpers'; +import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import { + parseErrors, + parseWarning, + getInlineEditorText, + getWrappedInPipesCode, + getIndicesForAutocomplete, +} from './helpers'; describe('helpers', function () { describe('parseErrors', function () { @@ -159,4 +165,25 @@ describe('helpers', function () { expect(code).toEqual('FROM index1 | keep field1, field2 | order field1'); }); }); + + describe('getIndicesForAutocomplete', function () { + it('should not return system indices', async function () { + const dataViewsMock = dataViewPluginMocks.createStartContract(); + const updatedDataViewsMock = { + ...dataViewsMock, + getIndices: jest.fn().mockResolvedValue([ + { + name: '.system1', + title: 'system1', + }, + { + name: 'logs', + title: 'logs', + }, + ]), + }; + const indices = await getIndicesForAutocomplete(updatedDataViewsMock); + expect(indices).toStrictEqual(['logs']); + }); + }); }); diff --git a/packages/kbn-text-based-editor/src/helpers.ts b/packages/kbn-text-based-editor/src/helpers.ts index 6b4e99f6e3093..8932276695117 100644 --- a/packages/kbn-text-based-editor/src/helpers.ts +++ b/packages/kbn-text-based-editor/src/helpers.ts @@ -10,6 +10,7 @@ import { useRef } from 'react'; import useDebounce from 'react-use/lib/useDebounce'; import { monaco } from '@kbn/monaco'; import { i18n } from '@kbn/i18n'; +import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; export interface MonacoError { message: string; @@ -172,3 +173,12 @@ export const getWrappedInPipesCode = (code: string, isWrapped: boolean): string }); return codeNoLines.join(isWrapped ? ' | ' : '\n| '); }; + +export const getIndicesForAutocomplete = async (dataViews: DataViewsPublicPluginStart) => { + const indices = await dataViews.getIndices({ + showAllIndices: false, + pattern: '*', + isRollupIndex: () => false, + }); + return indices.filter((index) => !index.name.startsWith('.')).map((i) => i.name); +}; diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx index 84abd18de3323..b1f1708262743 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.tsx @@ -56,6 +56,7 @@ import { getDocumentationSections, MonacoError, getWrappedInPipesCode, + getIndicesForAutocomplete, } from './helpers'; import { EditorFooter } from './editor_footer'; import { ResizableButton } from './resizable_button'; @@ -371,12 +372,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const getSourceIdentifiers: ESQLCustomAutocompleteCallbacks['getSourceIdentifiers'] = useCallback(async () => { - const indices = await dataViews.getIndices({ - showAllIndices: false, - pattern: '*', - isRollupIndex: () => false, - }); - return indices.map((i) => i.name); + return await getIndicesForAutocomplete(dataViews); }, [dataViews]); const getFieldsIdentifiers: ESQLCustomAutocompleteCallbacks['getFieldsIdentifiers'] = useCallback( @@ -453,7 +449,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ scrollBeyondLastLine: false, quickSuggestions: true, minimap: { enabled: false }, - wordWrap: isWordWrapped ? 'on' : 'off', + wordWrap: 'on', lineNumbers: showLineNumbers ? 'on' : 'off', theme: language === 'esql' ? ESQL_THEME_ID : isDark ? 'vs-dark' : 'vs', lineDecorationsWidth: 12, diff --git a/packages/kbn-ts-type-check-cli/run_type_check_cli.ts b/packages/kbn-ts-type-check-cli/run_type_check_cli.ts index 0295525578952..3f4385118c9c6 100644 --- a/packages/kbn-ts-type-check-cli/run_type_check_cli.ts +++ b/packages/kbn-ts-type-check-cli/run_type_check_cli.ts @@ -124,6 +124,9 @@ run( '--pretty', ...(flagsReader.boolean('verbose') ? ['--verbose'] : []), ], + env: { + NODE_OPTIONS: '--max-old-space-size=8192', + }, cwd: REPO_ROOT, wait: true, }); diff --git a/packages/shared-ux/button_toolbar/src/buttons/toolbar_button/toolbar_button.tsx b/packages/shared-ux/button_toolbar/src/buttons/toolbar_button/toolbar_button.tsx index 34bd7db5e9dec..76adb41e237bd 100644 --- a/packages/shared-ux/button_toolbar/src/buttons/toolbar_button/toolbar_button.tsx +++ b/packages/shared-ux/button_toolbar/src/buttons/toolbar_button/toolbar_button.tsx @@ -20,7 +20,7 @@ type ToolbarButtonTypes = 'primary' | 'empty'; export interface Props extends Pick< EuiButtonPropsForButton, - 'onClick' | 'iconType' | 'iconSide' | 'size' | 'data-test-subj' + 'onClick' | 'iconType' | 'iconSide' | 'size' | 'data-test-subj' | 'isDisabled' > { label: string; type?: ToolbarButtonTypes; @@ -31,16 +31,23 @@ export const ToolbarButton: React.FunctionComponent = ({ type = 'empty', iconSide = 'left', size = 'm', + isDisabled, ...rest }) => { const euiTheme = useEuiTheme(); - const toolbarButtonStyleProps: EuiButtonPropsForButton = - type === 'primary' + const toolbarButtonStyleProps: EuiButtonPropsForButton = !isDisabled + ? type === 'primary' ? { color: 'primary', fill: true } - : { color: 'text', css: ToolbarButtonStyles(euiTheme).emptyButton }; + : { color: 'text', css: ToolbarButtonStyles(euiTheme).emptyButton } + : {}; return ( - + {label} ); diff --git a/packages/shared-ux/button_toolbar/src/popover/popover.tsx b/packages/shared-ux/button_toolbar/src/popover/popover.tsx index 89654e37c850a..25dff5c52250f 100644 --- a/packages/shared-ux/button_toolbar/src/popover/popover.tsx +++ b/packages/shared-ux/button_toolbar/src/popover/popover.tsx @@ -35,6 +35,7 @@ export const ToolbarPopover = ({ iconType, size = 'm', children, + isDisabled, ...popover }: Props) => { const [isOpen, setIsOpen] = useState(false); @@ -46,6 +47,7 @@ export const ToolbarPopover = ({ ); diff --git a/packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template.test.tsx.snap b/packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template.test.tsx.snap index c57c90acbdcf7..09421e4cb5dd7 100644 --- a/packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template.test.tsx.snap +++ b/packages/shared-ux/page/kibana_template/impl/src/__snapshots__/page_template.test.tsx.snap @@ -3,7 +3,7 @@ exports[`KibanaPageTemplate render basic template 1`] = `
    <_EuiPageHeader diff --git a/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx b/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx index f9b9dcd247de6..5da29ba797041 100644 --- a/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx +++ b/packages/shared-ux/page/kibana_template/impl/src/page_template_inner.tsx @@ -68,7 +68,8 @@ export const KibanaPageTemplateInner: FC = ({ // the following props can be removed to allow the template to auto-handle // the fixed header and banner heights. offset={0} - minHeight={0} + minHeight={header ? 'calc(100vh - var(--euiFixedHeadersOffset, 0))' : 0} + grow={header ? false : undefined} {...rest} > {sideBar} diff --git a/scripts/generate_openapi.js b/scripts/generate_openapi.js new file mode 100644 index 0000000000000..2dfae34bf46dd --- /dev/null +++ b/scripts/generate_openapi.js @@ -0,0 +1,10 @@ +/* + * 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 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 or the Server + * Side Public License, v 1. + */ + +require('../src/setup_node_env'); +require('@kbn/openapi-generator').runCli(); diff --git a/src/core/server/integration_tests/saved_objects/migrations/elasticsearch_client_wrapper.ts b/src/core/server/integration_tests/saved_objects/migrations/elasticsearch_client_wrapper.ts new file mode 100644 index 0000000000000..66975bbba4409 --- /dev/null +++ b/src/core/server/integration_tests/saved_objects/migrations/elasticsearch_client_wrapper.ts @@ -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 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 or the Server + * Side Public License, v 1. + */ + +import type { Client } from '@elastic/elasticsearch'; + +export type ElasticsearchClientWrapperFactory = (client: Client) => Client; + +interface GetElasticsearchClientWrapperFactoryParams { + failOn: (methodName: string, methodArguments: any[]) => boolean; + errorDelaySeconds?: number; +} + +export const getElasticsearchClientWrapperFactory = ({ + failOn, + errorDelaySeconds, +}: GetElasticsearchClientWrapperFactoryParams): ElasticsearchClientWrapperFactory => { + const interceptClientMethod = (methodName: string, method: any): any => { + return new Proxy(method, { + apply: (applyTarget, thisArg, methodArguments) => { + if (failOn(methodName, methodArguments)) { + return new Promise((_, reject) => + setTimeout( + () => reject(`Error: esClient.${methodName}() failed unexpectedly`), + (errorDelaySeconds || 0) * 1000 + ) + ); + } + return Reflect.apply(applyTarget, thisArg, methodArguments); + }, + }); + }; + + const interceptClientApi = (apiName: string, api: any): any => + new Proxy(api, { + get(target, prop) { + return typeof target[prop] === 'function' + ? interceptClientMethod(`${apiName}.${prop.toString()}`, target[prop]) + : target[prop]; + }, + }); + + const wrapClient = (client: Client): any => + new Proxy(client, { + get(target, prop, receiver) { + switch (prop) { + // intercept top level esClient methods + case 'bulk': + case 'deleteByQuery': + case 'info': + case 'search': + case 'updateByQuery': + const clientMethod = Reflect.get(target, prop, receiver); + return interceptClientMethod(prop, clientMethod); + // intercept esClient APIs + case 'cluster': + case 'indices': + case 'tasks': + const clientApi = Reflect.get(target, prop, receiver); + return interceptClientApi(prop, clientApi); + // proxy child Clients too + case 'child': + return new Proxy(target[prop], { + apply(applyTarget, thisArg, argArray) { + const childClient = Reflect.apply(applyTarget, thisArg, argArray); + return wrapClient(childClient); + }, + }); + // do NOT intercept the rest of properties and symbols + default: + return Reflect.get(target, prop, receiver); + } + }, + }); + + return wrapClient; +}; diff --git a/src/core/server/integration_tests/saved_objects/migrations/group5/dot_kibana_split.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group5/dot_kibana_split.test.ts index 636e70cd9dd9e..25dc5a46a6793 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group5/dot_kibana_split.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group5/dot_kibana_split.test.ts @@ -29,6 +29,7 @@ import { } from '../kibana_migrator_test_kit'; import { delay, parseLogFile } from '../test_utils'; import '../jest_matchers'; +import { getElasticsearchClientWrapperFactory } from '../elasticsearch_client_wrapper'; // define a type => index distribution const RELOCATE_TYPES: Record = { @@ -58,6 +59,210 @@ describe('split .kibana index into multiple system indices', () => { await clearLog(logFilePathSecondRun); }); + describe('failure cases', () => { + const getFailingKibanaMigratorTestKit = async ({ + logFilePath, + failOn, + delaySeconds, + }: { + logFilePath: string; + failOn: (methodName: string, methodArgs: any[]) => boolean; + delaySeconds?: number; + }) => { + const clientWrapperFactory = getElasticsearchClientWrapperFactory({ + failOn, + errorDelaySeconds: delaySeconds, + }); + + return await getKibanaMigratorTestKit({ + types: typeRegistry.getAllTypes(), + kibanaIndex: MAIN_SAVED_OBJECT_INDEX, + defaultIndexTypesMap: DEFAULT_INDEX_TYPES_MAP, + logFilePath, + clientWrapperFactory, + }); + }; + + beforeEach(async () => { + esServer = await startElasticsearch({ + dataArchive: Path.join(__dirname, '..', 'archives', '7.7.2_xpack_100k_obj.zip'), + }); + }); + + describe('when the .kibana_task_manager migrator fails on the TRANSFORMED_DOCUMENTS_BULK_INDEX state, after the other ones have finished', () => { + it('is capable of completing the .kibana_task_manager migration in subsequent restart', async () => { + const { runMigrations: firstRun } = await getFailingKibanaMigratorTestKit({ + logFilePath: logFilePathFirstRun, + failOn: (methodName, methodArgs) => { + // fail on esClient.bulk({ index: '.kibana_task_manager_1' }) which supposedly causes + // the .kibana_task_manager migrator to fail on the TRANSFORMED_DOCUMENTS_BULK_INDEX state + return methodName === 'bulk' && methodArgs[0].index === '.kibana_task_manager_1'; + }, + delaySeconds: 90, // give the other migrators enough time to finish before failing + }); + + try { + await firstRun(); + throw new Error('First run should have thrown an error but it did not'); + } catch (error) { + expect(error.message).toEqual( + 'Unable to complete saved object migrations for the [.kibana_task_manager] index. Error: esClient.bulk() failed unexpectedly' + ); + } + }); + }); + + describe('when the .kibana migrator fails on the REINDEX_SOURCE_TO_TEMP_INDEX_BULK state', () => { + it('is capable of successfully performing the split migration in subsequent restart', async () => { + const { runMigrations: firstRun } = await getFailingKibanaMigratorTestKit({ + logFilePath: logFilePathFirstRun, + failOn: (methodName, methodArgs) => { + // fail on esClient.bulk({ index: '.kibana_8.11.0_reindex_temp_alias' }) which supposedly causes + // the .kibana migrator to fail on the REINDEX_SOURCE_TO_TEMP_INDEX_BULK + return ( + methodName === 'bulk' && + methodArgs[0].index === `.kibana_${currentVersion}_reindex_temp_alias` + ); + }, + delaySeconds: 10, // give the .kibana_task_manager migrator enough time to finish before failing + }); + + try { + await firstRun(); + throw new Error('First run should have thrown an error but it did not'); + } catch (error) { + expect(error.message).toEqual( + 'Unable to complete saved object migrations for the [.kibana] index. Error: esClient.bulk() failed unexpectedly' + ); + } + }); + }); + + describe('when the .kibana migrator fails on the CLONE_TEMP_TO_TARGET state', () => { + it('is capable of successfully performing the split migration in subsequent restart', async () => { + const { runMigrations: firstRun } = await getFailingKibanaMigratorTestKit({ + logFilePath: logFilePathFirstRun, + failOn: (methodName, methodArgs) => { + // fail on esClient.indices.clone({ index: '.kibana_8.11.0_reindex_temp', target: ... }) which supposedly causes + // the .kibana migrator to fail on the CLONE_TEMP_TO_TARGET + return ( + methodName === 'indices.clone' && + methodArgs[0].index === `.kibana_${currentVersion}_reindex_temp` && + methodArgs[0].target === `.kibana_${currentVersion}_001` + ); + }, + delaySeconds: 15, // give the other migrators enough time to finish before failing + }); + + try { + await firstRun(); + throw new Error('First run should have thrown an error but it did not'); + } catch (error) { + expect(error.message).toEqual( + 'Unable to complete saved object migrations for the [.kibana] index. Error: esClient.indices.clone() failed unexpectedly' + ); + } + }); + }); + + describe('when the .kibana migrator fails on the UPDATE_TARGET_MAPPINGS_PROPERTIES state', () => { + it('is capable of successfully performing the split migration in subsequent restart', async () => { + const { runMigrations: firstRun } = await getFailingKibanaMigratorTestKit({ + logFilePath: logFilePathFirstRun, + failOn: (methodName, methodArgs) => { + // fail on esClient.updateByQuery({ index: '.kibana_8.11.0_001' }) which supposedly causes + // the .kibana migrator to fail on the UPDATE_TARGET_MAPPINGS_PROPERTIES (pickup mappings' changes) + return ( + methodName === 'updateByQuery' && + methodArgs[0].index === `.kibana_${currentVersion}_001` + ); + }, + delaySeconds: 10, // give the other migrators enough time to finish before failing + }); + + try { + await firstRun(); + throw new Error('First run should have thrown an error but it did not'); + } catch (error) { + expect(error.message).toEqual( + 'Unable to complete saved object migrations for the [.kibana] index. Error: esClient.updateByQuery() failed unexpectedly' + ); + } + }); + }); + + describe('when the .kibana_analytics migrator fails on the CLONE_TEMP_TO_TARGET state', () => { + it('is capable of successfully performing the split migration in subsequent restart', async () => { + const { runMigrations: firstRun } = await getFailingKibanaMigratorTestKit({ + logFilePath: logFilePathFirstRun, + failOn: (methodName, methodArgs) => { + // fail on esClient.indices.clone({ index: '.kibana_8.11.0_reindex_temp', target: ... }) which supposedly causes + // the .kibana migrator to fail on the CLONE_TEMP_TO_TARGET + return ( + methodName === 'indices.clone' && + methodArgs[0].index === `.kibana_analytics_${currentVersion}_reindex_temp` && + methodArgs[0].target === `.kibana_analytics_${currentVersion}_001` + ); + }, + delaySeconds: 15, // give the other migrators enough time to finish before failing + }); + + try { + await firstRun(); + throw new Error('First run should have thrown an error but it did not'); + } catch (error) { + expect(error.message).toEqual( + 'Unable to complete saved object migrations for the [.kibana_analytics] index. Error: esClient.indices.clone() failed unexpectedly' + ); + } + }); + }); + + describe('when the .kibana_analytics migrator fails on the UPDATE_TARGET_MAPPINGS_PROPERTIES state', () => { + it('is capable of successfully performing the split migration in subsequent restart', async () => { + const { runMigrations: firstRun } = await getFailingKibanaMigratorTestKit({ + logFilePath: logFilePathFirstRun, + failOn: (methodName, methodArgs) => { + // fail on esClient.updateByQuery({ index: '.kibana_8.11.0_001' }) which supposedly causes + // the .kibana migrator to fail on the UPDATE_TARGET_MAPPINGS_PROPERTIES (pickup mappings' changes) + return ( + methodName === 'updateByQuery' && + methodArgs[0].index === `.kibana_analytics_${currentVersion}_001` + ); + }, + delaySeconds: 10, // give the other migrators enough time to finish before failing + }); + + try { + await firstRun(); + throw new Error('First run should have thrown an error but it did not'); + } catch (error) { + expect(error.message).toEqual( + 'Unable to complete saved object migrations for the [.kibana_analytics] index. Error: esClient.updateByQuery() failed unexpectedly' + ); + } + }); + }); + + afterEach(async () => { + const { runMigrations: secondRun } = await getKibanaMigratorTestKit({ + types: typeRegistry.getAllTypes(), + logFilePath: logFilePathSecondRun, + kibanaIndex: MAIN_SAVED_OBJECT_INDEX, + defaultIndexTypesMap: DEFAULT_INDEX_TYPES_MAP, + }); + const results = await secondRun(); + expect( + results + .flat() + .every((result) => result.status === 'migrated' || result.status === 'patched') + ).toEqual(true); + + await esServer?.stop(); + await delay(2); + }); + }); + describe('when migrating from a legacy version', () => { let migratorTestKitFactory: (logFilePath: string) => Promise; diff --git a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts index a911fcdbdead5..1f6e9a7a58c77 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/kibana_migrator_test_kit.ts @@ -50,6 +50,7 @@ import type { DocLinksServiceStart } from '@kbn/core-doc-links-server'; import type { NodeRoles } from '@kbn/core-node-server'; import { baselineDocuments, baselineTypes } from './kibana_migrator_test_kit.fixtures'; import { delay } from './test_utils'; +import type { ElasticsearchClientWrapperFactory } from './elasticsearch_client_wrapper'; export const defaultLogFilePath = Path.join(__dirname, 'kibana_migrator_test_kit.log'); @@ -76,6 +77,7 @@ export interface KibanaMigratorTestKitParams { types?: Array>; defaultIndexTypesMap?: IndexTypesMap; logFilePath?: string; + clientWrapperFactory?: ElasticsearchClientWrapperFactory; } export interface KibanaMigratorTestKit { @@ -134,6 +136,7 @@ export const getKibanaMigratorTestKit = async ({ types = [], logFilePath = defaultLogFilePath, nodeRoles = defaultNodeRoles, + clientWrapperFactory, }: KibanaMigratorTestKitParams = {}): Promise => { let hasRun = false; const loggingSystem = new LoggingSystem(); @@ -145,7 +148,8 @@ export const getKibanaMigratorTestKit = async ({ const loggingConf = await firstValueFrom(configService.atPath('logging')); loggingSystem.upgrade(loggingConf); - const client = await getElasticsearchClient(configService, loggerFactory, kibanaVersion); + const rawClient = await getElasticsearchClient(configService, loggerFactory, kibanaVersion); + const client = clientWrapperFactory ? clientWrapperFactory(rawClient) : rawClient; const typeRegistry = new SavedObjectTypeRegistry(); diff --git a/src/dev/build/tasks/fleet/download_elastic_gpg_key.ts b/src/dev/build/tasks/fleet/download_elastic_gpg_key.ts index 85e927001bd41..6cd0b351c4d31 100644 --- a/src/dev/build/tasks/fleet/download_elastic_gpg_key.ts +++ b/src/dev/build/tasks/fleet/download_elastic_gpg_key.ts @@ -13,7 +13,7 @@ import { ToolingLog } from '@kbn/tooling-log'; import { downloadToDisk } from '../../lib'; const ARTIFACTS_URL = 'https://artifacts.elastic.co/'; -const GPG_KEY_NAME = 'GPG-KEY-elasticsearch'; +const GPG_KEY_NAME = 'GPG-KEY-elasticsearch.sha1'; const GPG_KEY_SHA512 = '84ee193cc337344d9a7da9021daf3f5ede83f5f1ab049d169f3634921529dcd096abf7a91eec7f26f3a6913e5e38f88f69a5e2ce79ad155d46edc75705a648c6'; diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx index bcb193f9cc1e3..ba90513a44c1d 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/controls_toolbar_button/controls_toolbar_button.tsx @@ -17,7 +17,13 @@ import { AddDataControlButton } from './add_data_control_button'; import { AddTimeSliderControlButton } from './add_time_slider_control_button'; import { EditControlGroupButton } from './edit_control_group_button'; -export function ControlsToolbarButton({ controlGroup }: { controlGroup: ControlGroupContainer }) { +export function ControlsToolbarButton({ + controlGroup, + isDisabled, +}: { + controlGroup: ControlGroupContainer; + isDisabled?: boolean; +}) { const { euiTheme } = useEuiTheme(); return ( @@ -30,6 +36,7 @@ export function ControlsToolbarButton({ controlGroup }: { controlGroup: ControlG size="s" iconType="controlsHorizontal" data-test-subj="dashboard-controls-menu-button" + isDisabled={isDisabled} > {({ closePopover }: { closePopover: () => void }) => ( , + , dashboard.addFromLibrary()} size="s" data-test-subj="dashboardAddFromLibraryButton" + isDisabled={isDisabled} />, ]; if (dashboard.controlGroup) { - extraButtons.push(); + extraButtons.push( + + ); } return ( @@ -128,6 +135,7 @@ export function DashboardEditingToolbar() { primaryButton: ( state.componentState.fullScreenMode); const savedQueryId = dashboard.select((state) => state.componentState.savedQueryId); const lastSavedId = dashboard.select((state) => state.componentState.lastSavedId); + const focusedPanelId = dashboard.select((state) => state.componentState.focusedPanelId); const managed = dashboard.select((state) => state.componentState.managed); const viewMode = dashboard.select((state) => state.explicitInput.viewMode); @@ -323,7 +324,9 @@ export function DashboardTopNav({ embedSettings, redirectTo }: DashboardTopNavPr setIsLabsShown(false)} /> ) : null} - {viewMode === ViewMode.EDIT ? : null} + {viewMode === ViewMode.EDIT ? ( + + ) : null}
    ); diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx index 9512d837e61be..d2b6470650caa 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/editor_menu.tsx @@ -24,6 +24,7 @@ import { pluginServices } from '../../services/plugin_services'; import { DASHBOARD_APP_ID } from '../../dashboard_constants'; interface Props { + isDisabled?: boolean; /** Handler for creating new visualization of a specified type */ createNewVisType: (visType: BaseVisType | VisTypeAlias) => () => void; /** Handler for creating a new embeddable of a specified type */ @@ -43,7 +44,7 @@ interface UnwrappedEmbeddableFactory { isEditable: boolean; } -export const EditorMenu = ({ createNewVisType, createNewEmbeddable }: Props) => { +export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled }: Props) => { const { embeddable, visualizations: { @@ -273,6 +274,7 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable }: Props) => label={i18n.translate('dashboard.solutionToolbar.editorMenuButtonLabel', { defaultMessage: 'Add panel', })} + isDisabled={isDisabled} size="s" iconType="plusInCircle" panelPaddingSize="none" diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx index be21a9ba6645e..6c8a123d19588 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.test.tsx @@ -21,12 +21,19 @@ jest.mock('./dashboard_grid_item', () => { // eslint-disable-next-line @typescript-eslint/no-var-requires DashboardGridItem: require('react').forwardRef( (props: DashboardGridItemProps, ref: HTMLDivElement) => { - const className = + const className = `${ props.expandedPanelId === undefined ? 'regularPanel' : props.expandedPanelId === props.id ? 'expandedPanel' - : 'hiddenPanel'; + : 'hiddenPanel' + } ${ + props.focusedPanelId + ? props.focusedPanelId === props.id + ? 'focusedPanel' + : 'blurredPanel' + : '' + }`; return (
    mockDashboardGridItem @@ -101,3 +108,21 @@ test('DashboardGrid renders expanded panel', async () => { expect(component.find('#mockDashboardGridItem_1').hasClass('regularPanel')).toBe(true); expect(component.find('#mockDashboardGridItem_2').hasClass('regularPanel')).toBe(true); }); + +test('DashboardGrid renders focused panel', async () => { + const { dashboardContainer, component } = createAndMountDashboardGrid(); + dashboardContainer.setFocusedPanelId('2'); + component.update(); + // Both panels should still exist in the dom, so nothing needs to be re-fetched once minimized. + expect(component.find('GridItem').length).toBe(2); + + expect(component.find('#mockDashboardGridItem_1').hasClass('blurredPanel')).toBe(true); + expect(component.find('#mockDashboardGridItem_2').hasClass('focusedPanel')).toBe(true); + + dashboardContainer.setFocusedPanelId(undefined); + component.update(); + expect(component.find('GridItem').length).toBe(2); + + expect(component.find('#mockDashboardGridItem_1').hasClass('blurredPanel')).toBe(false); + expect(component.find('#mockDashboardGridItem_2').hasClass('focusedPanel')).toBe(false); +}); diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx index 12cd26df28f18..e496939e8ade0 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid.tsx @@ -30,6 +30,7 @@ export const DashboardGrid = ({ viewportWidth }: { viewportWidth: number }) => { const viewMode = dashboard.select((state) => state.explicitInput.viewMode); const useMargins = dashboard.select((state) => state.explicitInput.useMargins); const expandedPanelId = dashboard.select((state) => state.componentState.expandedPanelId); + const focusedPanelId = dashboard.select((state) => state.componentState.focusedPanelId); const animatePanelTransforms = dashboard.select( (state) => state.componentState.animatePanelTransforms ); @@ -78,11 +79,12 @@ export const DashboardGrid = ({ viewportWidth }: { viewportWidth: number }) => { index={index + 1} type={type} expandedPanelId={expandedPanelId} + focusedPanelId={focusedPanelId} onPanelStatusChange={onPanelStatusChange} /> ); }); - }, [expandedPanelId, onPanelStatusChange, panels, panelsInOrder]); + }, [expandedPanelId, onPanelStatusChange, panels, panelsInOrder, focusedPanelId]); const onLayoutChange = useCallback( (newLayout: Array) => { @@ -127,8 +129,8 @@ export const DashboardGrid = ({ viewportWidth }: { viewportWidth: number }) => { breakpoints={breakpoints} onDragStop={onLayoutChange} onResizeStop={onLayoutChange} - isResizable={!expandedPanelId} - isDraggable={!expandedPanelId} + isResizable={!expandedPanelId && !focusedPanelId} + isDraggable={!expandedPanelId && !focusedPanelId} rowHeight={DASHBOARD_GRID_HEIGHT} margin={useMargins ? [DASHBOARD_MARGIN_SIZE, DASHBOARD_MARGIN_SIZE] : [0, 0]} draggableHandle={'.embPanel--dragHandle'} diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.test.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.test.tsx new file mode 100644 index 0000000000000..fa26677ba1f17 --- /dev/null +++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.test.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 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 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; + +import { mountWithIntl } from '@kbn/test-jest-helpers'; +import { CONTACT_CARD_EMBEDDABLE } from '@kbn/embeddable-plugin/public/lib/test_samples/embeddables'; + +import { buildMockDashboard } from '../../../mocks'; +import { Item, Props as DashboardGridItemProps } from './dashboard_grid_item'; +import { DashboardContainerContext } from '../../embeddable/dashboard_container'; + +jest.mock('@kbn/embeddable-plugin/public', () => { + const original = jest.requireActual('@kbn/embeddable-plugin/public'); + + return { + ...original, + EmbeddablePanel: (props: DashboardGridItemProps) => { + return ( +
    + mockEmbeddablePanel +
    + ); + }, + }; +}); + +const createAndMountDashboardGridItem = (props: DashboardGridItemProps) => { + const panels = { + '1': { + gridData: { x: 0, y: 0, w: 6, h: 6, i: '1' }, + type: CONTACT_CARD_EMBEDDABLE, + explicitInput: { id: '1' }, + }, + '2': { + gridData: { x: 6, y: 6, w: 6, h: 6, i: '2' }, + type: CONTACT_CARD_EMBEDDABLE, + explicitInput: { id: '2' }, + }, + }; + const dashboardContainer = buildMockDashboard({ panels }); + + const component = mountWithIntl( + + + + ); + return { dashboardContainer, component }; +}; + +test('renders Item', async () => { + const { component } = createAndMountDashboardGridItem({ + id: '1', + key: '1', + type: CONTACT_CARD_EMBEDDABLE, + }); + const panelElements = component.find('.embedPanel'); + expect(panelElements.length).toBe(1); + + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--expanded')).toBe(false); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--hidden')).toBe(false); + + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--focused')).toBe(false); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--blurred')).toBe(false); +}); + +test('renders expanded panel', async () => { + const { component } = createAndMountDashboardGridItem({ + id: '1', + key: '1', + type: CONTACT_CARD_EMBEDDABLE, + expandedPanelId: '1', + }); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--expanded')).toBe(true); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--hidden')).toBe(false); +}); + +test('renders hidden panel', async () => { + const { component } = createAndMountDashboardGridItem({ + id: '1', + key: '1', + type: CONTACT_CARD_EMBEDDABLE, + expandedPanelId: '2', + }); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--expanded')).toBe(false); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--hidden')).toBe(true); +}); + +test('renders focused panel', async () => { + const { component } = createAndMountDashboardGridItem({ + id: '1', + key: '1', + type: CONTACT_CARD_EMBEDDABLE, + focusedPanelId: '1', + }); + + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--focused')).toBe(true); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--blurred')).toBe(false); +}); + +test('renders blurred panel', async () => { + const { component } = createAndMountDashboardGridItem({ + id: '1', + key: '1', + type: CONTACT_CARD_EMBEDDABLE, + focusedPanelId: '2', + }); + + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--focused')).toBe(false); + expect(component.find('#panel-1').hasClass('dshDashboardGrid__item--blurred')).toBe(true); +}); diff --git a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx index 9da737a5e7446..9eb12379741ab 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/grid/dashboard_grid_item.tsx @@ -12,6 +12,7 @@ import classNames from 'classnames'; import { EmbeddablePhaseEvent, EmbeddablePanel, ViewMode } from '@kbn/embeddable-plugin/public'; +import { css } from '@emotion/react'; import { DashboardPanelState } from '../../../../common'; import { pluginServices } from '../../../services/plugin_services'; import { useDashboardContainer } from '../../embeddable/dashboard_container'; @@ -22,14 +23,14 @@ export interface Props extends DivProps { id: DashboardPanelState['explicitInput']['id']; index?: number; type: DashboardPanelState['type']; - focusedPanelId?: string; expandedPanelId?: string; + focusedPanelId?: string; key: string; isRenderable?: boolean; onPanelStatusChange?: (info: EmbeddablePhaseEvent) => void; } -const Item = React.forwardRef( +export const Item = React.forwardRef( ( { expandedPanelId, @@ -43,7 +44,6 @@ const Item = React.forwardRef( // https://github.com/react-grid-layout/react-grid-layout/issues/1241#issuecomment-658306889 children, className, - style, ...rest }, ref @@ -54,9 +54,13 @@ const Item = React.forwardRef( const expandPanel = expandedPanelId !== undefined && expandedPanelId === id; const hidePanel = expandedPanelId !== undefined && expandedPanelId !== id; + const focusPanel = focusedPanelId !== undefined && focusedPanelId === id; + const blurPanel = focusedPanelId !== undefined && focusedPanelId !== id; const classes = classNames({ 'dshDashboardGrid__item--expanded': expandPanel, 'dshDashboardGrid__item--hidden': hidePanel, + 'dshDashboardGrid__item--focused': focusPanel, + 'dshDashboardGrid__item--blurred': blurPanel, // eslint-disable-next-line @typescript-eslint/naming-convention printViewport__vis: container.getInput().viewMode === ViewMode.PRINT, }); @@ -69,12 +73,29 @@ const Item = React.forwardRef( if (highlightPanelId === id) { container.highlightPanel(ref.current); } + + ref.current.querySelectorAll('*').forEach((e) => { + if (blurPanel) { + // remove blurred panels and nested elements from tab order + e.setAttribute('tabindex', '-1'); + } else { + // restore tab order + e.removeAttribute('tabindex'); + } + }); } - }, [id, container, scrollToPanelId, highlightPanelId, ref]); + }, [id, container, scrollToPanelId, highlightPanelId, ref, blurPanel]); + + const focusStyles = blurPanel + ? css` + pointer-events: none; + opacity: 0.25; + ` + : css``; return (
    ((props, const { settings: { isProjectEnabledInLabs }, } = pluginServices.getServices(); + const container = useDashboardContainer(); + const focusedPanelId = container.select((state) => state.componentState.focusedPanelId); const dashboard = useDashboardContainer(); const isPrintMode = dashboard.select((state) => state.explicitInput.viewMode) === ViewMode.PRINT; - const isEnabled = !isPrintMode && isProjectEnabledInLabs('labs:dashboard:deferBelowFold'); + const isEnabled = + !isPrintMode && + isProjectEnabledInLabs('labs:dashboard:deferBelowFold') && + (!focusedPanelId || focusedPanelId === props.id); return isEnabled ? : ; }); diff --git a/src/plugins/dashboard/public/dashboard_container/component/panel/_dashboard_panel.scss b/src/plugins/dashboard/public/dashboard_container/component/panel/_dashboard_panel.scss index 33aab22fb8b8b..eb448412d1ae4 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/panel/_dashboard_panel.scss +++ b/src/plugins/dashboard/public/dashboard_container/component/panel/_dashboard_panel.scss @@ -23,7 +23,9 @@ // Remove border color unless in editing mode .dshLayout-withoutMargins:not(.dshLayout--editing), -.dshDashboardGrid__item--expanded { +.dshDashboardGrid__item--expanded, +.dshDashboardGrid__item--blurred, +.dshDashboardGrid__item--focused { .embPanel { border-color: transparent; } diff --git a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx index 15219455b17b2..d1931d7ed3e61 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/viewport/dashboard_viewport.tsx @@ -20,13 +20,13 @@ import { pluginServices } from '../../../services/plugin_services'; import { useDashboardContainer } from '../../embeddable/dashboard_container'; import { DashboardEmptyScreen } from '../empty_screen/dashboard_empty_screen'; -export const useDebouncedWidthObserver = (wait = 250) => { +export const useDebouncedWidthObserver = (skipDebounce = false, wait = 100) => { const [width, setWidth] = useState(0); const onWidthChange = useMemo(() => debounce(setWidth, wait), [wait]); const { ref } = useResizeObserver({ onResize: (dimensions) => { if (dimensions.width) { - if (width === 0) setWidth(dimensions.width); + if (width === 0 || skipDebounce) setWidth(dimensions.width); if (dimensions.width !== width) onWidthChange(dimensions.width); } }, @@ -58,10 +58,11 @@ export const DashboardViewportComponent = () => { const viewMode = dashboard.select((state) => state.explicitInput.viewMode); const dashboardTitle = dashboard.select((state) => state.explicitInput.title); const description = dashboard.select((state) => state.explicitInput.description); + const focusedPanelId = dashboard.select((state) => state.componentState.focusedPanelId); const expandedPanelId = dashboard.select((state) => state.componentState.expandedPanelId); const controlsEnabled = isProjectEnabledInLabs('labs:dashboard:dashboardControls'); - const { ref: resizeRef, width: viewportWidth } = useDebouncedWidthObserver(); + const { ref: resizeRef, width: viewportWidth } = useDebouncedWidthObserver(!!focusedPanelId); const classes = classNames({ dshDashboardViewport: true, diff --git a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx index ef09d9fd9504d..2a618ad6a04d4 100644 --- a/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx +++ b/src/plugins/dashboard/public/dashboard_container/embeddable/dashboard_container.tsx @@ -434,14 +434,18 @@ export class DashboardContainer extends Container { + public openOverlay = (ref: OverlayRef, options?: { focusedPanelId?: string }) => { this.clearOverlays(); this.dispatch.setHasOverlays(true); this.overlayRef = ref; + if (options?.focusedPanelId) { + this.setFocusedPanelId(options?.focusedPanelId); + } }; public clearOverlays = () => { this.dispatch.setHasOverlays(false); + this.dispatch.setFocusedPanelId(undefined); this.controlGroup?.closeAllFlyouts(); this.overlayRef?.close(); }; @@ -500,4 +504,8 @@ export class DashboardContainer extends Container { + this.dispatch.setFocusedPanelId(id); + }; } diff --git a/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts b/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts index 65660e1065f28..b0299ecfd47f1 100644 --- a/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts +++ b/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts @@ -239,6 +239,9 @@ export const dashboardContainerReducers = { setHighlightPanelId: (state: DashboardReduxState, action: PayloadAction) => { state.componentState.highlightPanelId = action.payload; }, + setFocusedPanelId: (state: DashboardReduxState, action: PayloadAction) => { + state.componentState.focusedPanelId = action.payload; + }, setAnimatePanelTransforms: ( state: DashboardReduxState, diff --git a/src/plugins/dashboard/public/dashboard_container/types.ts b/src/plugins/dashboard/public/dashboard_container/types.ts index dd01f643b99fc..b71876b1ea724 100644 --- a/src/plugins/dashboard/public/dashboard_container/types.ts +++ b/src/plugins/dashboard/public/dashboard_container/types.ts @@ -43,6 +43,7 @@ export interface DashboardPublicState { managed?: boolean; scrollToPanelId?: string; highlightPanelId?: string; + focusedPanelId?: string; } export interface DashboardRenderPerformanceStats { diff --git a/src/plugins/embeddable/public/embeddable_panel/panel_actions/track_overlays.ts b/src/plugins/embeddable/public/embeddable_panel/panel_actions/track_overlays.ts index 28022e6ed1937..10633e557b52b 100644 --- a/src/plugins/embeddable/public/embeddable_panel/panel_actions/track_overlays.ts +++ b/src/plugins/embeddable/public/embeddable_panel/panel_actions/track_overlays.ts @@ -8,8 +8,12 @@ import { OverlayRef } from '@kbn/core-mount-utils-browser'; +interface TracksOverlaysOptions { + focusedPanelId?: string; +} + interface TracksOverlays { - openOverlay: (ref: OverlayRef) => void; + openOverlay: (ref: OverlayRef, options?: TracksOverlaysOptions) => void; clearOverlays: () => void; } diff --git a/src/plugins/embeddable/public/embeddable_panel/panel_header/embeddable_panel_context_menu.tsx b/src/plugins/embeddable/public/embeddable_panel/panel_header/embeddable_panel_context_menu.tsx index 5fe6461083cc5..e3f4b1e7af580 100644 --- a/src/plugins/embeddable/public/embeddable_panel/panel_header/embeddable_panel_context_menu.tsx +++ b/src/plugins/embeddable/public/embeddable_panel/panel_header/embeddable_panel_context_menu.tsx @@ -25,7 +25,7 @@ import { uiActions } from '../../kibana_services'; import { EmbeddablePanelProps, PanelUniversalActions } from '../types'; import { getContextMenuAriaLabel } from '../embeddable_panel_strings'; import { useSelectFromEmbeddableInput } from '../use_select_from_embeddable'; -import { IEmbeddable, contextMenuTrigger, CONTEXT_MENU_TRIGGER, ViewMode } from '../..'; +import { IEmbeddable, contextMenuTrigger, CONTEXT_MENU_TRIGGER } from '../..'; const sortByOrderField = ( { order: orderA }: { order?: number }, @@ -56,7 +56,6 @@ export const EmbeddablePanelContextMenu = ({ const [contextMenuPanels, setContextMenuPanels] = useState([]); const title = useSelectFromEmbeddableInput('title', embeddable); - const viewMode = useSelectFromEmbeddableInput('viewMode', embeddable); useEffect(() => { /** @@ -135,7 +134,7 @@ export const EmbeddablePanelContextMenu = ({ data-test-subj="embeddablePanelToggleMenuIcon" aria-label={getContextMenuAriaLabel(title, index)} onClick={() => setIsContextMenuOpen((isOpen) => !isOpen)} - iconType={viewMode === ViewMode.VIEW ? 'boxesHorizontal' : 'gear'} + iconType={'boxesHorizontal'} /> ); diff --git a/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap b/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap index bd4e658b04a99..2cd4388680751 100644 --- a/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap +++ b/src/plugins/home/public/application/components/tutorial/__snapshots__/tutorial.test.js.snap @@ -1,160 +1,166 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`isCloudEnabled is false should not render instruction toggle when ON_PREM_ELASTIC_CLOUD instructions are not provided 1`] = ` - -
    - - - +
    + -
    - + "prepend": [Function], + } + } + description="tutorial used to drive jest tests" + notices={null} + title="jest test tutorial" + /> + + +
    + + `; exports[`isCloudEnabled is false should render ON_PREM instructions with instruction toggle 1`] = ` - -
    - +
    + - - - + + + + + + - - - -
    - +
    + + `; exports[`should render ELASTIC_CLOUD instructions when isCloudEnabled is true 1`] = ` - -
    - - - +
    + -
    - + "prepend": [Function], + } + } + description="tutorial used to drive jest tests" + iconType="logoApache" + notices={null} + title="jest test tutorial" + /> + + +
    + + `; diff --git a/src/plugins/home/public/application/components/tutorial/tutorial.js b/src/plugins/home/public/application/components/tutorial/tutorial.js index de222dbe6155d..620da42169c35 100644 --- a/src/plugins/home/public/application/components/tutorial/tutorial.js +++ b/src/plugins/home/public/application/components/tutorial/tutorial.js @@ -18,7 +18,7 @@ import * as StatusCheckStates from './status_check_states'; import { injectI18n, FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { getServices } from '../../kibana_services'; -import { KibanaPageTemplate } from '@kbn/kibana-react-plugin/public'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; const INSTRUCTIONS_TYPE = { ELASTIC_CLOUD: 'elasticCloud', @@ -360,7 +360,7 @@ class TutorialUi extends React.Component { render() { let content; if (this.state.notFound) { - content = ( + return ( {content}; + return ( + + {content} + + ); } } diff --git a/src/plugins/home/public/application/components/tutorial_directory.js b/src/plugins/home/public/application/components/tutorial_directory.js index cde8b86f5df22..c5a4c1b27fbab 100644 --- a/src/plugins/home/public/application/components/tutorial_directory.js +++ b/src/plugins/home/public/application/components/tutorial_directory.js @@ -16,7 +16,7 @@ import { SampleDataTab } from '@kbn/home-sample-data-tab'; import { i18n } from '@kbn/i18n'; import { Synopsis } from './synopsis'; import { getServices } from '../kibana_services'; -import { KibanaPageTemplate } from '@kbn/kibana-react-plugin/public'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { getTutorials } from '../load_tutorials'; const SAMPLE_DATA_TAB_ID = 'sampleData'; @@ -257,7 +257,7 @@ class TutorialDirectoryUi extends React.Component { rightSideItems: headerLinks ? [headerLinks] : [], }} > - {this.renderTabContent()} + {this.renderTabContent()}
    ); } diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index f92739d045439..7954559206bb7 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -54,17 +54,13 @@ export { POSITIONS, WEIGHTS, TOOLBAR_BUTTON_SIZES, ToolbarButton } from './toolb export { reactRouterNavigate, reactRouterOnClickHandler } from './react_router_navigate'; export type { - KibanaPageTemplateProps, NoDataPageActions, NoDataPageActionsProps, NoDataPageProps, ElasticAgentCardProps, } from './page_template'; export { - KibanaPageTemplate, KibanaPageTemplateSolutionNavAvatar, - NO_DATA_PAGE_MAX_WIDTH, - NO_DATA_PAGE_TEMPLATE_PROPS, NO_DATA_RECOMMENDED, NoDataPage, ElasticAgentCard, diff --git a/src/plugins/kibana_react/public/page_template/__snapshots__/page_template.test.tsx.snap b/src/plugins/kibana_react/public/page_template/__snapshots__/page_template.test.tsx.snap deleted file mode 100644 index 4dea9549670f3..0000000000000 --- a/src/plugins/kibana_react/public/page_template/__snapshots__/page_template.test.tsx.snap +++ /dev/null @@ -1,440 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`KibanaPageTemplate render basic template 1`] = ` -
    -
    -
    -
    -
    -
    -
    -

    - test -

    -
    -
    -
    -
    -
    - test -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -`; - -exports[`KibanaPageTemplate render custom empty prompt only 1`] = ` - - - custom test - - } - /> - -`; - -exports[`KibanaPageTemplate render custom empty prompt with page header 1`] = ` - - - custom test - - } - /> - -`; - -exports[`KibanaPageTemplate render default empty prompt 1`] = ` - -`; - -exports[`KibanaPageTemplate render noDataContent 1`] = ` - -`; - -exports[`KibanaPageTemplate render solutionNav 1`] = ` -
    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -

    - test -

    -
    -
    -
    -
    -
    - test -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -`; diff --git a/src/plugins/kibana_react/public/page_template/index.ts b/src/plugins/kibana_react/public/page_template/index.ts index fda644a284797..65a5db433593a 100644 --- a/src/plugins/kibana_react/public/page_template/index.ts +++ b/src/plugins/kibana_react/public/page_template/index.ts @@ -6,9 +6,5 @@ * Side Public License, v 1. */ -export type { KibanaPageTemplateProps } from './page_template'; -export { KibanaPageTemplate } from './page_template'; export { KibanaPageTemplateSolutionNavAvatar, KibanaPageTemplateSolutionNav } from './solution_nav'; export * from './no_data_page'; -export { withSolutionNav } from './with_solution_nav'; -export { NO_DATA_PAGE_MAX_WIDTH, NO_DATA_PAGE_TEMPLATE_PROPS } from './util'; diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/index.ts b/src/plugins/kibana_react/public/page_template/no_data_page/index.ts index b5a11722dd397..55661ad6f14f7 100644 --- a/src/plugins/kibana_react/public/page_template/no_data_page/index.ts +++ b/src/plugins/kibana_react/public/page_template/no_data_page/index.ts @@ -8,4 +8,3 @@ export * from './no_data_page'; export * from './no_data_card'; -export * from './no_data_config_page'; diff --git a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx b/src/plugins/kibana_react/public/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx deleted file mode 100644 index cae591f571c79..0000000000000 --- a/src/plugins/kibana_react/public/page_template/no_data_page/no_data_config_page/no_data_config_page.tsx +++ /dev/null @@ -1,38 +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 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 or the Server - * Side Public License, v 1. - */ -import { EuiPageTemplate_Deprecated as EuiPageTemplate } from '@elastic/eui'; -import React from 'react'; -import { NoDataPage } from '../no_data_page'; -import { withSolutionNav } from '../../with_solution_nav'; -import { KibanaPageTemplateProps } from '../../page_template'; -import { getClasses, NO_DATA_PAGE_TEMPLATE_PROPS } from '../../util'; - -export const NoDataConfigPage = (props: KibanaPageTemplateProps) => { - const { className, noDataConfig, ...rest } = props; - - if (!noDataConfig) { - return null; - } - - const template = NO_DATA_PAGE_TEMPLATE_PROPS.template; - const classes = getClasses(template, className); - - return ( - - - - ); -}; - -export const NoDataConfigPageWithSolutionNavBar = withSolutionNav(NoDataConfigPage); diff --git a/src/plugins/kibana_react/public/page_template/page_template.scss b/src/plugins/kibana_react/public/page_template/page_template.scss deleted file mode 100644 index d94daec56235f..0000000000000 --- a/src/plugins/kibana_react/public/page_template/page_template.scss +++ /dev/null @@ -1,22 +0,0 @@ -.kbnPageTemplate__pageSideBar { - overflow: hidden; - // Temporary hack till the sizing is changed directly in EUI - min-width: 248px; - - @include euiCanAnimate { - transition: min-width $euiAnimSpeedFast $euiAnimSlightResistance; - } - - &.kbnPageTemplate__pageSideBar--shrink { - min-width: $euiSizeXXL; - } - - .kbnPageTemplate--centeredBody & { - border-bottom: $euiBorderThin; - - @include euiBreakpoint('m', 'l', 'xl') { - border-bottom: none; - border-right: $euiBorderThin; - } - } -} diff --git a/src/plugins/kibana_react/public/page_template/page_template.test.tsx b/src/plugins/kibana_react/public/page_template/page_template.test.tsx deleted file mode 100644 index aff6082902a34..0000000000000 --- a/src/plugins/kibana_react/public/page_template/page_template.test.tsx +++ /dev/null @@ -1,173 +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 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 or the Server - * Side Public License, v 1. - */ - -import React from 'react'; -import { shallow, render } from 'enzyme'; -import { KibanaPageTemplate, KibanaPageTemplateProps } from './page_template'; -import { EuiEmptyPrompt } from '@elastic/eui'; -import { KibanaPageTemplateSolutionNavProps } from './solution_nav'; - -const navItems: KibanaPageTemplateSolutionNavProps['items'] = [ - { - name: 'Ingest', - id: '1', - items: [ - { - name: 'Ingest Node Pipelines', - id: '1.1', - }, - { - name: 'Logstash Pipelines', - id: '1.2', - }, - { - name: 'Beats Central Management', - id: '1.3', - }, - ], - }, - { - name: 'Data', - id: '2', - items: [ - { - name: 'Index Management', - id: '2.1', - }, - { - name: 'Index Lifecycle Policies', - id: '2.2', - }, - { - name: 'Snapshot and Restore', - id: '2.3', - }, - ], - }, -]; - -const noDataConfig: KibanaPageTemplateProps['noDataConfig'] = { - solution: 'Elastic', - actions: { - elasticAgent: {}, - beats: {}, - custom: {}, - }, - docsLink: 'test', -}; - -describe('KibanaPageTemplate', () => { - test('render default empty prompt', () => { - const component = shallow( - - ); - expect(component).toMatchSnapshot(); - }); - - test('render custom empty prompt only', () => { - const component = shallow( - - custom test} /> - - ); - expect(component).toMatchSnapshot(); - }); - - test('render custom empty prompt with page header', () => { - const component = shallow( - - custom test} /> - - ); - expect(component).toMatchSnapshot(); - }); - - test('render basic template', () => { - const component = render( - - ); - expect(component).toMatchSnapshot(); - }); - - test('render solutionNav', () => { - const component = render( - - ); - expect(component).toMatchSnapshot(); - expect(component.find('div.kbnPageTemplate__pageSideBar').length).toBe(1); - }); - - test('render noDataContent', () => { - const component = shallow( - - ); - expect(component).toMatchSnapshot(); - }); - - test('render sidebar classes', () => { - const component = shallow( - - ); - expect(component.html().includes('kbnPageTemplate__pageSideBar customClass')).toBe(true); - }); -}); diff --git a/src/plugins/kibana_react/public/page_template/page_template.tsx b/src/plugins/kibana_react/public/page_template/page_template.tsx deleted file mode 100644 index 42ba9d1873587..0000000000000 --- a/src/plugins/kibana_react/public/page_template/page_template.tsx +++ /dev/null @@ -1,98 +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 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 or the Server - * Side Public License, v 1. - */ - -import './page_template.scss'; - -import React, { FunctionComponent } from 'react'; -import { EuiPageTemplateProps_Deprecated } from '@elastic/eui'; -import { KibanaPageTemplateSolutionNavProps } from './solution_nav'; - -import { - NoDataPageProps, - NoDataConfigPage, - NoDataConfigPageWithSolutionNavBar, -} from './no_data_page'; -import { KibanaPageTemplateInner, KibanaPageTemplateWithSolutionNav } from './page_template_inner'; - -/** - * A thin wrapper around EuiPageTemplate with a few Kibana specific additions - * @deprecated Use `KibanaPageTemplateProps` from `@kbn/shared-ux-page-kibana-template-types`. - */ -export type KibanaPageTemplateProps = EuiPageTemplateProps_Deprecated & { - /** - * Changes the template type depending on other props provided. - * With `pageHeader` only: Uses `centeredBody` and fills an EuiEmptyPrompt with `pageHeader` info. - * With `children` only: Uses `centeredBody` - * With `pageHeader` and `children`: Uses `centeredContent` - */ - isEmptyState?: boolean; - /** - * Quick creation of EuiSideNav. Hooks up mobile instance too - */ - solutionNav?: KibanaPageTemplateSolutionNavProps; - /** - * Accepts a configuration object, that when provided, ignores pageHeader and children and instead - * displays Agent, Beats, and custom cards to direct users to the right ingest location - */ - noDataConfig?: NoDataPageProps; -}; - -/** @deprecated Use `KibanaPageTemplate` from `@kbn/shared-ux-page-kibana-template`. */ -export const KibanaPageTemplate: FunctionComponent = ({ - template, - className, - children, - solutionNav, - noDataConfig, - ...rest -}) => { - /** - * If passing the custom template of `noDataConfig` - */ - if (noDataConfig && solutionNav) { - return ( - - ); - } - - if (noDataConfig) { - return ( - - ); - } - - if (solutionNav) { - return ( - - ); - } - - return ( - - ); -}; diff --git a/src/plugins/kibana_react/public/page_template/page_template_inner.tsx b/src/plugins/kibana_react/public/page_template/page_template_inner.tsx deleted file mode 100644 index 001cea5c26a23..0000000000000 --- a/src/plugins/kibana_react/public/page_template/page_template_inner.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 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 or the Server - * Side Public License, v 1. - */ - -import React, { FunctionComponent } from 'react'; - -import { EuiEmptyPrompt, EuiPageTemplate_Deprecated as EuiPageTemplate } from '@elastic/eui'; -import { withSolutionNav } from './with_solution_nav'; -import { KibanaPageTemplateProps } from './page_template'; -import { getClasses } from './util'; - -type Props = KibanaPageTemplateProps; - -/** - * A thin wrapper around EuiPageTemplate with a few Kibana specific additions - */ -export const KibanaPageTemplateInner: FunctionComponent = ({ - template, - className, - pageHeader, - children, - isEmptyState, - ...rest -}) => { - /** - * An easy way to create the right content for empty pages - */ - const emptyStateDefaultTemplate = 'centeredBody'; - if (isEmptyState && pageHeader && !children) { - template = template ?? emptyStateDefaultTemplate; - const { iconType, pageTitle, description, rightSideItems } = pageHeader; - pageHeader = undefined; - children = ( - {pageTitle} : undefined} - body={description ?

    {description}

    : undefined} - actions={rightSideItems} - /> - ); - } else if (isEmptyState && pageHeader && children) { - template = template ?? 'centeredContent'; - } else if (isEmptyState && !pageHeader) { - template = template ?? emptyStateDefaultTemplate; - } - - const classes = getClasses(template, className); - - return ( - - {children} - - ); -}; - -export const KibanaPageTemplateWithSolutionNav = withSolutionNav(KibanaPageTemplateInner); diff --git a/src/plugins/kibana_react/public/page_template/util/index.ts b/src/plugins/kibana_react/public/page_template/util/index.ts index adfefdf834566..06edc43d70d57 100644 --- a/src/plugins/kibana_react/public/page_template/util/index.ts +++ b/src/plugins/kibana_react/public/page_template/util/index.ts @@ -7,4 +7,3 @@ */ export { getClasses } from './presentation'; -export * from './constants'; diff --git a/src/plugins/kibana_react/public/page_template/with_solution_nav.tsx b/src/plugins/kibana_react/public/page_template/with_solution_nav.tsx deleted file mode 100644 index 842573b9d8de4..0000000000000 --- a/src/plugins/kibana_react/public/page_template/with_solution_nav.tsx +++ /dev/null @@ -1,77 +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 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 or the Server - * Side Public License, v 1. - */ - -import React, { ComponentType, useState } from 'react'; -import classNames from 'classnames'; -import { useIsWithinBreakpoints } from '@elastic/eui'; -import { EuiPageSideBarProps_Deprecated as EuiPageSideBarProps } from '@elastic/eui/src/components/page/page_side_bar'; -import { KibanaPageTemplateSolutionNav, KibanaPageTemplateSolutionNavProps } from './solution_nav'; -import { KibanaPageTemplateProps } from '.'; - -// https://reactjs.org/docs/higher-order-components.html#convention-wrap-the-display-name-for-easy-debugging -function getDisplayName(Component: ComponentType) { - return Component.displayName || Component.name || 'UnnamedComponent'; -} - -type SolutionNavProps = KibanaPageTemplateProps & { - solutionNav: KibanaPageTemplateSolutionNavProps; -}; - -const SOLUTION_NAV_COLLAPSED_KEY = 'solutionNavIsCollapsed'; - -export const withSolutionNav = (WrappedComponent: ComponentType) => { - const WithSolutionNav = (props: SolutionNavProps) => { - const isMediumBreakpoint = useIsWithinBreakpoints(['m']); - const isLargerBreakpoint = useIsWithinBreakpoints(['l', 'xl']); - const [isSideNavOpenOnDesktop, setisSideNavOpenOnDesktop] = useState( - !JSON.parse(String(localStorage.getItem(SOLUTION_NAV_COLLAPSED_KEY))) - ); - const { solutionNav, ...propagatedProps } = props; - const { children, isEmptyState, template } = propagatedProps; - const toggleOpenOnDesktop = () => { - setisSideNavOpenOnDesktop(!isSideNavOpenOnDesktop); - // Have to store it as the opposite of the default we want - localStorage.setItem(SOLUTION_NAV_COLLAPSED_KEY, JSON.stringify(isSideNavOpenOnDesktop)); - }; - const sideBarClasses = classNames( - 'kbnPageTemplate__pageSideBar', - { - 'kbnPageTemplate__pageSideBar--shrink': - isMediumBreakpoint || (isLargerBreakpoint && !isSideNavOpenOnDesktop), - }, - props.pageSideBarProps?.className - ); - - const templateToUse = isEmptyState && !template ? 'centeredContent' : template; - - const pageSideBar = ( - - ); - const pageSideBarProps = { - paddingSize: 'none', - ...props.pageSideBarProps, - className: sideBarClasses, - } as EuiPageSideBarProps; // needed because for some reason 'none' is not recognized as a valid value for paddingSize - return ( - - {children} - - ); - }; - WithSolutionNav.displayName = `WithSolutionNavBar(${getDisplayName(WrappedComponent)})`; - return WithSolutionNav; -}; diff --git a/test/functional/services/dashboard/add_panel.ts b/test/functional/services/dashboard/add_panel.ts index 926e19cd43474..00a91dff87b85 100644 --- a/test/functional/services/dashboard/add_panel.ts +++ b/test/functional/services/dashboard/add_panel.ts @@ -236,6 +236,9 @@ export class DashboardAddPanelService extends FtrService { await this.testSubjects.click(`savedObjectTitle${embeddableName.split(' ').join('-')}`); await this.testSubjects.exists('addObjectToDashboardSuccess'); await this.closeAddPanel(); + + // close "Added successfully" toast + await this.common.clearAllToasts(); return embeddableName; } diff --git a/test/functional/services/dashboard/panel_settings.ts b/test/functional/services/dashboard/panel_settings.ts index a90a51fdc2feb..de75a9c4a7a19 100644 --- a/test/functional/services/dashboard/panel_settings.ts +++ b/test/functional/services/dashboard/panel_settings.ts @@ -8,8 +8,9 @@ import { FtrProviderContext } from '../../ftr_provider_context'; import { CommonlyUsed } from '../../page_objects/time_picker'; +import { WebElementWrapper } from '../lib/web_element_wrapper'; -export function DashboardCustomizePanelProvider({ getService }: FtrProviderContext) { +export function DashboardCustomizePanelProvider({ getService, getPageObject }: FtrProviderContext) { const log = getService('log'); const retry = getService('retry'); const toasts = getService('toasts'); @@ -39,6 +40,48 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte await testSubjects.missingOrFail(this.TOGGLE_TIME_RANGE_TEST_SUBJ); } + public async findCustomTimeRangeToggleButton(): Promise { + log.debug('findCustomTimeRangeToggleButton'); + let button: WebElementWrapper | undefined; + await retry.waitFor('custom time range toggle button', async () => { + button = await testSubjects.find(this.TOGGLE_TIME_RANGE_TEST_SUBJ); + return Boolean(button); + }); + return button!; + } + + public async enableCustomTimeRange() { + log.debug('enableCustomTimeRange'); + const toggle = await this.findCustomTimeRangeToggleButton(); + + await retry.try(async () => { + if ((await toggle.getAttribute('aria-checked')) === 'false') { + await toggle.click(); + await retry.waitForWithTimeout( + 'custom time range to be enabled', + 1000, + async () => (await toggle.getAttribute('aria-checked')) === 'true' + ); + } + }); + } + + public async disableCustomTimeRange() { + log.debug('disableCustomTimeRange'); + const toggle = await this.findCustomTimeRangeToggleButton(); + + await retry.try(async () => { + if ((await toggle.getAttribute('aria-checked')) === 'true') { + await toggle.click(); + await retry.waitForWithTimeout( + 'custom time range to be disabled', + 1000, + async () => (await toggle.getAttribute('aria-checked')) === 'false' + ); + } + }); + } + public async findFlyout() { log.debug('findFlyout'); return await testSubjects.find(this.FLYOUT_TEST_SUBJ); @@ -50,15 +93,21 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte return await flyout.findByCssSelector(`[data-test-subj="${testSubject}"]`); } - public async findToggleQuickMenuButton() { - log.debug('findToggleQuickMenuButton'); + public async findDatePickerQuickMenuButton() { + log.debug('findDatePickerQuickMenuButton'); return await this.findFlyoutTestSubject('superDatePickerToggleQuickMenuButton'); } - public async clickToggleQuickMenuButton() { - log.debug('clickToggleQuickMenuButton'); - const button = await this.findToggleQuickMenuButton(); - await button.click(); + public async openDatePickerQuickMenu() { + log.debug('openDatePickerQuickMenu'); + let button: WebElementWrapper | undefined; + await retry.waitFor('superDatePickerToggleQuickMenuButton to be present', async () => { + button = await this.findDatePickerQuickMenuButton(); + return Boolean(button); + }); + if (button) { + await button.click(); + } } public async clickCommonlyUsedTimeRange(time: CommonlyUsed) { @@ -111,10 +160,5 @@ export function DashboardCustomizePanelProvider({ getService }: FtrProviderConte await testSubjects.waitForDeleted('cancelCustomizePanelButton'); }); } - - public async clickToggleShowCustomTimeRange() { - log.debug('clickToggleShowCustomTimeRange'); - await testSubjects.click(this.TOGGLE_TIME_RANGE_TEST_SUBJ); - } })(); } diff --git a/tsconfig.base.json b/tsconfig.base.json index 31381c8271962..a33f7b1cd960b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1072,6 +1072,8 @@ "@kbn/oidc-provider-plugin/*": ["x-pack/test/security_api_integration/plugins/oidc_provider/*"], "@kbn/open-telemetry-instrumented-plugin": ["test/common/plugins/otel_metrics"], "@kbn/open-telemetry-instrumented-plugin/*": ["test/common/plugins/otel_metrics/*"], + "@kbn/openapi-generator": ["packages/kbn-openapi-generator"], + "@kbn/openapi-generator/*": ["packages/kbn-openapi-generator/*"], "@kbn/optimizer": ["packages/kbn-optimizer"], "@kbn/optimizer/*": ["packages/kbn-optimizer/*"], "@kbn/optimizer-webpack-helpers": ["packages/kbn-optimizer-webpack-helpers"], diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx index 65b8183b60a0b..2f46e99d12b07 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.test.tsx @@ -126,4 +126,88 @@ describe('fetchConnectorExecuteAction', () => { expect(result).toBe('Test response'); }); + + it('returns the value of the action_input property when assistantLangChain is true, and `content` has properly prefixed and suffixed JSON with the action_input property', async () => { + const content = '```json\n{"action_input": "value from action_input"}\n```'; + + (mockHttp.fetch as jest.Mock).mockResolvedValue({ + status: 'ok', + data: { + choices: [ + { + message: { + content, + }, + }, + ], + }, + }); + + const testProps: FetchConnectorExecuteAction = { + assistantLangChain: true, // <-- requires response parsing + http: mockHttp, + messages, + apiConfig, + }; + + const result = await fetchConnectorExecuteAction(testProps); + + expect(result).toBe('value from action_input'); + }); + + it('returns the original content when assistantLangChain is true, and `content` has properly formatted JSON WITHOUT the action_input property', async () => { + const content = '```json\n{"some_key": "some value"}\n```'; + + (mockHttp.fetch as jest.Mock).mockResolvedValue({ + status: 'ok', + data: { + choices: [ + { + message: { + content, + }, + }, + ], + }, + }); + + const testProps: FetchConnectorExecuteAction = { + assistantLangChain: true, // <-- requires response parsing + http: mockHttp, + messages, + apiConfig, + }; + + const result = await fetchConnectorExecuteAction(testProps); + + expect(result).toBe(content); + }); + + it('returns the original when assistantLangChain is true, and `content` is not JSON', async () => { + const content = 'plain text content'; + + (mockHttp.fetch as jest.Mock).mockResolvedValue({ + status: 'ok', + data: { + choices: [ + { + message: { + content, + }, + }, + ], + }, + }); + + const testProps: FetchConnectorExecuteAction = { + assistantLangChain: true, // <-- requires response parsing + http: mockHttp, + messages, + apiConfig, + }; + + const result = await fetchConnectorExecuteAction(testProps); + + expect(result).toBe(content); + }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx index 511b5aa585af0..6d3452b6f7880 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/api.tsx @@ -12,6 +12,7 @@ import { HttpSetup, IHttpFetchError } from '@kbn/core-http-browser'; import type { Conversation, Message } from '../assistant_context/types'; import { API_ERROR } from './translations'; import { MODEL_GPT_3_5_TURBO } from '../connectorland/models/model_selector/model_selector'; +import { getFormattedMessageContent } from './helpers'; export interface FetchConnectorExecuteAction { assistantLangChain: boolean; @@ -78,7 +79,8 @@ export const fetchConnectorExecuteAction = async ({ if (data.choices && data.choices.length > 0 && data.choices[0].message.content) { const result = data.choices[0].message.content.trim(); - return result; + + return assistantLangChain ? getFormattedMessageContent(result) : result; } else { return API_ERROR; } diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts index 69bed887e730e..f2b89a07c319e 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.test.ts @@ -5,7 +5,11 @@ * 2.0. */ -import { getDefaultConnector, getBlockBotConversation } from './helpers'; +import { + getBlockBotConversation, + getDefaultConnector, + getFormattedMessageContent, +} from './helpers'; import { enterpriseMessaging } from './use_conversation/sample_conversations'; import { ActionConnector } from '@kbn/triggers-actions-ui-plugin/public'; @@ -190,4 +194,41 @@ describe('getBlockBotConversation', () => { expect(result).toBeUndefined(); }); }); + + describe('getFormattedMessageContent', () => { + it('returns the value of the action_input property when `content` has properly prefixed and suffixed JSON with the action_input property', () => { + const content = '```json\n{"action_input": "value from action_input"}\n```'; + + expect(getFormattedMessageContent(content)).toBe('value from action_input'); + }); + + it('returns the original content when `content` has properly formatted JSON WITHOUT the action_input property', () => { + const content = '```json\n{"some_key": "some value"}\n```'; + expect(getFormattedMessageContent(content)).toBe(content); + }); + + it('returns the original content when `content` has improperly formatted JSON', () => { + const content = '```json\n{"action_input": "value from action_input",}\n```'; // <-- the trailing comma makes it invalid + + expect(getFormattedMessageContent(content)).toBe(content); + }); + + it('returns the original content when `content` is missing the prefix', () => { + const content = '{"action_input": "value from action_input"}\n```'; // <-- missing prefix + + expect(getFormattedMessageContent(content)).toBe(content); + }); + + it('returns the original content when `content` is missing the suffix', () => { + const content = '```json\n{"action_input": "value from action_input"}'; // <-- missing suffix + + expect(getFormattedMessageContent(content)).toBe(content); + }); + + it('returns the original content when `content` does NOT contain a JSON string', () => { + const content = 'plain text content'; + + expect(getFormattedMessageContent(content)).toBe(content); + }); + }); }); diff --git a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts index b01c9001e8319..2b2c5b76851f7 100644 --- a/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts +++ b/x-pack/packages/kbn-elastic-assistant/impl/assistant/helpers.ts @@ -59,3 +59,24 @@ export const getDefaultConnector = ( connectors: Array, Record>> | undefined ): ActionConnector, Record> | undefined => connectors?.length === 1 ? connectors[0] : undefined; + +/** + * When `content` is a JSON string, prefixed with "```json\n" + * and suffixed with "\n```", this function will attempt to parse it and return + * the `action_input` property if it exists. + */ +export const getFormattedMessageContent = (content: string): string => { + const formattedContentMatch = content.match(/```json\n([\s\S]+)\n```/); + + if (formattedContentMatch) { + try { + const parsedContent = JSON.parse(formattedContentMatch[1]); + + return parsedContent.action_input ?? content; + } catch { + // we don't want to throw an error here, so we'll fall back to the original content + } + } + + return content; +}; diff --git a/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx b/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx index e3e5a1de3d65f..fcf4622e87cc0 100644 --- a/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx +++ b/x-pack/packages/ml/date_picker/src/components/full_time_range_selector.tsx @@ -98,6 +98,7 @@ export const FullTimeRangeSelector: FC = (props) => apiPath, hideFrozenDataTierChoice = false, } = props; + const { http, notifications: { toasts }, diff --git a/x-pack/packages/ml/trained_models_utils/index.ts b/x-pack/packages/ml/trained_models_utils/index.ts index ba67911f3f8ab..22b808bdc7b5e 100644 --- a/x-pack/packages/ml/trained_models_utils/index.ts +++ b/x-pack/packages/ml/trained_models_utils/index.ts @@ -14,4 +14,10 @@ export { type DeploymentState, type SupportedPytorchTasksType, type TrainedModelType, + ELASTIC_MODEL_DEFINITIONS, + type ElasticModelId, + type ModelDefinition, + type ModelDefinitionResponse, + type ElserVersion, + type GetElserOptions, } from './src/constants/trained_models'; diff --git a/x-pack/packages/ml/trained_models_utils/src/constants/trained_models.ts b/x-pack/packages/ml/trained_models_utils/src/constants/trained_models.ts index 86b88f51a66c4..4580330119ddd 100644 --- a/x-pack/packages/ml/trained_models_utils/src/constants/trained_models.ts +++ b/x-pack/packages/ml/trained_models_utils/src/constants/trained_models.ts @@ -46,8 +46,9 @@ export const BUILT_IN_MODEL_TAG = 'prepackaged'; export const ELASTIC_MODEL_TAG = 'elastic'; -export const ELASTIC_MODEL_DEFINITIONS = { +export const ELASTIC_MODEL_DEFINITIONS: Record = Object.freeze({ '.elser_model_1': { + version: 1, config: { input: { field_names: ['text_field'], @@ -57,7 +58,49 @@ export const ELASTIC_MODEL_DEFINITIONS = { defaultMessage: 'Elastic Learned Sparse EncodeR v1 (Tech Preview)', }), }, -} as const; + '.elser_model_2_SNAPSHOT': { + version: 2, + default: true, + config: { + input: { + field_names: ['text_field'], + }, + }, + description: i18n.translate('xpack.ml.trainedModels.modelsList.elserV2Description', { + defaultMessage: 'Elastic Learned Sparse EncodeR v2 (Tech Preview)', + }), + }, + '.elser_model_2_linux-x86_64_SNAPSHOT': { + version: 2, + os: 'Linux', + arch: 'amd64', + config: { + input: { + field_names: ['text_field'], + }, + }, + description: i18n.translate('xpack.ml.trainedModels.modelsList.elserV2x86Description', { + defaultMessage: + 'Elastic Learned Sparse EncodeR v2, optimized for linux-x86_64 (Tech Preview)', + }), + }, +} as const); + +export interface ModelDefinition { + version: number; + config: object; + description: string; + os?: string; + arch?: string; + default?: boolean; + recommended?: boolean; +} + +export type ModelDefinitionResponse = ModelDefinition & { + name: string; +}; + +export type ElasticModelId = keyof typeof ELASTIC_MODEL_DEFINITIONS; export const MODEL_STATE = { ...DEPLOYMENT_STATE, @@ -66,3 +109,9 @@ export const MODEL_STATE = { } as const; export type ModelState = typeof MODEL_STATE[keyof typeof MODEL_STATE] | null; + +export type ElserVersion = 1 | 2; + +export interface GetElserOptions { + version?: ElserVersion; +} diff --git a/x-pack/plugins/actions/docs/openapi/bundled.json b/x-pack/plugins/actions/docs/openapi/bundled.json index f79bb3ca9c0fe..94efaf061fb4f 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.json +++ b/x-pack/plugins/actions/docs/openapi/bundled.json @@ -111,6 +111,9 @@ { "$ref": "#/components/schemas/create_connector_request_tines" }, + { + "$ref": "#/components/schemas/create_connector_request_torq" + }, { "$ref": "#/components/schemas/create_connector_request_webhook" }, @@ -389,6 +392,9 @@ { "$ref": "#/components/schemas/create_connector_request_tines" }, + { + "$ref": "#/components/schemas/create_connector_request_torq" + }, { "$ref": "#/components/schemas/create_connector_request_webhook" }, @@ -508,6 +514,12 @@ { "$ref": "#/components/schemas/update_connector_request_teams" }, + { + "$ref": "#/components/schemas/update_connector_request_tines" + }, + { + "$ref": "#/components/schemas/update_connector_request_torq" + }, { "$ref": "#/components/schemas/update_connector_request_webhook" }, @@ -2789,13 +2801,34 @@ "title": "Connector request properties for a Tines connector", "description": "Defines properties for connectors when type is `.tines`.", "type": "object", - "additionalProperties": true + "required": [ + "url" + ], + "properties": { + "url": { + "description": "The Tines tenant URL. If you are using the `xpack.actions.allowedHosts` setting, make sure this hostname is added to the allowed hosts.\n", + "type": "string" + } + } }, "secrets_properties_tines": { "title": "Connector secrets properties for a Tines connector", "description": "Defines secrets for connectors when type is `.tines`.", "type": "object", - "additionalProperties": true + "required": [ + "email", + "token" + ], + "properties": { + "email": { + "description": "The email used to sign in to Tines.", + "type": "string" + }, + "token": { + "description": "The Tines API token.", + "type": "string" + } + } }, "create_connector_request_tines": { "title": "Create Tines connector request", @@ -2829,6 +2862,66 @@ } } }, + "config_properties_torq": { + "title": "Connector request properties for a Torq connector", + "description": "Defines properties for connectors when type is `.torq`.", + "type": "object", + "required": [ + "webhookIntegrationUrl" + ], + "properties": { + "webhookIntegrationUrl": { + "description": "The endpoint URL of the Elastic Security integration in Torq.", + "type": "string" + } + } + }, + "secrets_properties_torq": { + "title": "Connector secrets properties for a Torq connector", + "description": "Defines secrets for connectors when type is `.torq`.", + "type": "object", + "required": [ + "token" + ], + "properties": { + "token": { + "description": "The secret of the webhook authentication header.", + "type": "string" + } + } + }, + "create_connector_request_torq": { + "title": "Create Torq connector request", + "description": "The Torq connector uses a Torq webhook to trigger workflows with Kibana actions.\n", + "type": "object", + "required": [ + "config", + "connector_type_id", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_torq" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".torq" + ], + "example": ".torq" + }, + "name": { + "type": "string", + "description": "The display name for the connector.", + "example": "my-connector" + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_torq" + } + } + }, "config_properties_webhook": { "title": "Connector request properties for a Webhook connector", "description": "Defines properties for connectors when type is `.webhook`.", @@ -3776,6 +3869,50 @@ } } }, + "connector_response_properties_torq": { + "title": "Connector response properties for a Torq connector", + "type": "object", + "required": [ + "config", + "connector_type_id", + "id", + "is_deprecated", + "is_preconfigured", + "name" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_torq" + }, + "connector_type_id": { + "type": "string", + "description": "The type of connector.", + "enum": [ + ".torq" + ] + }, + "id": { + "type": "string", + "description": "The identifier for the connector." + }, + "is_deprecated": { + "$ref": "#/components/schemas/is_deprecated" + }, + "is_missing_secrets": { + "$ref": "#/components/schemas/is_missing_secrets" + }, + "is_preconfigured": { + "$ref": "#/components/schemas/is_preconfigured" + }, + "is_system_action": { + "$ref": "#/components/schemas/is_system_action" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + } + } + }, "connector_response_properties_webhook": { "title": "Connector response properties for a Webhook connector", "type": "object", @@ -3919,6 +4056,9 @@ { "$ref": "#/components/schemas/connector_response_properties_tines" }, + { + "$ref": "#/components/schemas/connector_response_properties_torq" + }, { "$ref": "#/components/schemas/connector_response_properties_webhook" }, @@ -4221,6 +4361,48 @@ } } }, + "update_connector_request_tines": { + "title": "Update Tines connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_tines" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_tines" + } + } + }, + "update_connector_request_torq": { + "title": "Update Torq connector request", + "type": "object", + "required": [ + "config", + "name", + "secrets" + ], + "properties": { + "config": { + "$ref": "#/components/schemas/config_properties_torq" + }, + "name": { + "type": "string", + "description": "The display name for the connector." + }, + "secrets": { + "$ref": "#/components/schemas/secrets_properties_torq" + } + } + }, "update_connector_request_webhook": { "title": "Update Webhook connector request", "type": "object", @@ -4286,6 +4468,7 @@ ".swimlane", ".teams", ".tines", + ".torq", ".webhook", ".xmatters" ], diff --git a/x-pack/plugins/actions/docs/openapi/bundled.yaml b/x-pack/plugins/actions/docs/openapi/bundled.yaml index ed97fb7f31233..b1ff36d6f3370 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled.yaml @@ -55,6 +55,7 @@ paths: - $ref: '#/components/schemas/create_connector_request_swimlane' - $ref: '#/components/schemas/create_connector_request_teams' - $ref: '#/components/schemas/create_connector_request_tines' + - $ref: '#/components/schemas/create_connector_request_torq' - $ref: '#/components/schemas/create_connector_request_webhook' - $ref: '#/components/schemas/create_connector_request_xmatters' discriminator: @@ -208,6 +209,7 @@ paths: - $ref: '#/components/schemas/create_connector_request_swimlane' - $ref: '#/components/schemas/create_connector_request_teams' - $ref: '#/components/schemas/create_connector_request_tines' + - $ref: '#/components/schemas/create_connector_request_torq' - $ref: '#/components/schemas/create_connector_request_webhook' - $ref: '#/components/schemas/create_connector_request_xmatters' discriminator: @@ -264,6 +266,8 @@ paths: - $ref: '#/components/schemas/update_connector_request_slack_webhook' - $ref: '#/components/schemas/update_connector_request_swimlane' - $ref: '#/components/schemas/update_connector_request_teams' + - $ref: '#/components/schemas/update_connector_request_tines' + - $ref: '#/components/schemas/update_connector_request_torq' - $ref: '#/components/schemas/update_connector_request_webhook' - $ref: '#/components/schemas/update_connector_request_xmatters' examples: @@ -1885,12 +1889,27 @@ components: title: Connector request properties for a Tines connector description: Defines properties for connectors when type is `.tines`. type: object - additionalProperties: true + required: + - url + properties: + url: + description: | + The Tines tenant URL. If you are using the `xpack.actions.allowedHosts` setting, make sure this hostname is added to the allowed hosts. + type: string secrets_properties_tines: title: Connector secrets properties for a Tines connector description: Defines secrets for connectors when type is `.tines`. type: object - additionalProperties: true + required: + - email + - token + properties: + email: + description: The email used to sign in to Tines. + type: string + token: + description: The Tines API token. + type: string create_connector_request_tines: title: Create Tines connector request description: | @@ -1916,6 +1935,51 @@ components: example: my-connector secrets: $ref: '#/components/schemas/secrets_properties_tines' + config_properties_torq: + title: Connector request properties for a Torq connector + description: Defines properties for connectors when type is `.torq`. + type: object + required: + - webhookIntegrationUrl + properties: + webhookIntegrationUrl: + description: The endpoint URL of the Elastic Security integration in Torq. + type: string + secrets_properties_torq: + title: Connector secrets properties for a Torq connector + description: Defines secrets for connectors when type is `.torq`. + type: object + required: + - token + properties: + token: + description: The secret of the webhook authentication header. + type: string + create_connector_request_torq: + title: Create Torq connector request + description: | + The Torq connector uses a Torq webhook to trigger workflows with Kibana actions. + type: object + required: + - config + - connector_type_id + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_torq' + connector_type_id: + type: string + description: The type of connector. + enum: + - .torq + example: .torq + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: '#/components/schemas/secrets_properties_torq' config_properties_webhook: title: Connector request properties for a Webhook connector description: Defines properties for connectors when type is `.webhook`. @@ -2626,6 +2690,38 @@ components: name: type: string description: The display name for the connector. + connector_response_properties_torq: + title: Connector response properties for a Torq connector + type: object + required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name + properties: + config: + $ref: '#/components/schemas/config_properties_torq' + connector_type_id: + type: string + description: The type of connector. + enum: + - .torq + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: '#/components/schemas/is_deprecated' + is_missing_secrets: + $ref: '#/components/schemas/is_missing_secrets' + is_preconfigured: + $ref: '#/components/schemas/is_preconfigured' + is_system_action: + $ref: '#/components/schemas/is_system_action' + name: + type: string + description: The display name for the connector. connector_response_properties_webhook: title: Connector response properties for a Webhook connector type: object @@ -2711,6 +2807,7 @@ components: - $ref: '#/components/schemas/connector_response_properties_swimlane' - $ref: '#/components/schemas/connector_response_properties_teams' - $ref: '#/components/schemas/connector_response_properties_tines' + - $ref: '#/components/schemas/connector_response_properties_torq' - $ref: '#/components/schemas/connector_response_properties_webhook' - $ref: '#/components/schemas/connector_response_properties_xmatters' discriminator: @@ -2922,6 +3019,36 @@ components: description: The display name for the connector. secrets: $ref: '#/components/schemas/secrets_properties_teams' + update_connector_request_tines: + title: Update Tines connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_tines' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_tines' + update_connector_request_torq: + title: Update Torq connector request + type: object + required: + - config + - name + - secrets + properties: + config: + $ref: '#/components/schemas/config_properties_torq' + name: + type: string + description: The display name for the connector. + secrets: + $ref: '#/components/schemas/secrets_properties_torq' update_connector_request_webhook: title: Update Webhook connector request type: object @@ -2975,6 +3102,7 @@ components: - .swimlane - .teams - .tines + - .torq - .webhook - .xmatters example: .server-log diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml index 336a312d9ac8e..2bb480d7c18b2 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_tines.yaml @@ -1,5 +1,11 @@ title: Connector request properties for a Tines connector description: Defines properties for connectors when type is `.tines`. type: object -additionalProperties: true -# TO-DO: Add the properties for this connector. \ No newline at end of file +required: + - url +properties: + url: + description: > + The Tines tenant URL. + If you are using the `xpack.actions.allowedHosts` setting, make sure this hostname is added to the allowed hosts. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_torq.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_torq.yaml new file mode 100644 index 0000000000000..06808a37a75fc --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_torq.yaml @@ -0,0 +1,9 @@ +title: Connector request properties for a Torq connector +description: Defines properties for connectors when type is `.torq`. +type: object +required: + - webhookIntegrationUrl +properties: + webhookIntegrationUrl: + description: The endpoint URL of the Elastic Security integration in Torq. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml index 334fe3fa5cdb3..edef270fd75ae 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties.yaml @@ -18,6 +18,7 @@ oneOf: - $ref: 'connector_response_properties_swimlane.yaml' - $ref: 'connector_response_properties_teams.yaml' - $ref: 'connector_response_properties_tines.yaml' + - $ref: 'connector_response_properties_torq.yaml' - $ref: 'connector_response_properties_webhook.yaml' - $ref: 'connector_response_properties_xmatters.yaml' discriminator: diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_torq.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_torq.yaml new file mode 100644 index 0000000000000..135d5e9db6cb4 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_torq.yaml @@ -0,0 +1,31 @@ +title: Connector response properties for a Torq connector +type: object +required: + - config + - connector_type_id + - id + - is_deprecated + - is_preconfigured + - name +properties: + config: + $ref: 'config_properties_torq.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .torq + id: + type: string + description: The identifier for the connector. + is_deprecated: + $ref: 'is_deprecated.yaml' + is_missing_secrets: + $ref: 'is_missing_secrets.yaml' + is_preconfigured: + $ref: 'is_preconfigured.yaml' + is_system_action: + $ref: 'is_system_action.yaml' + name: + type: string + description: The display name for the connector. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml index 2bbc9f5dabac4..687648acd7141 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_types.yaml @@ -20,6 +20,7 @@ enum: - .swimlane - .teams - .tines + - .torq - .webhook - .xmatters example: .server-log \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_torq.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_torq.yaml new file mode 100644 index 0000000000000..934f9c9c1b395 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_torq.yaml @@ -0,0 +1,24 @@ +title: Create Torq connector request +description: > + The Torq connector uses a Torq webhook to trigger workflows with Kibana actions. +type: object +required: + - config + - connector_type_id + - name + - secrets +properties: + config: + $ref: 'config_properties_torq.yaml' + connector_type_id: + type: string + description: The type of connector. + enum: + - .torq + example: .torq + name: + type: string + description: The display name for the connector. + example: my-connector + secrets: + $ref: 'secrets_properties_torq.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml index 2373f14beae50..e480505dc1938 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_tines.yaml @@ -1,5 +1,13 @@ title: Connector secrets properties for a Tines connector description: Defines secrets for connectors when type is `.tines`. type: object -additionalProperties: true -# TO-DO: Add the properties for this connector. \ No newline at end of file +required: + - email + - token +properties: + email: + description: The email used to sign in to Tines. + type: string + token: + description: The Tines API token. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_torq.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_torq.yaml new file mode 100644 index 0000000000000..ab79a0f672b42 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/secrets_properties_torq.yaml @@ -0,0 +1,9 @@ +title: Connector secrets properties for a Torq connector +description: Defines secrets for connectors when type is `.torq`. +type: object +required: + - token +properties: + token: + description: The secret of the webhook authentication header. + type: string \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_torq.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_torq.yaml new file mode 100644 index 0000000000000..f82de22f3e27b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_torq.yaml @@ -0,0 +1,14 @@ +title: Update Torq connector request +type: object +required: + - config + - name + - secrets +properties: + config: + $ref: 'config_properties_torq.yaml' + name: + type: string + description: The display name for the connector. + secrets: + $ref: 'secrets_properties_torq.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml index f32def50706b2..62f2e1821eb8f 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector.yaml @@ -34,6 +34,7 @@ post: - $ref: '../components/schemas/create_connector_request_swimlane.yaml' - $ref: '../components/schemas/create_connector_request_teams.yaml' - $ref: '../components/schemas/create_connector_request_tines.yaml' + - $ref: '../components/schemas/create_connector_request_torq.yaml' - $ref: '../components/schemas/create_connector_request_webhook.yaml' - $ref: '../components/schemas/create_connector_request_xmatters.yaml' discriminator: diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml index c6a2447c251a2..d85e38cff5f75 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector@{connectorid}.yaml @@ -118,6 +118,7 @@ post: - $ref: '../components/schemas/create_connector_request_swimlane.yaml' - $ref: '../components/schemas/create_connector_request_teams.yaml' - $ref: '../components/schemas/create_connector_request_tines.yaml' + - $ref: '../components/schemas/create_connector_request_torq.yaml' - $ref: '../components/schemas/create_connector_request_webhook.yaml' - $ref: '../components/schemas/create_connector_request_xmatters.yaml' discriminator: @@ -175,7 +176,8 @@ put: - $ref: '../components/schemas/update_connector_request_slack_webhook.yaml' - $ref: '../components/schemas/update_connector_request_swimlane.yaml' - $ref: '../components/schemas/update_connector_request_teams.yaml' -# - $ref: '../components/schemas/update_connector_request_tines.yaml' + - $ref: '../components/schemas/update_connector_request_tines.yaml' + - $ref: '../components/schemas/update_connector_request_torq.yaml' - $ref: '../components/schemas/update_connector_request_webhook.yaml' - $ref: '../components/schemas/update_connector_request_xmatters.yaml' examples: diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts index c17bedeb8635a..04b8f7f41bdf1 100644 --- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts +++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts @@ -12,9 +12,9 @@ import { isEmpty, pickBy } from 'lodash'; import moment from 'moment'; import url from 'url'; import type { InfraLocators } from '@kbn/infra-plugin/common/locators'; -import type { ProfilingLocators } from '@kbn/profiling-plugin/public'; import { LocatorPublic } from '@kbn/share-plugin/common'; import { AllDatasetsLocatorParams } from '@kbn/deeplinks-observability/locators'; +import type { ProfilingLocators } from '@kbn/observability-shared-plugin/public'; import { Environment } from '../../../../common/environment_rt'; import type { Transaction } from '../../../../typings/es_schemas/ui/transaction'; import { getDiscoverHref } from '../links/discover_links/discover_link'; diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx index 162fdf8e90b85..4dcd10a3ea540 100644 --- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx +++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx @@ -18,7 +18,6 @@ import { SectionSubtitle, SectionTitle, } from '@kbn/observability-shared-plugin/public'; -import { ProfilingLocators } from '@kbn/profiling-plugin/public'; import React, { useState } from 'react'; import { useLocation } from 'react-router-dom'; import useAsync from 'react-use/lib/useAsync'; @@ -26,6 +25,7 @@ import { AllDatasetsLocatorParams, ALL_DATASETS_LOCATOR_ID, } from '@kbn/deeplinks-observability/locators'; +import type { ProfilingLocators } from '@kbn/observability-shared-plugin/public'; import { useAnyOfApmParams } from '../../../hooks/use_apm_params'; import { ApmFeatureFlagName } from '../../../../common/apm_feature_flags'; import { Transaction } from '../../../../typings/es_schemas/ui/transaction'; diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts index f7ae6ea53147a..eff505b22bd4a 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts @@ -6,7 +6,7 @@ */ import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types'; -import { APMRouteHandlerResources } from '../../../../routes/typings'; +import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes'; type InfraMetricsSearchParams = Omit & { size: number; diff --git a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts deleted file mode 100644 index 24b76edb4d887..0000000000000 --- a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts +++ /dev/null @@ -1,25 +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 { SavedObjectsClientContract } from '@kbn/core/server'; -import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes'; - -export async function getInfraMetricIndices({ - infraPlugin, - savedObjectsClient, -}: { - infraPlugin: Required; - savedObjectsClient: SavedObjectsClientContract; -}): Promise { - if (!infraPlugin) { - throw new Error('Infra Plugin needs to be setup'); - } - const infra = await infraPlugin.start(); - const infraMetricIndices = await infra.getMetricIndices(savedObjectsClient); - - return infraMetricIndices; -} diff --git a/x-pack/plugins/apm/server/routes/infrastructure/route.ts b/x-pack/plugins/apm/server/routes/infrastructure/route.ts index 4117a43ce1e3f..9050f1a46622c 100644 --- a/x-pack/plugins/apm/server/routes/infrastructure/route.ts +++ b/x-pack/plugins/apm/server/routes/infrastructure/route.ts @@ -5,7 +5,6 @@ * 2.0. */ import * as t from 'io-ts'; -import Boom from '@hapi/boom'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; @@ -30,10 +29,6 @@ const infrastructureRoute = createApmServerRoute({ hostNames: string[]; podNames: string[]; }> => { - if (!resources.plugins.infra) { - throw Boom.notFound(); - } - const apmEventClient = await getApmEventClient(resources); const infraMetricsClient = createInfraMetricsClient(resources); const { params } = resources; diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index 4ac0a37b3d10d..970a72d478f72 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -250,7 +250,7 @@ const serviceMetadataDetailsRoute = createApmServerRoute({ end, }); - if (serviceMetadataDetails?.container?.ids && resources.plugins.infra) { + if (serviceMetadataDetails?.container?.ids) { const infraMetricsClient = createInfraMetricsClient(resources); const containerMetadata = await getServiceOverviewContainerMetadata({ infraMetricsClient, @@ -761,10 +761,7 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({ end, }); - if ( - serviceInstanceMetadataDetails?.container?.id && - resources.plugins.infra - ) { + if (serviceInstanceMetadataDetails?.container?.id) { const infraMetricsClient = createInfraMetricsClient(resources); const containerMetadata = await getServiceInstanceContainerMetadata({ infraMetricsClient, diff --git a/x-pack/plugins/canvas/shareable_runtime/index.ts b/x-pack/plugins/canvas/shareable_runtime/index.ts index aee57c3780503..475989494c574 100644 --- a/x-pack/plugins/canvas/shareable_runtime/index.ts +++ b/x-pack/plugins/canvas/shareable_runtime/index.ts @@ -9,4 +9,3 @@ export * from './api'; import '@kbn/core-apps-server-internal/assets/legacy_light_theme.css'; import '../public/style/index.scss'; import '@elastic/eui/dist/eui_theme_light.css'; -import '@kbn/ui-framework/dist/kui_light.css'; diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index e1bcdc1f9a95f..7f0b4f62fb216 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -65,6 +65,8 @@ export const LATEST_VULNERABILITIES_RETENTION_POLICY = '3d'; export const DATA_VIEW_INDEX_PATTERN = 'logs-*'; +export const SECURITY_DEFAULT_DATA_VIEW_ID = 'security-solution-default'; + export const CSP_INGEST_TIMESTAMP_PIPELINE = 'cloud_security_posture_add_ingest_timestamp_pipeline'; export const CSP_LATEST_FINDINGS_INGEST_TIMESTAMP_PIPELINE = 'cloud_security_posture_latest_index_add_ingest_timestamp_pipeline'; diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts index 9bdd3bfada098..e3d213118dd51 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.test.ts @@ -6,7 +6,11 @@ */ import { renderHook, act } from '@testing-library/react-hooks/dom'; -import { useNavigateFindings, useNavigateFindingsByResource } from './use_navigate_findings'; +import { + useNavigateFindings, + useNavigateFindingsByResource, + useNavigateVulnerabilities, +} from './use_navigate_findings'; import { useHistory } from 'react-router-dom'; jest.mock('react-router-dom', () => ({ @@ -29,9 +33,17 @@ jest.mock('./use_kibana', () => ({ }, }), })); +jest.mock('../api/use_latest_findings_data_view', () => ({ + useLatestFindingsDataView: jest.fn().mockReturnValue({ + status: 'success', + data: { + id: 'data-view-id', + }, + }), +})); describe('useNavigateFindings', () => { - it('creates a URL to findings page with correct path and filter', () => { + it('creates a URL to findings page with correct path, filter and dataViewId', () => { const push = jest.fn(); (useHistory as jest.Mock).mockReturnValueOnce({ push }); @@ -44,7 +56,7 @@ describe('useNavigateFindings', () => { expect(push).toHaveBeenCalledWith({ pathname: '/cloud_security_posture/findings/configurations', search: - "cspq=(filters:!((meta:(alias:!n,disabled:!f,key:foo,negate:!f,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", + "cspq=(filters:!((meta:(alias:!n,disabled:!f,index:data-view-id,key:foo,negate:!f,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", }); expect(push).toHaveBeenCalledTimes(1); }); @@ -62,7 +74,7 @@ describe('useNavigateFindings', () => { expect(push).toHaveBeenCalledWith({ pathname: '/cloud_security_posture/findings/configurations', search: - "cspq=(filters:!((meta:(alias:!n,disabled:!f,key:foo,negate:!t,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", + "cspq=(filters:!((meta:(alias:!n,disabled:!f,index:data-view-id,key:foo,negate:!t,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", }); expect(push).toHaveBeenCalledTimes(1); }); @@ -80,7 +92,25 @@ describe('useNavigateFindings', () => { expect(push).toHaveBeenCalledWith({ pathname: '/cloud_security_posture/findings/resource', search: - "cspq=(filters:!((meta:(alias:!n,disabled:!f,key:foo,negate:!f,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", + "cspq=(filters:!((meta:(alias:!n,disabled:!f,index:data-view-id,key:foo,negate:!f,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", + }); + expect(push).toHaveBeenCalledTimes(1); + }); + + it('creates a URL to vulnerabilities page with correct path, filter and dataViewId', () => { + const push = jest.fn(); + (useHistory as jest.Mock).mockReturnValueOnce({ push }); + + const { result } = renderHook(() => useNavigateVulnerabilities()); + + act(() => { + result.current({ foo: 1 }); + }); + + expect(push).toHaveBeenCalledWith({ + pathname: '/cloud_security_posture/findings/vulnerabilities', + search: + "cspq=(filters:!((meta:(alias:!n,disabled:!f,index:security-solution-default,key:foo,negate:!f,type:phrase),query:(match_phrase:(foo:1)))),query:(language:kuery,query:''))", }); expect(push).toHaveBeenCalledTimes(1); }); diff --git a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts index 48b16f62cbaf5..fbeeeb32a0c2e 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/hooks/use_navigate_findings.ts @@ -8,9 +8,14 @@ import { useCallback } from 'react'; import { useHistory } from 'react-router-dom'; import { Filter } from '@kbn/es-query'; +import { + LATEST_FINDINGS_INDEX_PATTERN, + SECURITY_DEFAULT_DATA_VIEW_ID, +} from '../../../common/constants'; import { findingsNavigation } from '../navigation/constants'; import { encodeQuery } from '../navigation/query_utils'; import { useKibana } from './use_kibana'; +import { useLatestFindingsDataView } from '../api/use_latest_findings_data_view'; interface NegatedValue { value: string | number; @@ -21,7 +26,7 @@ type FilterValue = string | number | NegatedValue; export type NavFilter = Record; -const createFilter = (key: string, filterValue: FilterValue): Filter => { +const createFilter = (key: string, filterValue: FilterValue, dataViewId: string): Filter => { let negate = false; let value = filterValue; if (typeof filterValue === 'object') { @@ -32,7 +37,7 @@ const createFilter = (key: string, filterValue: FilterValue): Filter => { if (value === '*') { return { query: { exists: { field: key } }, - meta: { type: 'exists' }, + meta: { type: 'exists', index: dataViewId }, }; } return { @@ -42,18 +47,19 @@ const createFilter = (key: string, filterValue: FilterValue): Filter => { disabled: false, type: 'phrase', key, + index: dataViewId, }, query: { match_phrase: { [key]: value } }, }; }; -const useNavigate = (pathname: string) => { +const useNavigate = (pathname: string, dataViewId = SECURITY_DEFAULT_DATA_VIEW_ID) => { const history = useHistory(); const { services } = useKibana(); return useCallback( (filterParams: NavFilter = {}) => { const filters = Object.entries(filterParams).map(([key, filterValue]) => - createFilter(key, filterValue) + createFilter(key, filterValue, dataViewId) ); history.push({ @@ -65,14 +71,19 @@ const useNavigate = (pathname: string) => { }), }); }, - [pathname, history, services.data.query.queryString] + [pathname, history, services.data.query.queryString, dataViewId] ); }; -export const useNavigateFindings = () => useNavigate(findingsNavigation.findings_default.path); +export const useNavigateFindings = () => { + const { data } = useLatestFindingsDataView(LATEST_FINDINGS_INDEX_PATTERN); + return useNavigate(findingsNavigation.findings_default.path, data?.id); +}; -export const useNavigateFindingsByResource = () => - useNavigate(findingsNavigation.findings_by_resource.path); +export const useNavigateFindingsByResource = () => { + const { data } = useLatestFindingsDataView(LATEST_FINDINGS_INDEX_PATTERN); + return useNavigate(findingsNavigation.findings_by_resource.path, data?.id); +}; export const useNavigateVulnerabilities = () => useNavigate(findingsNavigation.vulnerabilities.path); diff --git a/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.test.tsx b/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.test.tsx new file mode 100644 index 0000000000000..1e2f2f52fd02a --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.test.tsx @@ -0,0 +1,138 @@ +/* + * 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 { render, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { DetectionRuleCounter } from './detection_rule_counter'; +import { TestProvider } from '../test/test_provider'; +import { useFetchDetectionRulesByTags } from '../common/api/use_fetch_detection_rules_by_tags'; +import { useFetchDetectionRulesAlertsStatus } from '../common/api/use_fetch_detection_rules_alerts_status'; +import { RuleResponse } from '../common/types'; + +jest.mock('../common/api/use_fetch_detection_rules_by_tags', () => ({ + useFetchDetectionRulesByTags: jest.fn(), +})); +jest.mock('../common/api/use_fetch_detection_rules_alerts_status', () => ({ + useFetchDetectionRulesAlertsStatus: jest.fn(), +})); + +describe('DetectionRuleCounter', () => { + beforeEach(() => { + jest.restoreAllMocks(); + }); + it('should render loading skeleton when both rules and alerts are loading', () => { + (useFetchDetectionRulesByTags as jest.Mock).mockReturnValue({ + data: undefined, + isLoading: true, + }); + + (useFetchDetectionRulesAlertsStatus as jest.Mock).mockReturnValue({ + data: undefined, + isLoading: true, + }); + const { getByTestId } = render( + + + + ); + + const skeletonText = getByTestId('csp:detection-rule-counter-loading'); + expect(skeletonText).toBeInTheDocument(); + }); + + it('should render create rule link when no rules exist', () => { + (useFetchDetectionRulesByTags as jest.Mock).mockReturnValue({ + data: { total: 0 }, + isLoading: false, + }); + + (useFetchDetectionRulesAlertsStatus as jest.Mock).mockReturnValue({ + data: null, + isLoading: false, + isFetching: false, + }); + + const { getByText, getByTestId } = render( + + + + ); + + const createRuleLink = getByTestId('csp:findings-flyout-create-detection-rule-link'); + expect(createRuleLink).toBeInTheDocument(); + expect(getByText('Create a detection rule')).toBeInTheDocument(); + }); + + it('should render alert and rule count when rules exist', () => { + (useFetchDetectionRulesByTags as jest.Mock).mockReturnValue({ + data: { total: 5 }, + isLoading: false, + }); + + (useFetchDetectionRulesAlertsStatus as jest.Mock).mockReturnValue({ + data: { total: 10 }, + isLoading: false, + isFetching: false, + }); + + const { getByText, getByTestId } = render( + + + + ); + + const alertCountLink = getByTestId('csp:findings-flyout-alert-count'); + const ruleCountLink = getByTestId('csp:findings-flyout-detection-rule-count'); + + expect(alertCountLink).toBeInTheDocument(); + expect(getByText(/10 alerts/i)).toBeInTheDocument(); + expect(ruleCountLink).toBeInTheDocument(); + expect(getByText(/5 detection rules/i)).toBeInTheDocument(); + }); + + it('should show loading spinner when creating a rule', async () => { + (useFetchDetectionRulesByTags as jest.Mock).mockReturnValue({ + data: { total: 0 }, + isLoading: false, + }); + + (useFetchDetectionRulesAlertsStatus as jest.Mock).mockReturnValue({ + data: null, + isLoading: false, + isFetching: false, + }); + const createRuleFn = jest.fn(() => Promise.resolve({} as RuleResponse)); + const { getByTestId, queryByTestId } = render( + + + + ); + + // Trigger createDetectionRuleOnClick + const createRuleLink = getByTestId('csp:findings-flyout-create-detection-rule-link'); + userEvent.click(createRuleLink); + + const loadingSpinner = getByTestId('csp:findings-flyout-detection-rule-counter-loading'); + expect(loadingSpinner).toBeInTheDocument(); + + (useFetchDetectionRulesByTags as jest.Mock).mockReturnValue({ + data: { total: 1 }, + isLoading: false, + }); + + (useFetchDetectionRulesAlertsStatus as jest.Mock).mockReturnValue({ + data: { total: 0 }, + isLoading: false, + isFetching: false, + }); + + // Wait for the loading spinner to disappear + await waitFor(() => { + expect(queryByTestId('csp:findings-flyout-detection-rule-counter-loading')).toBeNull(); + }); + }); +}); diff --git a/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.tsx b/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.tsx index eeea89f9a310f..b2a79710d09a2 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/detection_rule_counter.tsx @@ -68,7 +68,12 @@ export const DetectionRuleCounter = ({ tags, createRuleFn }: DetectionRuleCounte }, [createRuleFn, http, notifications, queryClient]); return ( - + {rulesData?.total === 0 ? ( <> @@ -78,11 +83,17 @@ export const DetectionRuleCounter = ({ tags, createRuleFn }: DetectionRuleCounte id="xpack.csp.findingsFlyout.alerts.creatingRule" defaultMessage="Creating detection rule" />{' '} - + ) : ( <> - + ) : ( <> - + {' '} - + +
  • + +
  • {accountType === AWS_ORGANIZATION_ACCOUNT ? (
  • { list-style: auto; `} > +
  • + +
  • - {ruleResponse.name} + {ruleResponse.name} {` `} - + ({ - ConversationalRetrievalQAChain: { + RetrievalQAChain: { fromLLM: jest.fn().mockImplementation(() => mockConversationChain), }, })); +const mockCall = jest.fn(); +jest.mock('langchain/agents', () => ({ + initializeAgentExecutorWithOptions: jest.fn().mockImplementation(() => ({ + call: mockCall, + })), +})); + const mockConnectorId = 'mock-connector-id'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -42,7 +49,7 @@ const mockActions: ActionsPluginStart = {} as ActionsPluginStart; const mockLogger = loggerMock.create(); const esClientMock = elasticsearchServiceMock.createScopedClusterClient().asCurrentUser; -describe('executeCustomLlmChain', () => { +describe('callAgentExecutor', () => { beforeEach(() => { jest.clearAllMocks(); @@ -52,7 +59,7 @@ describe('executeCustomLlmChain', () => { }); it('creates an instance of ActionsClientLlm with the expected context from the request', async () => { - await executeCustomLlmChain({ + await callAgentExecutor({ actions: mockActions, connectorId: mockConnectorId, esClient: esClientMock, @@ -70,7 +77,7 @@ describe('executeCustomLlmChain', () => { }); it('kicks off the chain with (only) the last message', async () => { - await executeCustomLlmChain({ + await callAgentExecutor({ actions: mockActions, connectorId: mockConnectorId, esClient: esClientMock, @@ -79,15 +86,15 @@ describe('executeCustomLlmChain', () => { request: mockRequest, }); - expect(mockConversationChain.call).toHaveBeenCalledWith({ - question: '\n\nDo you know my name?', + expect(mockCall).toHaveBeenCalledWith({ + input: '\n\nDo you know my name?', }); }); it('kicks off the chain with the expected message when langChainMessages has only one entry', async () => { const onlyOneMessage = [langChainMessages[0]]; - await executeCustomLlmChain({ + await callAgentExecutor({ actions: mockActions, connectorId: mockConnectorId, esClient: esClientMock, @@ -96,13 +103,13 @@ describe('executeCustomLlmChain', () => { request: mockRequest, }); - expect(mockConversationChain.call).toHaveBeenCalledWith({ - question: 'What is my name?', + expect(mockCall).toHaveBeenCalledWith({ + input: 'What is my name?', }); }); it('returns the expected response body', async () => { - const result: ResponseBody = await executeCustomLlmChain({ + const result: ResponseBody = await callAgentExecutor({ actions: mockActions, connectorId: mockConnectorId, esClient: esClientMock, diff --git a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts index 5a65b1589b21e..b6a768ad69598 100644 --- a/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts +++ b/x-pack/plugins/elastic_assistant/server/lib/langchain/execute_custom_llm_chain/index.ts @@ -7,16 +7,18 @@ import { ElasticsearchClient, KibanaRequest, Logger } from '@kbn/core/server'; import type { PluginStartContract as ActionsPluginStart } from '@kbn/actions-plugin/server'; +import { initializeAgentExecutorWithOptions } from 'langchain/agents'; +import { RetrievalQAChain } from 'langchain/chains'; import { BufferMemory, ChatMessageHistory } from 'langchain/memory'; import { BaseMessage } from 'langchain/schema'; +import { ChainTool, Tool } from 'langchain/tools'; -import { ConversationalRetrievalQAChain } from 'langchain/chains'; +import { ElasticsearchStore } from '../elasticsearch_store/elasticsearch_store'; import { ResponseBody } from '../helpers'; import { ActionsClientLlm } from '../llm/actions_client_llm'; -import { ElasticsearchStore } from '../elasticsearch_store/elasticsearch_store'; import { KNOWLEDGE_BASE_INDEX_PATTERN } from '../../../routes/knowledge_base/constants'; -export const executeCustomLlmChain = async ({ +export const callAgentExecutor = async ({ actions, connectorId, esClient, @@ -34,31 +36,38 @@ export const executeCustomLlmChain = async ({ }): Promise => { const llm = new ActionsClientLlm({ actions, connectorId, request, logger }); - // Chat History Memory: in-memory memory, from client local storage, first message is the system prompt const pastMessages = langChainMessages.slice(0, -1); // all but the last message const latestMessage = langChainMessages.slice(-1); // the last message + const memory = new BufferMemory({ chatHistory: new ChatMessageHistory(pastMessages), - memoryKey: 'chat_history', + memoryKey: 'chat_history', // this is the key expected by https://github.com/langchain-ai/langchainjs/blob/a13a8969345b0f149c1ca4a120d63508b06c52a5/langchain/src/agents/initialize.ts#L166 + inputKey: 'input', + outputKey: 'output', + returnMessages: true, }); // ELSER backed ElasticsearchStore for Knowledge Base const esStore = new ElasticsearchStore(esClient, KNOWLEDGE_BASE_INDEX_PATTERN, logger); + const chain = RetrievalQAChain.fromLLM(llm, esStore.asRetriever()); + + const tools: Tool[] = [ + new ChainTool({ + name: 'esql-language-knowledge-base', + description: + 'Call this for knowledge on how to build an ESQL query, or answer questions about the ES|QL query language.', + chain, + }), + ]; - // Chain w/ chat history memory and knowledge base retriever - const chain = ConversationalRetrievalQAChain.fromLLM(llm, esStore.asRetriever(), { + const executor = await initializeAgentExecutorWithOptions(tools, llm, { + agentType: 'chat-conversational-react-description', memory, - // See `qaChainOptions` from https://js.langchain.com/docs/modules/chains/popular/chat_vector_db - qaChainOptions: { type: 'stuff' }, + verbose: false, }); - await chain.call({ question: latestMessage[0].content }); - // Chain w/ just knowledge base retriever - // const chain = RetrievalQAChain.fromLLM(llm, esStore.asRetriever()); - // await chain.call({ query: latestMessage[0].content }); + await executor.call({ input: latestMessage[0].content }); - // The assistant (on the client side) expects the same response returned - // from the actions framework, so we need to return the same shape of data: return { connector_id: connectorId, data: llm.getActionResultData(), // the response from the actions framework diff --git a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts index 2e6709a6e33c2..57f2b25f5a65f 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.test.ts @@ -20,7 +20,7 @@ jest.mock('../lib/build_response', () => ({ })); jest.mock('../lib/langchain/execute_custom_llm_chain', () => ({ - executeCustomLlmChain: jest.fn().mockImplementation( + callAgentExecutor: jest.fn().mockImplementation( async ({ connectorId, }: { diff --git a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts index 1043f68f0f9c1..bbb1c76e3e579 100644 --- a/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts +++ b/x-pack/plugins/elastic_assistant/server/routes/post_actions_connector_execute.ts @@ -20,7 +20,7 @@ import { PostActionsConnectorExecutePathParams, } from '../schemas/post_actions_connector_execute'; import { ElasticAssistantRequestHandlerContext } from '../types'; -import { executeCustomLlmChain } from '../lib/langchain/execute_custom_llm_chain'; +import { callAgentExecutor } from '../lib/langchain/execute_custom_llm_chain'; export const postActionsConnectorExecuteRoute = ( router: IRouter @@ -53,7 +53,7 @@ export const postActionsConnectorExecuteRoute = ( // convert the assistant messages to LangChain messages: const langChainMessages = getLangChainMessages(assistantMessages); - const langChainResponseBody = await executeCustomLlmChain({ + const langChainResponseBody = await callAgentExecutor({ actions, connectorId, esClient, diff --git a/x-pack/plugins/enterprise_search/server/index.ts b/x-pack/plugins/enterprise_search/server/index.ts index a82d6f18a3b26..3b9372f339acf 100644 --- a/x-pack/plugins/enterprise_search/server/index.ts +++ b/x-pack/plugins/enterprise_search/server/index.ts @@ -8,7 +8,7 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { PluginInitializerContext, PluginConfigDescriptor } from '@kbn/core/server'; -import { EnterpriseSearchPlugin, EnterpriseSearchPluginStart as PluginStart } from './plugin'; +import { EnterpriseSearchPlugin } from './plugin'; export const plugin = (initializerContext: PluginInitializerContext) => { return new EnterpriseSearchPlugin(initializerContext); @@ -54,5 +54,3 @@ export const config: PluginConfigDescriptor = { }; export const CRAWLERS_INDEX = '.ent-search-actastic-crawler2_configurations_v2'; - -export type EnterpriseSearchPluginStart = PluginStart; diff --git a/x-pack/plugins/enterprise_search/server/lib/crawler/fetch_crawler_multiple_schedules.ts b/x-pack/plugins/enterprise_search/server/lib/crawler/fetch_crawler_multiple_schedules.ts index d367e02ed6ab1..04f922e1702ed 100644 --- a/x-pack/plugins/enterprise_search/server/lib/crawler/fetch_crawler_multiple_schedules.ts +++ b/x-pack/plugins/enterprise_search/server/lib/crawler/fetch_crawler_multiple_schedules.ts @@ -7,9 +7,7 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { Connector } from '@kbn/search-connectors'; - -import { CONNECTORS_INDEX } from '../..'; +import { CONNECTORS_INDEX, Connector } from '@kbn/search-connectors'; const CUSTOM_SCHEDULING = 'custom_scheduling'; diff --git a/x-pack/plugins/enterprise_search/server/lib/crawler/post_crawler_multiple_schedules.ts b/x-pack/plugins/enterprise_search/server/lib/crawler/post_crawler_multiple_schedules.ts index 21d9f8b558800..539495e9556ae 100644 --- a/x-pack/plugins/enterprise_search/server/lib/crawler/post_crawler_multiple_schedules.ts +++ b/x-pack/plugins/enterprise_search/server/lib/crawler/post_crawler_multiple_schedules.ts @@ -7,7 +7,7 @@ import { IScopedClusterClient } from '@kbn/core/server'; -import { CONNECTORS_INDEX } from '../..'; +import { CONNECTORS_INDEX } from '@kbn/search-connectors'; import { CrawlerCustomScheduleMappingServer, diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index 52cb24271afa5..3548fee93fbf2 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -9,7 +9,7 @@ import { ElasticsearchAssetType, KibanaAssetType } from '../types/models'; export const PACKAGES_SAVED_OBJECT_TYPE = 'epm-packages'; export const ASSETS_SAVED_OBJECT_TYPE = 'epm-packages-assets'; -export const MAX_TIME_COMPLETE_INSTALL = 60000; +export const MAX_TIME_COMPLETE_INSTALL = 30 * 60 * 1000; // 30 minutes export const FLEET_SYSTEM_PACKAGE = 'system'; export const FLEET_ELASTIC_AGENT_PACKAGE = 'elastic_agent'; diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index 919d67392770d..a653bbfb8b223 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -5,6 +5,8 @@ * 2.0. */ +import type { SecurityRoleDescriptor } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; + import type { agentPolicyStatuses } from '../../constants'; import type { MonitoringType, PolicySecretReference, ValueOf } from '..'; @@ -77,15 +79,7 @@ export interface FullAgentPolicyInput { [key: string]: any; } -export interface FullAgentPolicyOutputPermissions { - [packagePolicyName: string]: { - cluster?: string[]; - indices?: Array<{ - names: string[]; - privileges: string[]; - }>; - }; -} +export type FullAgentPolicyOutputPermissions = Record; export type FullAgentPolicyOutput = Pick & { proxy_url?: string; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx index 0ca51d6f595fa..294754d28e509 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx @@ -20,8 +20,14 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { useQuery } from '@tanstack/react-query'; +import { useAgentPolicyWithPackagePolicies } from '../../../../../../../components/agent_enrollment_flyout/hooks'; + import type { AgentPolicy, PackagePolicy } from '../../../../../types'; -import { sendGetEnrollmentAPIKeys, useCreateCloudFormationUrl } from '../../../../../hooks'; +import { + sendGetEnrollmentAPIKeys, + useCreateCloudFormationUrl, + useFleetServerHostsForPolicy, +} from '../../../../../hooks'; import { getCloudFormationPropsFromPackagePolicy } from '../../../../../services'; import { CloudFormationGuide } from '../../../../../components'; @@ -31,7 +37,7 @@ export const PostInstallCloudFormationModal: React.FunctionComponent<{ agentPolicy: AgentPolicy; packagePolicy: PackagePolicy; }> = ({ onConfirm, onCancel, agentPolicy, packagePolicy }) => { - const { data: apyKeysData } = useQuery(['cloudFormationApiKeys'], () => + const { data: apiKeysData, isLoading } = useQuery(['cloudFormationApiKeys'], () => sendGetEnrollmentAPIKeys({ page: 1, perPage: 1, @@ -39,11 +45,16 @@ export const PostInstallCloudFormationModal: React.FunctionComponent<{ }) ); + const { agentPolicyWithPackagePolicies } = useAgentPolicyWithPackagePolicies(agentPolicy.id); + const { fleetServerHosts } = useFleetServerHostsForPolicy(agentPolicyWithPackagePolicies); + const fleetServerHost = fleetServerHosts[0]; + const cloudFormationProps = getCloudFormationPropsFromPackagePolicy(packagePolicy); - const { cloudFormationUrl, error, isError, isLoading } = useCreateCloudFormationUrl({ - enrollmentAPIKey: apyKeysData?.data?.items[0]?.api_key, + const { cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({ + enrollmentAPIKey: apiKeysData?.data?.items[0]?.api_key, cloudFormationProps, + fleetServerHost, }); return ( diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx index 61ed68a059cab..daee7d9d8955c 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx @@ -18,15 +18,18 @@ import type { CloudSecurityIntegration } from './types'; interface Props { enrollmentAPIKey?: string; cloudSecurityIntegration: CloudSecurityIntegration; + fleetServerHost: string; } export const CloudFormationInstructions: React.FunctionComponent = ({ enrollmentAPIKey, cloudSecurityIntegration, + fleetServerHost, }) => { - const { isLoading, cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({ + const { cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({ enrollmentAPIKey, cloudFormationProps: cloudSecurityIntegration?.cloudFormationProps, + fleetServerHost, }); if (error && isError) { @@ -42,7 +45,7 @@ export const CloudFormationInstructions: React.FunctionComponent = ({ { + it('should return the correct link', () => { + expect(getManifestDownloadLink('https://fleet.host', 'enrollmentToken')).toEqual( + '/api/fleet/kubernetes/download?fleetServer=https%3A%2F%2Ffleet.host&enrolToken=enrollmentToken' + ); + expect(getManifestDownloadLink('https://fleet.host')).toEqual( + '/api/fleet/kubernetes/download?fleetServer=https%3A%2F%2Ffleet.host' + ); + expect(getManifestDownloadLink(undefined, 'enrollmentToken')).toEqual( + '/api/fleet/kubernetes/download?enrolToken=enrollmentToken' + ); + }); +}); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/kubernetes_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/kubernetes_instructions.tsx index 8125cdb4acf35..a44b7ab4020e9 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/kubernetes_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/kubernetes_instructions.tsx @@ -31,6 +31,15 @@ interface Props { fleetServerHost?: string; } +export const getManifestDownloadLink = (fleetServerHost?: string, enrollmentAPIKey?: string) => { + const searchParams = new URLSearchParams({ + ...(fleetServerHost && { fleetServer: fleetServerHost }), + ...(enrollmentAPIKey && { enrolToken: enrollmentAPIKey }), + }); + + return `${agentPolicyRouteService.getK8sFullDownloadPath()}?${searchParams.toString()}`; +}; + export const KubernetesInstructions: React.FunctionComponent = ({ enrollmentAPIKey, onCopy, @@ -111,13 +120,8 @@ export const KubernetesInstructions: React.FunctionComponent = ({ ); - const searchParams = new URLSearchParams({ - ...(fleetServerHost && { fleetServer: fleetServerHost }), - ...(enrollmentAPIKey && { enrolToken: enrollmentAPIKey }), - }); - const downloadLink = core.http.basePath.prepend( - `${agentPolicyRouteService.getK8sFullDownloadPath()}${searchParams.toString()}` + getManifestDownloadLink(fleetServerHost, enrollmentAPIKey) ); const k8sDownloadYaml = ( diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx index 7d3e26fe2e954..12a0025efd46d 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx @@ -220,6 +220,8 @@ export const ManagedSteps: React.FunctionComponent = ({ const agentVersion = useAgentVersion(); + const fleetServerHost = fleetServerHosts?.[0]; + const installManagedCommands = ManualInstructions({ apiKey: enrollToken, fleetServerHosts, @@ -260,6 +262,7 @@ export const ManagedSteps: React.FunctionComponent = ({ selectedApiKeyId, enrollToken, cloudSecurityIntegration, + fleetServerHost, }) ); } else if (cloudSecurityIntegration?.cloudShellUrl) { @@ -279,7 +282,7 @@ export const ManagedSteps: React.FunctionComponent = ({ selectedApiKeyId, isK8s, cloudSecurityIntegration, - fleetServerHost: fleetServerHosts?.[0], + fleetServerHost, enrollToken, }) ); @@ -324,7 +327,7 @@ export const ManagedSteps: React.FunctionComponent = ({ enrollToken, installManagedCommands, isK8s, - fleetServerHosts, + fleetServerHost, onClickViewAgents, link, enrolledAgentIds, diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx index 7826d1648ae64..e66f221e7f1c6 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx @@ -23,12 +23,14 @@ export const InstallCloudFormationManagedAgentStep = ({ enrollToken, isComplete, cloudSecurityIntegration, + fleetServerHost, }: { selectedApiKeyId?: string; apiKeyData?: GetOneEnrollmentAPIKeyResponse | null; enrollToken?: string; isComplete?: boolean; cloudSecurityIntegration?: CloudSecurityIntegration | undefined; + fleetServerHost: string; }): EuiContainedStepProps => { const nonCompleteStatus = selectedApiKeyId ? undefined : 'disabled'; const status = isComplete ? 'complete' : nonCompleteStatus; @@ -43,6 +45,7 @@ export const InstallCloudFormationManagedAgentStep = ({ ) : ( diff --git a/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts b/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts index 9e5c2008f262c..718f056b1ef5f 100644 --- a/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts +++ b/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts @@ -13,35 +13,31 @@ import type { } from '../components/agent_enrollment_flyout/types'; import { useAgentVersion } from './use_agent_version'; -import { useGetSettings } from './use_request'; const CLOUD_FORMATION_DEFAULT_ACCOUNT_TYPE = 'single-account'; export const useCreateCloudFormationUrl = ({ enrollmentAPIKey, cloudFormationProps, + fleetServerHost, }: { - enrollmentAPIKey: string | undefined; - cloudFormationProps: CloudFormationProps | undefined; + enrollmentAPIKey?: string; + cloudFormationProps?: CloudFormationProps; + fleetServerHost?: string; }) => { - const { data, isLoading } = useGetSettings(); - const agentVersion = useAgentVersion(); let isError = false; let error: string | undefined; - // Default fleet server host - const fleetServerHost = data?.item.fleet_server_hosts?.[0]; - - if (!fleetServerHost && !isLoading) { + if (!fleetServerHost) { isError = true; error = i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.noFleetServerHost', { defaultMessage: 'No Fleet Server host found', }); } - if (!enrollmentAPIKey && !isLoading) { + if (!enrollmentAPIKey) { isError = true; error = i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.noApiKey', { defaultMessage: 'No enrollment token found', @@ -60,7 +56,6 @@ export const useCreateCloudFormationUrl = ({ : undefined; return { - isLoading, cloudFormationUrl, isError, error, diff --git a/x-pack/plugins/fleet/server/config.test.ts b/x-pack/plugins/fleet/server/config.test.ts new file mode 100644 index 0000000000000..da654244aae30 --- /dev/null +++ b/x-pack/plugins/fleet/server/config.test.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 { config } from './config'; + +describe('Config schema', () => { + it('should not allow to specify both default output in xpack.fleet.ouputs and xpack.fleet.agents.elasticsearch.hosts ', () => { + expect(() => { + config.schema.validate({ + agents: { elasticsearch: { hosts: ['https://elasticsearch:9200'] } }, + outputs: [ + { + id: 'test', + name: 'test output', + type: 'elasticsearch', + hosts: ['http://elasticsearch:9200'], + is_default: true, + is_default_monitoring: true, + }, + ], + }); + }).toThrowErrorMatchingInlineSnapshot( + `"xpack.fleet.agents.elasticsearch.hosts should not be used when defining default outputs in xpack.fleet.outputs, please remove it."` + ); + }); + + it('should allow to specify both outputs in xpack.fleet.ouputs without default outputs and xpack.fleet.agents.elasticsearch.hosts ', () => { + expect(() => { + config.schema.validate({ + agents: { elasticsearch: { hosts: ['https://elasticsearch:9200'] } }, + outputs: [ + { + id: 'test', + name: 'test output', + type: 'elasticsearch', + hosts: ['http://elasticsearch:9200'], + is_default: false, + is_default_monitoring: false, + }, + ], + }); + }).not.toThrow(); + }); + + it('should allow to specify default outputs only xpack.fleet.ouputs ', () => { + expect(() => { + config.schema.validate({ + outputs: [ + { + id: 'test', + name: 'test output', + type: 'elasticsearch', + hosts: ['http://elasticsearch:9200'], + is_default: true, + is_default_monitoring: true, + }, + ], + }); + }).not.toThrow(); + }); + + it('should allow to specify default output only in xpack.fleet.agents.elasticsearch.hosts ', () => { + expect(() => { + config.schema.validate({ + agents: { elasticsearch: { hosts: ['https://elasticsearch:9200'] } }, + }); + }).not.toThrow(); + }); +}); diff --git a/x-pack/plugins/fleet/server/config.ts b/x-pack/plugins/fleet/server/config.ts index 49e80690a261c..cbf38a2024733 100644 --- a/x-pack/plugins/fleet/server/config.ts +++ b/x-pack/plugins/fleet/server/config.ts @@ -111,142 +111,157 @@ export const config: PluginConfigDescriptor = { return fullConfig; }, ], - schema: schema.object({ - registryUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), - registryProxyUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), - agents: schema.object({ - enabled: schema.boolean({ defaultValue: true }), - elasticsearch: schema.object({ - hosts: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }))), - ca_sha256: schema.maybe(schema.string()), + schema: schema.object( + { + registryUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), + registryProxyUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), + agents: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + elasticsearch: schema.object({ + hosts: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }))), + ca_sha256: schema.maybe(schema.string()), + }), + fleet_server: schema.maybe( + schema.object({ + hosts: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }))), + }) + ), }), - fleet_server: schema.maybe( + packages: PreconfiguredPackagesSchema, + agentPolicies: PreconfiguredAgentPoliciesSchema, + outputs: PreconfiguredOutputsSchema, + fleetServerHosts: PreconfiguredFleetServerHostsSchema, + proxies: PreconfiguredFleetProxiesSchema, + agentIdVerificationEnabled: schema.boolean({ defaultValue: true }), + setup: schema.maybe( schema.object({ - hosts: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }))), + agentPolicySchemaUpgradeBatchSize: schema.maybe(schema.number()), }) ), - }), - packages: PreconfiguredPackagesSchema, - agentPolicies: PreconfiguredAgentPoliciesSchema, - outputs: PreconfiguredOutputsSchema, - fleetServerHosts: PreconfiguredFleetServerHostsSchema, - proxies: PreconfiguredFleetProxiesSchema, - agentIdVerificationEnabled: schema.boolean({ defaultValue: true }), - setup: schema.maybe( - schema.object({ - agentPolicySchemaUpgradeBatchSize: schema.maybe(schema.number()), - }) - ), - developer: schema.object({ - maxAgentPoliciesWithInactivityTimeout: schema.maybe(schema.number()), - disableRegistryVersionCheck: schema.boolean({ defaultValue: false }), - allowAgentUpgradeSourceUri: schema.boolean({ defaultValue: false }), - bundledPackageLocation: schema.string({ defaultValue: DEFAULT_BUNDLED_PACKAGE_LOCATION }), - }), - packageVerification: schema.object({ - gpgKeyPath: schema.string({ defaultValue: DEFAULT_GPG_KEY_PATH }), - }), - /** - * For internal use. A list of string values (comma delimited) that will enable experimental - * type of functionality that is not yet released. - * - * @example - * xpack.fleet.enableExperimental: - * - feature1 - * - feature2 - */ - enableExperimental: schema.arrayOf(schema.string(), { - defaultValue: () => [], - validate(list) { - for (const key of list) { - if (!isValidExperimentalValue(key)) { - return `[${key}] is not allowed. Allowed values are: ${allowedExperimentalValues.join( - ', ' - )}`; + developer: schema.object({ + maxAgentPoliciesWithInactivityTimeout: schema.maybe(schema.number()), + disableRegistryVersionCheck: schema.boolean({ defaultValue: false }), + allowAgentUpgradeSourceUri: schema.boolean({ defaultValue: false }), + bundledPackageLocation: schema.string({ defaultValue: DEFAULT_BUNDLED_PACKAGE_LOCATION }), + }), + packageVerification: schema.object({ + gpgKeyPath: schema.string({ defaultValue: DEFAULT_GPG_KEY_PATH }), + }), + /** + * For internal use. A list of string values (comma delimited) that will enable experimental + * type of functionality that is not yet released. + * + * @example + * xpack.fleet.enableExperimental: + * - feature1 + * - feature2 + */ + enableExperimental: schema.arrayOf(schema.string(), { + defaultValue: () => [], + validate(list) { + for (const key of list) { + if (!isValidExperimentalValue(key)) { + return `[${key}] is not allowed. Allowed values are: ${allowedExperimentalValues.join( + ', ' + )}`; + } } - } - }, - }), + }, + }), - internal: schema.maybe( - schema.object({ - disableILMPolicies: schema.boolean({ - defaultValue: false, - }), - disableProxies: schema.boolean({ - defaultValue: false, - }), - fleetServerStandalone: schema.boolean({ - defaultValue: false, - }), - onlyAllowAgentUpgradeToKnownVersions: schema.boolean({ - defaultValue: false, - }), - activeAgentsSoftLimit: schema.maybe( - schema.number({ - min: 0, - }) - ), - registry: schema.object( - { - kibanaVersionCheckEnabled: schema.boolean({ defaultValue: true }), - spec: schema.object( - { - min: schema.maybe(schema.string()), - max: schema.string({ defaultValue: REGISTRY_SPEC_MAX_VERSION }), - }, - { - defaultValue: { + internal: schema.maybe( + schema.object({ + disableILMPolicies: schema.boolean({ + defaultValue: false, + }), + disableProxies: schema.boolean({ + defaultValue: false, + }), + fleetServerStandalone: schema.boolean({ + defaultValue: false, + }), + onlyAllowAgentUpgradeToKnownVersions: schema.boolean({ + defaultValue: false, + }), + activeAgentsSoftLimit: schema.maybe( + schema.number({ + min: 0, + }) + ), + registry: schema.object( + { + kibanaVersionCheckEnabled: schema.boolean({ defaultValue: true }), + spec: schema.object( + { + min: schema.maybe(schema.string()), + max: schema.string({ defaultValue: REGISTRY_SPEC_MAX_VERSION }), + }, + { + defaultValue: { + max: REGISTRY_SPEC_MAX_VERSION, + }, + } + ), + capabilities: schema.arrayOf( + schema.oneOf([ + // See package-spec for the list of available capiblities https://github.com/elastic/package-spec/blob/dcc37b652690f8a2bca9cf8a12fc28fd015730a0/spec/integration/manifest.spec.yml#L113 + schema.literal('apm'), + schema.literal('enterprise_search'), + schema.literal('observability'), + schema.literal('security'), + schema.literal('serverless_search'), + schema.literal('uptime'), + ]), + { defaultValue: [] } + ), + }, + { + defaultValue: { + kibanaVersionCheckEnabled: true, + capabilities: [], + spec: { max: REGISTRY_SPEC_MAX_VERSION, }, - } - ), - capabilities: schema.arrayOf( - schema.oneOf([ - // See package-spec for the list of available capiblities https://github.com/elastic/package-spec/blob/dcc37b652690f8a2bca9cf8a12fc28fd015730a0/spec/integration/manifest.spec.yml#L113 - schema.literal('apm'), - schema.literal('enterprise_search'), - schema.literal('observability'), - schema.literal('security'), - schema.literal('serverless_search'), - schema.literal('uptime'), - ]), - { defaultValue: [] } - ), - }, - { - defaultValue: { - kibanaVersionCheckEnabled: true, - capabilities: [], - spec: { - max: REGISTRY_SPEC_MAX_VERSION, }, - }, - } - ), - }) - ), - enabled: schema.boolean({ defaultValue: true }), - /** - * The max size of the artifacts encoded_size sum in a batch when more than one (there is at least one artifact in a batch). - * @example - * artifact1.encoded_size = 400 - * artifact2.encoded_size = 600 - * artifact3.encoded_size = 1_200 - * and - * createArtifactsBulkBatchSize: 1_000 - * then - * batch1 = [artifact1, artifact2] - * batch2 = [artifact3] - */ - createArtifactsBulkBatchSize: schema.maybe( - schema.number({ - defaultValue: BULK_CREATE_MAX_ARTIFACTS_BYTES, - max: 4_000_000, - min: 400, - }) - ), - }), + } + ), + }) + ), + enabled: schema.boolean({ defaultValue: true }), + /** + * The max size of the artifacts encoded_size sum in a batch when more than one (there is at least one artifact in a batch). + * @example + * artifact1.encoded_size = 400 + * artifact2.encoded_size = 600 + * artifact3.encoded_size = 1_200 + * and + * createArtifactsBulkBatchSize: 1_000 + * then + * batch1 = [artifact1, artifact2] + * batch2 = [artifact3] + */ + createArtifactsBulkBatchSize: schema.maybe( + schema.number({ + defaultValue: BULK_CREATE_MAX_ARTIFACTS_BYTES, + max: 4_000_000, + min: 400, + }) + ), + }, + { + validate: (configToValidate) => { + const hasDefaultPreconfiguredOuputs = configToValidate.outputs.some( + (o) => o.is_default || o.is_default_monitoring + ); + const hasDefaulElasticsearchOutputDefined = + configToValidate.agents?.elasticsearch?.hosts?.length ?? 0 > 0; + + if (hasDefaulElasticsearchOutputDefined && hasDefaultPreconfiguredOuputs) { + return 'xpack.fleet.agents.elasticsearch.hosts should not be used when defining default outputs in xpack.fleet.outputs, please remove it.'; + } + }, + } + ), }; export type FleetConfigType = TypeOf; diff --git a/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts b/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts index c6eaba98135f3..139f07fb999b3 100644 --- a/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/cloud_preconfiguration.test.ts @@ -312,31 +312,11 @@ describe('Fleet preconfiguration reset', () => { cluster: ['cluster:monitor/main'], indices: [ { - names: ['logs-apm.app-default'], + names: ['traces-*', 'logs-*', 'metrics-*'], privileges: ['auto_configure', 'create_doc'], }, { - names: ['metrics-apm.app.*-default'], - privileges: ['auto_configure', 'create_doc'], - }, - { - names: ['logs-apm.error-default'], - privileges: ['auto_configure', 'create_doc'], - }, - { - names: ['metrics-apm.internal-default'], - privileges: ['auto_configure', 'create_doc'], - }, - { - names: ['metrics-apm.profiling-default'], - privileges: ['auto_configure', 'create_doc'], - }, - { - names: ['traces-apm.rum-default'], - privileges: ['auto_configure', 'create_doc'], - }, - { - names: ['traces-apm.sampled-default'], + names: ['traces-apm.sampled-*'], privileges: [ 'auto_configure', 'create_doc', @@ -345,10 +325,6 @@ describe('Fleet preconfiguration reset', () => { 'read', ], }, - { - names: ['traces-apm-default'], - privileges: ['auto_configure', 'create_doc'], - }, ], }, }, diff --git a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts index 8bd45d80d9429..e4f2b30bc4a9e 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.test.ts @@ -239,26 +239,66 @@ packageInfoCache.set('profiler_collector-8.9.0-preview', { }, }); +packageInfoCache.set('apm-8.9.0-preview', { + format_version: '2.7.0', + name: 'apm', + title: 'APM', + version: '8.9.0-preview', + license: 'basic', + description: 'APM Server integration', + type: 'integration', + release: 'beta', + categories: ['observability'], + icons: [], + owner: { github: 'elastic/apm-server' }, + data_streams: [], + latestVersion: '8.9.0-preview', + status: 'not_installed', + assets: { + kibana: { + csp_rule_template: [], + dashboard: [], + visualization: [], + search: [], + index_pattern: [], + map: [], + lens: [], + security_rule: [], + ml_module: [], + tag: [], + osquery_pack_asset: [], + osquery_saved_query: [], + }, + elasticsearch: { + component_template: [], + ingest_pipeline: [], + ilm_policy: [], + transform: [], + index_template: [], + data_stream_ilm_policy: [], + ml_model: [], + }, + }, +}); + describe('storedPackagePoliciesToAgentPermissions()', () => { it('Returns `undefined` if there are no package policies', async () => { const permissions = await storedPackagePoliciesToAgentPermissions(packageInfoCache, []); expect(permissions).toBeUndefined(); }); - it('Throw an error if package policies is not an array', async () => { - await expect(() => - storedPackagePoliciesToAgentPermissions(packageInfoCache, undefined) - ).rejects.toThrow( + it('Throw an error if package policies is not an array', () => { + expect(() => storedPackagePoliciesToAgentPermissions(packageInfoCache, undefined)).toThrow( /storedPackagePoliciesToAgentPermissions should be called with a PackagePolicy/ ); }); - it('Returns the default permissions if a package policy does not have a package', async () => { - await expect(() => + it('Returns the default permissions if a package policy does not have a package', () => { + expect(() => storedPackagePoliciesToAgentPermissions(packageInfoCache, [ { name: 'foo', package: undefined } as PackagePolicy, ]) - ).rejects.toThrow(/No package for package policy foo/); + ).toThrow(/No package for package policy foo/); }); it('Returns the permissions for the enabled inputs', async () => { @@ -545,6 +585,52 @@ describe('storedPackagePoliciesToAgentPermissions()', () => { }, }); }); + + it('returns the correct permissions for the APM package', async () => { + const packagePolicies: PackagePolicy[] = [ + { + id: 'package-policy-uuid-test-123', + name: 'test-policy', + namespace: '', + enabled: true, + package: { name: 'apm', version: '8.9.0-preview', title: 'Test Package' }, + inputs: [ + { + type: 'pf-elastic-collector', + enabled: true, + streams: [], + }, + ], + created_at: '', + updated_at: '', + created_by: '', + updated_by: '', + revision: 1, + policy_id: '', + }, + ]; + + const permissions = await storedPackagePoliciesToAgentPermissions( + packageInfoCache, + packagePolicies + ); + + expect(permissions).toMatchObject({ + 'package-policy-uuid-test-123': { + cluster: ['cluster:monitor/main'], + indices: [ + { + names: ['traces-*', 'logs-*', 'metrics-*'], + privileges: ['auto_configure', 'create_doc'], + }, + { + names: ['traces-apm.sampled-*'], + privileges: ['auto_configure', 'create_doc', 'maintenance', 'monitor', 'read'], + }, + ], + }, + }); + }); }); describe('getDataStreamPrivileges()', () => { diff --git a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts index eeb81ca9c1724..4445ebbe84769 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/package_policies_to_agent_permissions.ts @@ -5,7 +5,13 @@ * 2.0. */ +import type { + SecurityIndicesPrivileges, + SecurityRoleDescriptor, +} from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; + import { + FLEET_APM_PACKAGE, FLEET_UNIVERSAL_PROFILING_COLLECTOR_PACKAGE, FLEET_UNIVERSAL_PROFILING_SYMBOLIZER_PACKAGE, } from '../../../common/constants'; @@ -34,10 +40,10 @@ export const UNIVERSAL_PROFILING_PERMISSIONS = [ 'view_index_metadata', ]; -export async function storedPackagePoliciesToAgentPermissions( +export function storedPackagePoliciesToAgentPermissions( packageInfoCache: Map, packagePolicies?: PackagePolicy[] -): Promise { +): FullAgentPolicyOutputPermissions | undefined { // I'm not sure what permissions to return for this case, so let's return the defaults if (!packagePolicies) { throw new Error( @@ -49,114 +55,116 @@ export async function storedPackagePoliciesToAgentPermissions( return; } - const permissionEntries = (packagePolicies as PackagePolicy[]).map>( - async (packagePolicy) => { - if (!packagePolicy.package) { - throw new Error(`No package for package policy ${packagePolicy.name ?? packagePolicy.id}`); - } - - const pkg = packageInfoCache.get(pkgToPkgKey(packagePolicy.package))!; - - // Special handling for Universal Profiling packages, as it does not use data streams _only_, - // but also indices that do not adhere to the convention. - if ( - pkg.name === FLEET_UNIVERSAL_PROFILING_SYMBOLIZER_PACKAGE || - pkg.name === FLEET_UNIVERSAL_PROFILING_COLLECTOR_PACKAGE - ) { - return Promise.resolve(universalProfilingPermissions(packagePolicy.id)); - } - - const dataStreams = getNormalizedDataStreams(pkg); - if (!dataStreams || dataStreams.length === 0) { - return [packagePolicy.name, undefined]; - } - - let dataStreamsForPermissions: DataStreamMeta[]; - - switch (pkg.name) { - case 'endpoint': - // - Endpoint doesn't store the `data_stream` metadata in - // `packagePolicy.inputs`, so we will use _all_ data_streams from the - // package. - dataStreamsForPermissions = dataStreams; - break; - - case 'apm': - // - APM doesn't store the `data_stream` metadata in - // `packagePolicy.inputs`, so we will use _all_ data_streams from - // the package. - dataStreamsForPermissions = dataStreams; - break; - - case 'osquery_manager': - // - Osquery manager doesn't store the `data_stream` metadata in - // `packagePolicy.inputs`, so we will use _all_ data_streams from - // the package. - dataStreamsForPermissions = dataStreams; - break; - - default: - // - Normal packages store some of the `data_stream` metadata in - // `packagePolicy.inputs[].streams[].data_stream` - // - The rest of the metadata needs to be fetched from the - // `data_stream` object in the package. The link is - // `packagePolicy.inputs[].type == dataStreams.streams[].input` - // - Some packages (custom logs) have a compiled dataset, stored in - // `input.streams.compiled_stream.data_stream.dataset` - dataStreamsForPermissions = packagePolicy.inputs - .filter((i) => i.enabled) - .flatMap((input) => { - if (!input.streams) { - return []; - } - - const dataStreams_: DataStreamMeta[] = []; - - input.streams - .filter((s) => s.enabled) - .forEach((stream) => { - if (!('data_stream' in stream)) { - return; - } - - const ds: DataStreamMeta = { - type: stream.data_stream.type, - dataset: - stream.compiled_stream?.data_stream?.dataset ?? stream.data_stream.dataset, - }; - - if (stream.data_stream.elasticsearch) { - ds.elasticsearch = stream.data_stream.elasticsearch; - } - - dataStreams_.push(ds); - }); - - return dataStreams_; - }); - } - - let clusterRoleDescriptor = {}; - const cluster = packagePolicy?.elasticsearch?.privileges?.cluster ?? []; - if (cluster.length > 0) { - clusterRoleDescriptor = { - cluster, - }; - } - - return [ - packagePolicy.id, - { - indices: dataStreamsForPermissions.map((ds) => - getDataStreamPrivileges(ds, packagePolicy.namespace) - ), - ...clusterRoleDescriptor, - }, - ]; + const permissionEntries = packagePolicies.map((packagePolicy) => { + if (!packagePolicy.package) { + throw new Error(`No package for package policy ${packagePolicy.name ?? packagePolicy.id}`); + } + + const pkg = packageInfoCache.get(pkgToPkgKey(packagePolicy.package))!; + + // Special handling for Universal Profiling packages, as it does not use data streams _only_, + // but also indices that do not adhere to the convention. + if ( + pkg.name === FLEET_UNIVERSAL_PROFILING_SYMBOLIZER_PACKAGE || + pkg.name === FLEET_UNIVERSAL_PROFILING_COLLECTOR_PACKAGE + ) { + return universalProfilingPermissions(packagePolicy.id); + } + + if (pkg.name === FLEET_APM_PACKAGE) { + return apmPermissions(packagePolicy.id); + } + + const dataStreams = getNormalizedDataStreams(pkg); + if (!dataStreams || dataStreams.length === 0) { + return [packagePolicy.name, undefined]; + } + + let dataStreamsForPermissions: DataStreamMeta[]; + + switch (pkg.name) { + case 'endpoint': + // - Endpoint doesn't store the `data_stream` metadata in + // `packagePolicy.inputs`, so we will use _all_ data_streams from the + // package. + dataStreamsForPermissions = dataStreams; + break; + + case 'apm': + // - APM doesn't store the `data_stream` metadata in + // `packagePolicy.inputs`, so we will use _all_ data_streams from + // the package. + dataStreamsForPermissions = dataStreams; + break; + + case 'osquery_manager': + // - Osquery manager doesn't store the `data_stream` metadata in + // `packagePolicy.inputs`, so we will use _all_ data_streams from + // the package. + dataStreamsForPermissions = dataStreams; + break; + + default: + // - Normal packages store some of the `data_stream` metadata in + // `packagePolicy.inputs[].streams[].data_stream` + // - The rest of the metadata needs to be fetched from the + // `data_stream` object in the package. The link is + // `packagePolicy.inputs[].type == dataStreams.streams[].input` + // - Some packages (custom logs) have a compiled dataset, stored in + // `input.streams.compiled_stream.data_stream.dataset` + dataStreamsForPermissions = packagePolicy.inputs + .filter((i) => i.enabled) + .flatMap((input) => { + if (!input.streams) { + return []; + } + + const dataStreams_: DataStreamMeta[] = []; + + input.streams + .filter((s) => s.enabled) + .forEach((stream) => { + if (!('data_stream' in stream)) { + return; + } + + const ds: DataStreamMeta = { + type: stream.data_stream.type, + dataset: + stream.compiled_stream?.data_stream?.dataset ?? stream.data_stream.dataset, + }; + + if (stream.data_stream.elasticsearch) { + ds.elasticsearch = stream.data_stream.elasticsearch; + } + + dataStreams_.push(ds); + }); + + return dataStreams_; + }); + } + + let clusterRoleDescriptor = {}; + const cluster = packagePolicy?.elasticsearch?.privileges?.cluster ?? []; + if (cluster.length > 0) { + clusterRoleDescriptor = { + cluster, + }; } - ); - return Object.fromEntries(await Promise.all(permissionEntries)); + return [ + packagePolicy.id, + { + indices: dataStreamsForPermissions.map((ds) => + getDataStreamPrivileges(ds, packagePolicy.namespace) + ), + ...clusterRoleDescriptor, + }, + ]; + }); + + return Object.fromEntries(permissionEntries); } export interface DataStreamMeta { @@ -171,7 +179,10 @@ export interface DataStreamMeta { }; } -export function getDataStreamPrivileges(dataStream: DataStreamMeta, namespace: string = '*') { +export function getDataStreamPrivileges( + dataStream: DataStreamMeta, + namespace: string = '*' +): SecurityIndicesPrivileges { let index = dataStream.hidden ? `.${dataStream.type}-` : `${dataStream.type}-`; // Determine dataset @@ -200,7 +211,7 @@ export function getDataStreamPrivileges(dataStream: DataStreamMeta, namespace: s }; } -async function universalProfilingPermissions(packagePolicyId: string): Promise<[string, any]> { +function universalProfilingPermissions(packagePolicyId: string): [string, SecurityRoleDescriptor] { const profilingIndexPattern = 'profiling-*'; return [ packagePolicyId, @@ -214,3 +225,22 @@ async function universalProfilingPermissions(packagePolicyId: string): Promise<[ }, ]; } + +function apmPermissions(packagePolicyId: string): [string, SecurityRoleDescriptor] { + return [ + packagePolicyId, + { + cluster: ['cluster:monitor/main'], + indices: [ + { + names: ['traces-*', 'logs-*', 'metrics-*'], + privileges: ['auto_configure', 'create_doc'], + }, + { + names: ['traces-apm.sampled-*'], + privileges: ['auto_configure', 'create_doc', 'maintenance', 'monitor', 'read'], + }, + ], + }, + ]; +} diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts index 3e9363fa9828f..5682749d7e381 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts @@ -11,6 +11,8 @@ import type { MappingTypeMapping, } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import pMap from 'p-map'; + import type { Field, Fields } from '../../fields/field'; import type { RegistryDataStream, @@ -729,15 +731,22 @@ const updateAllDataStreams = async ( esClient: ElasticsearchClient, logger: Logger ): Promise => { - const updatedataStreamPromises = indexNameWithTemplates.map((templateEntry) => { - return updateExistingDataStream({ - esClient, - logger, - dataStreamName: templateEntry.dataStreamName, - }); - }); - await Promise.all(updatedataStreamPromises); + await pMap( + indexNameWithTemplates, + (templateEntry) => { + return updateExistingDataStream({ + esClient, + logger, + dataStreamName: templateEntry.dataStreamName, + }); + }, + { + // Limit concurrent putMapping/rollover requests to avoid overhwhelming ES cluster + concurrency: 20, + } + ); }; + const updateExistingDataStream = async ({ dataStreamName, esClient, diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts index 3c308b8e85b0a..b7fe0d95310ef 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.test.ts @@ -5,11 +5,21 @@ * 2.0. */ -import type { SavedObjectsClientContract, ElasticsearchClient } from '@kbn/core/server'; +import type { + SavedObjectsClientContract, + ElasticsearchClient, + SavedObject, +} from '@kbn/core/server'; import { savedObjectsClientMock, elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { loggerMock } from '@kbn/logging-mocks'; import { DEFAULT_SPACE_ID } from '@kbn/spaces-plugin/common/constants'; +import { ConcurrentInstallOperationError } from '../../../errors'; + +import type { Installation } from '../../../../common'; + +import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../common'; + import { appContextService } from '../../app_context'; import { createAppContextStartContractMock } from '../../../mocks'; import { saveArchiveEntries } from '../archive/storage'; @@ -29,7 +39,9 @@ jest.mock('../elasticsearch/datastream_ilm/install'); import { updateCurrentWriteIndices } from '../elasticsearch/template/template'; import { installKibanaAssetsAndReferences } from '../kibana/assets/install'; -import { installIndexTemplatesAndPipelines } from './install'; +import { MAX_TIME_COMPLETE_INSTALL } from '../../../../common/constants'; + +import { installIndexTemplatesAndPipelines, restartInstallation } from './install'; import { _installPackage } from './_install_package'; @@ -69,9 +81,7 @@ describe('_installPackage', () => { jest.mocked(saveArchiveEntries).mockResolvedValue({ saved_objects: [], }); - }); - afterEach(async () => { - appContextService.stop(); + jest.mocked(restartInstallation).mockReset(); }); it('handles errors from installKibanaAssets', async () => { // force errors from this function @@ -226,4 +236,128 @@ describe('_installPackage', () => { expect(installILMPolicy).toBeCalled(); expect(installIlmForDataStream).toBeCalled(); }); + + describe('when package is stuck in `installing`', () => { + afterEach(() => {}); + const mockInstalledPackageSo: SavedObject = { + id: 'mocked-package', + attributes: { + name: 'test-package', + version: '1.0.0', + install_status: 'installing', + install_version: '1.0.0', + install_started_at: new Date().toISOString(), + install_source: 'registry', + verification_status: 'verified', + installed_kibana: [] as any, + installed_es: [] as any, + es_index_patterns: {}, + }, + type: PACKAGES_SAVED_OBJECT_TYPE, + references: [], + }; + + beforeEach(() => { + appContextService.start( + createAppContextStartContractMock({ + internal: { + disableILMPolicies: true, + disableProxies: false, + fleetServerStandalone: false, + onlyAllowAgentUpgradeToKnownVersions: false, + registry: { + kibanaVersionCheckEnabled: true, + capabilities: [], + }, + }, + }) + ); + }); + + describe('timeout reached', () => { + it('restarts installation', async () => { + await _installPackage({ + savedObjectsClient: soClient, + // @ts-ignore + savedObjectsImporter: jest.fn(), + esClient, + logger: loggerMock.create(), + paths: [], + packageInfo: { + name: mockInstalledPackageSo.attributes.name, + version: mockInstalledPackageSo.attributes.version, + title: mockInstalledPackageSo.attributes.name, + } as any, + installedPkg: { + ...mockInstalledPackageSo, + attributes: { + ...mockInstalledPackageSo.attributes, + install_started_at: new Date( + Date.now() - MAX_TIME_COMPLETE_INSTALL * 2 + ).toISOString(), + }, + }, + }); + + expect(restartInstallation).toBeCalled(); + }); + }); + + describe('timeout not reached', () => { + describe('force flag not provided', () => { + it('throws concurrent installation error if force flag is not provided', async () => { + expect( + _installPackage({ + savedObjectsClient: soClient, + // @ts-ignore + savedObjectsImporter: jest.fn(), + esClient, + logger: loggerMock.create(), + paths: [], + packageInfo: { + name: mockInstalledPackageSo.attributes.name, + version: mockInstalledPackageSo.attributes.version, + title: mockInstalledPackageSo.attributes.name, + } as any, + installedPkg: { + ...mockInstalledPackageSo, + attributes: { + ...mockInstalledPackageSo.attributes, + install_started_at: new Date(Date.now() - 1000).toISOString(), + }, + }, + }) + ).rejects.toThrowError(ConcurrentInstallOperationError); + }); + }); + + describe('force flag provided', () => { + it('restarts installation', async () => { + await _installPackage({ + savedObjectsClient: soClient, + // @ts-ignore + savedObjectsImporter: jest.fn(), + esClient, + logger: loggerMock.create(), + paths: [], + packageInfo: { + name: mockInstalledPackageSo.attributes.name, + version: mockInstalledPackageSo.attributes.version, + title: mockInstalledPackageSo.attributes.name, + } as any, + installedPkg: { + ...mockInstalledPackageSo, + attributes: { + ...mockInstalledPackageSo.attributes, + install_started_at: new Date(Date.now() - 1000).toISOString(), + }, + }, + force: true, + }); + + expect(restartInstallation).toBeCalled(); + }); + }); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts index 337cf59bbd613..3bfc74bf68968 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts @@ -99,18 +99,30 @@ export async function _installPackage({ try { // if some installation already exists if (installedPkg) { + const isStatusInstalling = installedPkg.attributes.install_status === 'installing'; + const hasExceededTimeout = + Date.now() - Date.parse(installedPkg.attributes.install_started_at) < + MAX_TIME_COMPLETE_INSTALL; + // if the installation is currently running, don't try to install // instead, only return already installed assets - if ( - installedPkg.attributes.install_status === 'installing' && - Date.now() - Date.parse(installedPkg.attributes.install_started_at) < - MAX_TIME_COMPLETE_INSTALL - ) { - throw new ConcurrentInstallOperationError( - `Concurrent installation or upgrade of ${pkgName || 'unknown'}-${ - pkgVersion || 'unknown' - } detected, aborting.` - ); + if (isStatusInstalling && hasExceededTimeout) { + // If this is a forced installation, ignore the timeout and restart the installation anyway + if (force) { + await restartInstallation({ + savedObjectsClient, + pkgName, + pkgVersion, + installSource, + verificationResult, + }); + } else { + throw new ConcurrentInstallOperationError( + `Concurrent installation or upgrade of ${pkgName || 'unknown'}-${ + pkgVersion || 'unknown' + } detected, aborting.` + ); + } } else { // if no installation is running, or the installation has been running longer than MAX_TIME_COMPLETE_INSTALL // (it might be stuck) update the saved object and proceed diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts index 1decd82c4ed19..80156ae1442aa 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts @@ -6,8 +6,8 @@ */ import React from 'react'; import './helpers.scss'; -import type { IEmbeddable } from '@kbn/embeddable-plugin/public'; -import type { OverlayRef, OverlayStart, ThemeServiceStart } from '@kbn/core/public'; +import { IEmbeddable, tracksOverlays } from '@kbn/embeddable-plugin/public'; +import type { OverlayStart, ThemeServiceStart } from '@kbn/core/public'; import { toMountPoint } from '@kbn/kibana-react-plugin/public'; import { IncompatibleActionError } from '@kbn/ui-actions-plugin/public'; import { isLensEmbeddable } from '../utils'; @@ -20,15 +20,6 @@ interface Context { theme: ThemeServiceStart; } -interface TracksOverlays { - openOverlay: (ref: OverlayRef) => void; - clearOverlays: () => void; -} - -function tracksOverlays(root: unknown): root is TracksOverlays { - return Boolean((root as TracksOverlays).openOverlay && (root as TracksOverlays).clearOverlays); -} - export async function isActionCompatible(embeddable: IEmbeddable) { return Boolean(isLensEmbeddable(embeddable) && embeddable.isTextBasedLanguage()); } @@ -67,6 +58,6 @@ export async function executeAction({ embeddable, startDependencies, overlays, t outsideClickCloses: true, } ); - overlayTracker?.openOverlay(handle); + overlayTracker?.openOverlay(handle, { focusedPanelId: embeddable.id }); } } diff --git a/x-pack/plugins/metrics_data_access/server/client/client.test.ts b/x-pack/plugins/metrics_data_access/server/client/client.test.ts index 72449cf47132b..d96d8efecf52f 100644 --- a/x-pack/plugins/metrics_data_access/server/client/client.test.ts +++ b/x-pack/plugins/metrics_data_access/server/client/client.test.ts @@ -7,18 +7,13 @@ import { SavedObjectsErrorHelpers } from '@kbn/core/server'; import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; -import { MetricsDataClient } from './client'; +import { MetricsDataClient, DEFAULT_METRIC_INDICES } from './client'; import { metricsDataSourceSavedObjectName } from '../saved_objects/metrics_data_source'; describe('MetricsDataClient', () => { - const client = new MetricsDataClient(); - - client.setDefaultMetricIndicesHandler(async () => { - return 'fallback-indices*'; - }); - describe('metric indices', () => { it('retrieves metrics saved object', async () => { + const client = new MetricsDataClient(); const savedObjectsClient = { get: jest.fn().mockResolvedValue({ attributes: { metricIndices: 'foo,bar' } }), }; @@ -36,6 +31,10 @@ describe('MetricsDataClient', () => { }); it('falls back to provided handler when no metrics saved object exists', async () => { + const client = new MetricsDataClient(); + client.setDefaultMetricIndicesHandler(async () => { + return 'fallback-indices*'; + }); const savedObjectsClient = { get: jest.fn().mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError()), }; @@ -51,5 +50,17 @@ describe('MetricsDataClient', () => { ]); expect(indices).toEqual('fallback-indices*'); }); + + it('falls back to static indices when no fallback exists', async () => { + const client = new MetricsDataClient(); + const savedObjectsClient = { + get: jest.fn().mockRejectedValue(SavedObjectsErrorHelpers.createGenericNotFoundError()), + }; + + const indices = await client.getMetricIndices({ + savedObjectsClient: savedObjectsClient as unknown as SavedObjectsClientContract, + }); + expect(indices).toEqual(DEFAULT_METRIC_INDICES); + }); }); }); diff --git a/x-pack/plugins/metrics_data_access/server/client/client.ts b/x-pack/plugins/metrics_data_access/server/client/client.ts index 30d367cea0293..26359cae578a7 100644 --- a/x-pack/plugins/metrics_data_access/server/client/client.ts +++ b/x-pack/plugins/metrics_data_access/server/client/client.ts @@ -16,21 +16,19 @@ import { metricsDataSourceSavedObjectName, } from '../saved_objects/metrics_data_source'; +export const DEFAULT_METRIC_INDICES = 'metrics-*,metricbeat-*'; + export class MetricsDataClient { private readonly defaultSavedObjectId = 'default'; private getDefaultMetricIndices: DefaultMetricIndicesHandler = null; async getMetricIndices(options: GetMetricIndicesOptions): Promise { - if (!this.getDefaultMetricIndices) { - throw new Error('Missing getMetricsIndices fallback'); - } - const metricIndices = await options.savedObjectsClient .get(metricsDataSourceSavedObjectName, this.defaultSavedObjectId) .then(({ attributes }) => attributes.metricIndices) .catch((err) => { if (SavedObjectsErrorHelpers.isNotFoundError(err)) { - return this.getDefaultMetricIndices!(options); + return this.getDefaultMetricIndices?.(options) ?? DEFAULT_METRIC_INDICES; } throw err; diff --git a/x-pack/plugins/ml/public/application/components/ml_inference/components/add_inference_pipeline_horizontal_steps.tsx b/x-pack/plugins/ml/public/application/components/ml_inference/components/add_inference_pipeline_horizontal_steps.tsx index 9954ed8955259..2a34f6483c24d 100644 --- a/x-pack/plugins/ml/public/application/components/ml_inference/components/add_inference_pipeline_horizontal_steps.tsx +++ b/x-pack/plugins/ml/public/application/components/ml_inference/components/add_inference_pipeline_horizontal_steps.tsx @@ -113,6 +113,6 @@ export const AddInferencePipelineHorizontalSteps: FC = memo( navSteps[4].status = 'current'; break; } - return ; + return ; } ); diff --git a/x-pack/plugins/ml/public/application/services/elastic_models_service.ts b/x-pack/plugins/ml/public/application/services/elastic_models_service.ts new file mode 100644 index 0000000000000..2591fb6d82e7d --- /dev/null +++ b/x-pack/plugins/ml/public/application/services/elastic_models_service.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 { ModelDefinitionResponse, GetElserOptions } from '@kbn/ml-trained-models-utils'; +import { type TrainedModelsApiService } from './ml_api_service/trained_models'; + +export class ElasticModels { + constructor(private readonly trainedModels: TrainedModelsApiService) {} + + /** + * Provides an ELSER model name and configuration for download based on the current cluster architecture. + * The current default version is 2. If running on Cloud it returns the Linux x86_64 optimized version. + * If any of the ML nodes run a different OS rather than Linux, or the CPU architecture isn't x86_64, + * a portable version of the model is returned. + */ + public async getELSER(options?: GetElserOptions): Promise { + return await this.trainedModels.getElserConfig(options); + } +} diff --git a/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts b/x-pack/plugins/ml/public/application/services/get_shared_ml_services.ts new file mode 100644 index 0000000000000..23ac82737044f --- /dev/null +++ b/x-pack/plugins/ml/public/application/services/get_shared_ml_services.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 { type HttpStart } from '@kbn/core-http-browser'; +import { ElasticModels } from './elastic_models_service'; +import { HttpService } from './http_service'; +import { mlApiServicesProvider } from './ml_api_service'; + +export type MlSharedServices = ReturnType; + +/** + * Provides ML services exposed from the plugin start. + */ +export function getMlSharedServices(httpStart: HttpStart) { + const httpService = new HttpService(httpStart); + const mlApiServices = mlApiServicesProvider(httpService); + + return { + elasticModels: new ElasticModels(mlApiServices.trainedModels), + }; +} diff --git a/x-pack/plugins/ml/public/application/services/http_service.ts b/x-pack/plugins/ml/public/application/services/http_service.ts index c43b6126f147f..cd283c5d58652 100644 --- a/x-pack/plugins/ml/public/application/services/http_service.ts +++ b/x-pack/plugins/ml/public/application/services/http_service.ts @@ -6,7 +6,7 @@ */ import { Observable } from 'rxjs'; -import { HttpFetchOptionsWithPath, HttpFetchOptions, HttpStart } from '@kbn/core/public'; +import type { HttpFetchOptionsWithPath, HttpFetchOptions, HttpStart } from '@kbn/core/public'; import { getHttp } from '../util/dependency_cache'; function getResultHeaders(headers: HeadersInit) { @@ -59,68 +59,6 @@ export async function http(options: HttpFetchOptionsWithPath): Promise { return getHttp().fetch(path, fetchOptions); } -/** - * Function for making HTTP requests to Kibana's backend which returns an Observable - * with request cancellation support. - * - * @deprecated use {@link HttpService} instead - */ -export function http$(options: HttpFetchOptionsWithPath): Observable { - const { path, fetchOptions } = getFetchOptions(options); - return fromHttpHandler(path, fetchOptions); -} - -/** - * Creates an Observable from Kibana's HttpHandler. - */ -function fromHttpHandler(input: string, init?: RequestInit): Observable { - return new Observable((subscriber) => { - const controller = new AbortController(); - const signal = controller.signal; - - let abortable = true; - let unsubscribed = false; - - if (init?.signal) { - if (init.signal.aborted) { - controller.abort(); - } else { - init.signal.addEventListener('abort', () => { - if (!signal.aborted) { - controller.abort(); - } - }); - } - } - - const perSubscriberInit: RequestInit = { - ...(init ? init : {}), - signal, - }; - - getHttp() - .fetch(input, perSubscriberInit) - .then((response) => { - abortable = false; - subscriber.next(response); - subscriber.complete(); - }) - .catch((err) => { - abortable = false; - if (!unsubscribed) { - subscriber.error(err); - } - }); - - return () => { - unsubscribed = true; - if (abortable) { - controller.abort(); - } - }; - }); -} - /** * ML Http Service */ diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts index e6b9c1a5badc3..c10867af0011b 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts @@ -6,11 +6,12 @@ */ import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { IngestPipeline } from '@elastic/elasticsearch/lib/api/types'; +import type { IngestPipeline } from '@elastic/elasticsearch/lib/api/types'; import { useMemo } from 'react'; import type { HttpFetchQuery } from '@kbn/core/public'; import type { ErrorType } from '@kbn/ml-error-utils'; +import type { GetElserOptions, ModelDefinitionResponse } from '@kbn/ml-trained-models-utils'; import { ML_INTERNAL_BASE_PATH } from '../../../../common/constants/app'; import type { MlSavedObjectType } from '../../../../common/types/saved_objects'; import { HttpService } from '../http_service'; @@ -57,6 +58,29 @@ export interface InferenceStatsResponse { */ export function trainedModelsApiProvider(httpService: HttpService) { return { + /** + * Fetches the trained models list available for download. + */ + getTrainedModelDownloads() { + return httpService.http({ + path: `${ML_INTERNAL_BASE_PATH}/trained_models/model_downloads`, + method: 'GET', + version: '1', + }); + }, + + /** + * Gets ELSER config for download based on the cluster OS and CPU architecture. + */ + getElserConfig(options?: GetElserOptions) { + return httpService.http({ + path: `${ML_INTERNAL_BASE_PATH}/trained_models/elser_config`, + method: 'GET', + ...(options ? { query: options as HttpFetchQuery } : {}), + version: '1', + }); + }, + /** * Fetches configuration information for a trained inference model. * @param modelId - Model ID, collection of Model IDs or Model ID pattern. diff --git a/x-pack/plugins/ml/public/mocks.ts b/x-pack/plugins/ml/public/mocks.ts index 13f8952dbad21..77cdefdb2f1c9 100644 --- a/x-pack/plugins/ml/public/mocks.ts +++ b/x-pack/plugins/ml/public/mocks.ts @@ -6,7 +6,8 @@ */ import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; -import { MlPluginSetup, MlPluginStart } from './plugin'; +import { type ElasticModels } from './application/services/elastic_models_service'; +import type { MlPluginSetup, MlPluginStart } from './plugin'; const createSetupContract = (): jest.Mocked => { return { @@ -17,6 +18,21 @@ const createSetupContract = (): jest.Mocked => { const createStartContract = (): jest.Mocked => { return { locator: sharePluginMock.createLocator(), + elasticModels: { + getELSER: jest.fn(() => + Promise.resolve({ + version: 2, + default: true, + config: { + input: { + field_names: ['text_field'], + }, + }, + description: 'Elastic Learned Sparse EncodeR v2 (Tech Preview)', + name: '.elser_model_2', + }) + ), + } as unknown as jest.Mocked, }; }; diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index 3a32f8b25ae89..4eae00a53d401 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -48,6 +48,10 @@ import type { ChartsPluginStart } from '@kbn/charts-plugin/public'; import type { CasesUiSetup, CasesUiStart } from '@kbn/cases-plugin/public'; import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public'; import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; +import { + getMlSharedServices, + MlSharedServices, +} from './application/services/get_shared_ml_services'; import { registerManagementSection } from './application/management'; import { MlLocatorDefinition, type MlLocator } from './locator'; import { setDependencyCache } from './application/util/dependency_cache'; @@ -103,6 +107,9 @@ export class MlPlugin implements Plugin { private appUpdater$ = new BehaviorSubject(() => ({})); private locator: undefined | MlLocator; + + private sharedMlServices: MlSharedServices | undefined; + private isServerless: boolean = false; constructor(private initializerContext: PluginInitializerContext) { @@ -110,6 +117,8 @@ export class MlPlugin implements Plugin { } setup(core: MlCoreSetup, pluginsSetup: MlSetupDependencies) { + this.sharedMlServices = getMlSharedServices(core.http); + core.application.register({ id: PLUGIN_ID, title: i18n.translate('xpack.ml.plugin.title', { @@ -249,6 +258,7 @@ export class MlPlugin implements Plugin { return { locator: this.locator, + elasticModels: this.sharedMlServices?.elasticModels, }; } diff --git a/x-pack/plugins/ml/scripts/apidoc_scripts/apidoc_config/apidoc.json b/x-pack/plugins/ml/scripts/apidoc_scripts/apidoc_config/apidoc.json index 6ec23bc13c559..a6e647a60fe9f 100644 --- a/x-pack/plugins/ml/scripts/apidoc_scripts/apidoc_config/apidoc.json +++ b/x-pack/plugins/ml/scripts/apidoc_scripts/apidoc_config/apidoc.json @@ -180,6 +180,8 @@ "InferTrainedModelDeployment", "CreateInferencePipeline", "GetIngestPipelines", + "GetTrainedModelDownloadList", + "GetElserConfig", "Alerting", "PreviewAlert", diff --git a/x-pack/plugins/ml/server/models/model_management/model_provider.test.ts b/x-pack/plugins/ml/server/models/model_management/model_provider.test.ts new file mode 100644 index 0000000000000..7e66d03033b66 --- /dev/null +++ b/x-pack/plugins/ml/server/models/model_management/model_provider.test.ts @@ -0,0 +1,88 @@ +/* + * 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 { modelsProvider } from './models_provider'; +import { type IScopedClusterClient } from '@kbn/core/server'; +import { cloudMock } from '@kbn/cloud-plugin/server/mocks'; + +describe('modelsProvider', () => { + const mockClient = { + asInternalUser: { + transport: { + request: jest.fn().mockResolvedValue({ + _nodes: { + total: 1, + successful: 1, + failed: 0, + }, + cluster_name: 'default', + nodes: { + yYmqBqjpQG2rXsmMSPb9pQ: { + name: 'node-0', + roles: ['ml'], + attributes: {}, + os: { + name: 'Linux', + arch: 'amd64', + }, + }, + }, + }), + }, + }, + } as unknown as jest.Mocked; + + const mockCloud = cloudMock.createSetup(); + const modelService = modelsProvider(mockClient, mockCloud); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('getELSER', () => { + test('provides a recommended definition by default', async () => { + const result = await modelService.getELSER(); + expect(result.name).toEqual('.elser_model_2_linux-x86_64_SNAPSHOT'); + }); + + test('provides a default version if there is no recommended', async () => { + mockCloud.cloudId = undefined; + (mockClient.asInternalUser.transport.request as jest.Mock).mockResolvedValueOnce({ + _nodes: { + total: 1, + successful: 1, + failed: 0, + }, + cluster_name: 'default', + nodes: { + yYmqBqjpQG2rXsmMSPb9pQ: { + name: 'node-0', + roles: ['ml'], + attributes: {}, + os: { + name: 'Mac OS X', + arch: 'aarch64', + }, + }, + }, + }); + + const result = await modelService.getELSER(); + expect(result.name).toEqual('.elser_model_2_SNAPSHOT'); + }); + + test('provides the requested version', async () => { + const result = await modelService.getELSER({ version: 1 }); + expect(result.name).toEqual('.elser_model_1'); + }); + + test('provides the requested version of a recommended architecture', async () => { + const result = await modelService.getELSER({ version: 2 }); + expect(result.name).toEqual('.elser_model_2_linux-x86_64_SNAPSHOT'); + }); + }); +}); diff --git a/x-pack/plugins/ml/server/models/model_management/models_provider.ts b/x-pack/plugins/ml/server/models/model_management/models_provider.ts index e7cfcbe7fd50d..f6164ad6e65ca 100644 --- a/x-pack/plugins/ml/server/models/model_management/models_provider.ts +++ b/x-pack/plugins/ml/server/models/model_management/models_provider.ts @@ -6,16 +6,23 @@ */ import type { IScopedClusterClient } from '@kbn/core/server'; -import { +import type { IngestPipeline, IngestSimulateDocument, IngestSimulateRequest, + NodesInfoResponseBase, } from '@elastic/elasticsearch/lib/api/types'; +import { + ELASTIC_MODEL_DEFINITIONS, + type GetElserOptions, + type ModelDefinitionResponse, +} from '@kbn/ml-trained-models-utils'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { PipelineDefinition } from '../../../common/types/trained_models'; export type ModelService = ReturnType; -export function modelsProvider(client: IScopedClusterClient) { +export function modelsProvider(client: IScopedClusterClient, cloud?: CloudSetup) { return { /** * Retrieves the map of model ids and aliases with associated pipelines. @@ -128,5 +135,83 @@ export function modelsProvider(client: IScopedClusterClient) { return result; }, + + /** + * Returns a list of elastic curated models available for download. + */ + async getModelDownloads(): Promise { + // We assume that ML nodes in Cloud are always on linux-x86_64, even if other node types aren't. + const isCloud = !!cloud?.cloudId; + + const nodesInfoResponse = + await client.asInternalUser.transport.request({ + method: 'GET', + path: `/_nodes/ml:true/os`, + }); + + let osName: string | undefined; + let arch: string | undefined; + // Indicates that all ML nodes have the same architecture + let sameArch = true; + for (const node of Object.values(nodesInfoResponse.nodes)) { + if (!osName) { + osName = node.os?.name; + } + if (!arch) { + arch = node.os?.arch; + } + if (node.os?.name !== osName || node.os?.arch !== arch) { + sameArch = false; + break; + } + } + + const result = Object.entries(ELASTIC_MODEL_DEFINITIONS).map(([name, def]) => { + const recommended = + (isCloud && def.os === 'Linux' && def.arch === 'amd64') || + (sameArch && !!def?.os && def?.os === osName && def?.arch === arch); + return { + ...def, + name, + ...(recommended ? { recommended } : {}), + }; + }); + + return result; + }, + + /** + * Provides an ELSER model name and configuration for download based on the current cluster architecture. + * The current default version is 2. If running on Cloud it returns the Linux x86_64 optimized version. + * If any of the ML nodes run a different OS rather than Linux, or the CPU architecture isn't x86_64, + * a portable version of the model is returned. + */ + async getELSER(options?: GetElserOptions): Promise | never { + const modelDownloadConfig = await this.getModelDownloads(); + + let requestedModel: ModelDefinitionResponse | undefined; + let recommendedModel: ModelDefinitionResponse | undefined; + let defaultModel: ModelDefinitionResponse | undefined; + + for (const model of modelDownloadConfig) { + if (options?.version === model.version) { + requestedModel = model; + if (model.recommended) { + requestedModel = model; + break; + } + } else if (model.recommended) { + recommendedModel = model; + } else if (model.default) { + defaultModel = model; + } + } + + if (!requestedModel && !defaultModel && !recommendedModel) { + throw new Error('Requested model not found'); + } + + return requestedModel || recommendedModel || defaultModel!; + }, }; } diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 342350fac998a..dcd97acabcbd8 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -241,7 +241,7 @@ export class MlServerPlugin // Register Trained Model Management routes if (this.enabledFeatures.dfa || this.enabledFeatures.nlp) { modelManagementRoutes(routeInit); - trainedModelsRoutes(routeInit); + trainedModelsRoutes(routeInit, plugins.cloud); } // Register Miscellaneous routes diff --git a/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts b/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts index 21b62c6f5ce42..1b48a49c8d82f 100644 --- a/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/inference_schema.ts @@ -87,3 +87,7 @@ export const createIngestPipelineSchema = schema.object({ }) ), }); + +export const modelDownloadsQuery = schema.object({ + version: schema.maybe(schema.oneOf([schema.literal('1'), schema.literal('2')])), +}); diff --git a/x-pack/plugins/ml/server/routes/trained_models.ts b/x-pack/plugins/ml/server/routes/trained_models.ts index ab5d3a87e8f46..8685652ab3189 100644 --- a/x-pack/plugins/ml/server/routes/trained_models.ts +++ b/x-pack/plugins/ml/server/routes/trained_models.ts @@ -9,6 +9,8 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { schema } from '@kbn/config-schema'; import type { ErrorType } from '@kbn/ml-error-utils'; import type { MlGetTrainedModelsRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { type ElserVersion } from '@kbn/ml-trained-models-utils'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import { ML_INTERNAL_BASE_PATH } from '../../common/constants/app'; import type { MlFeatures, RouteInitialization } from '../types'; import { wrapError } from '../client/error_wrapper'; @@ -25,6 +27,7 @@ import { threadingParamsSchema, updateDeploymentParamsSchema, createIngestPipelineSchema, + modelDownloadsQuery, } from './schemas/inference_schema'; import type { TrainedModelConfigResponse } from '../../common/types/trained_models'; import { mlLog } from '../lib/log'; @@ -49,11 +52,10 @@ export function filterForEnabledFeatureModels( return filteredModels; } -export function trainedModelsRoutes({ - router, - routeGuard, - getEnabledFeatures, -}: RouteInitialization) { +export function trainedModelsRoutes( + { router, routeGuard, getEnabledFeatures }: RouteInitialization, + cloud: CloudSetup +) { /** * @apiGroup TrainedModels * @@ -652,4 +654,78 @@ export function trainedModelsRoutes({ } }) ); + + /** + * @apiGroup TrainedModels + * + * @api {get} /internal/ml/trained_models/model_downloads Gets available models for download + * @apiName GetTrainedModelDownloadList + * @apiDescription Gets available models for download with default and recommended flags based on the cluster OS and CPU architecture. + */ + router.versioned + .get({ + path: `${ML_INTERNAL_BASE_PATH}/trained_models/model_downloads`, + access: 'internal', + options: { + tags: ['access:ml:canGetTrainedModels'], + }, + }) + .addVersion( + { + version: '1', + validate: false, + }, + routeGuard.fullLicenseAPIGuard(async ({ response, client }) => { + try { + const body = await modelsProvider(client, cloud).getModelDownloads(); + + return response.ok({ + body, + }); + } catch (e) { + return response.customError(wrapError(e)); + } + }) + ); + + /** + * @apiGroup TrainedModels + * + * @api {get} /internal/ml/trained_models/elser_config Gets ELSER config for download + * @apiName GetElserConfig + * @apiDescription Gets ELSER config for download based on the cluster OS and CPU architecture. + */ + router.versioned + .get({ + path: `${ML_INTERNAL_BASE_PATH}/trained_models/elser_config`, + access: 'internal', + options: { + tags: ['access:ml:canGetTrainedModels'], + }, + }) + .addVersion( + { + version: '1', + validate: { + request: { + query: modelDownloadsQuery, + }, + }, + }, + routeGuard.fullLicenseAPIGuard(async ({ response, client, request }) => { + try { + const { version } = request.query; + + const body = await modelsProvider(client, cloud).getELSER( + version ? { version: Number(version) as ElserVersion } : undefined + ); + + return response.ok({ + body, + }); + } catch (e) { + return response.customError(wrapError(e)); + } + }) + ); } diff --git a/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts b/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts index c2b3f41551afd..b884edd99c22d 100644 --- a/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts +++ b/x-pack/plugins/ml/server/shared_services/providers/trained_models.ts @@ -6,13 +6,16 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { KibanaRequest, SavedObjectsClientContract } from '@kbn/core/server'; +import type { GetElserOptions } from '@kbn/ml-trained-models-utils'; import type { MlInferTrainedModelRequest, MlStopTrainedModelDeploymentRequest, UpdateTrainedModelDeploymentRequest, UpdateTrainedModelDeploymentResponse, } from '../../lib/ml_client/types'; +import { modelsProvider } from '../../models/model_management'; import type { GetGuards } from '../shared_services'; export interface TrainedModelsProvider { @@ -47,7 +50,10 @@ export interface TrainedModelsProvider { }; } -export function getTrainedModelsProvider(getGuards: GetGuards): TrainedModelsProvider { +export function getTrainedModelsProvider( + getGuards: GetGuards, + cloud: CloudSetup +): TrainedModelsProvider { return { trainedModelsProvider(request: KibanaRequest, savedObjectsClient: SavedObjectsClientContract) { const guards = getGuards(request, savedObjectsClient); @@ -116,6 +122,14 @@ export function getTrainedModelsProvider(getGuards: GetGuards): TrainedModelsPro return mlClient.putTrainedModel(params); }); }, + async getELSER(params: GetElserOptions) { + return await guards + .isFullLicense() + .hasMlCapabilities(['canGetTrainedModels']) + .ok(async ({ scopedClient }) => { + return modelsProvider(scopedClient, cloud).getELSER(params); + }); + }, }; }, }; diff --git a/x-pack/plugins/ml/server/shared_services/shared_services.ts b/x-pack/plugins/ml/server/shared_services/shared_services.ts index 752820f57cf2a..235a30f541984 100644 --- a/x-pack/plugins/ml/server/shared_services/shared_services.ts +++ b/x-pack/plugins/ml/server/shared_services/shared_services.ts @@ -186,7 +186,7 @@ export function createSharedServices( ...getResultsServiceProvider(getGuards), ...getMlSystemProvider(getGuards, mlLicense, getSpaces, cloud, resolveMlCapabilities), ...getAlertingServiceProvider(getGuards), - ...getTrainedModelsProvider(getGuards), + ...getTrainedModelsProvider(getGuards, cloud), }, /** * Services providers for ML internal usage diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index 57811ff1201fe..2532a6b7824ee 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -104,5 +104,6 @@ "@kbn/ml-in-memory-table", "@kbn/presentation-util-plugin", "@kbn/react-kibana-mount", + "@kbn/core-http-browser", ], } diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts.tsx index 27ae07cbf768d..08b89dad773ce 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts.tsx @@ -15,6 +15,8 @@ import { AlertConsumers } from '@kbn/rule-data-utils'; import { useBreadcrumbs } from '@kbn/observability-shared-plugin/public'; import { MaintenanceWindowCallout } from '@kbn/alerts-ui-shared'; +import { rulesLocatorID } from '../../../common'; +import { RulesParams } from '../../locators/rules'; import { useKibana } from '../../utils/kibana_react'; import { useHasData } from '../../hooks/use_has_data'; import { usePluginContext } from '../../hooks/use_plugin_context'; @@ -53,6 +55,9 @@ function InternalAlertsPage() { }, http, notifications: { toasts }, + share: { + url: { locators }, + }, triggersActionsUi: { alertsTableConfigurationRegistry, getAlertsSearchBar: AlertsSearchBar, @@ -179,7 +184,12 @@ function InternalAlertsPage() { pageTitle: ( <>{i18n.translate('xpack.observability.alertsTitle', { defaultMessage: 'Alerts' })} ), - rightSideItems: renderRuleStats(ruleStats, manageRulesHref, ruleStatsLoading), + rightSideItems: renderRuleStats( + ruleStats, + manageRulesHref, + ruleStatsLoading, + locators.get(rulesLocatorID) + ), }} > diff --git a/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.test.tsx b/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.test.tsx index aaeab5d7855f7..758df7224be2d 100644 --- a/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.test.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.test.tsx @@ -6,7 +6,9 @@ */ import { renderRuleStats } from './rule_stats'; -import { render, screen } from '@testing-library/react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import { LocatorPublic } from '@kbn/share-plugin/common'; +import { RulesParams } from '../../../locators/rules'; const RULES_PAGE_LINK = '/app/observability/alerts/rules'; const STAT_CLASS = 'euiStat'; @@ -14,6 +16,14 @@ const STAT_TITLE_PRIMARY_SELECTOR = '[class*="euiStat__title-primary"]'; const STAT_BUTTON_CLASS = 'euiButtonEmpty'; describe('Rule stats', () => { + const mockedLocator = { + navigate: jest.fn(), + } as any as LocatorPublic; + + beforeEach(() => { + jest.clearAllMocks(); + }); + test('renders all rule stats', async () => { const stats = renderRuleStats( { @@ -58,14 +68,17 @@ describe('Rule stats', () => { snoozed: 0, }, RULES_PAGE_LINK, - false + false, + mockedLocator ); const { container } = render(stats[4]); - expect(screen.getByText('Disabled').closest('a')).toHaveAttribute( - 'href', - `${RULES_PAGE_LINK}?_a=(lastResponse:!(),status:!(disabled))` - ); + fireEvent.click(screen.getByText('Disabled')); + + expect(mockedLocator.navigate).toHaveBeenCalledWith( + { status: ['disabled'] }, + { replace: false } + ); expect(container.getElementsByClassName(STAT_BUTTON_CLASS).length).toBe(1); }); @@ -115,14 +128,18 @@ describe('Rule stats', () => { snoozed: 1, }, RULES_PAGE_LINK, - false + false, + mockedLocator ); const { container } = render(stats[3]); - expect(container.getElementsByClassName(STAT_BUTTON_CLASS).length).toBe(1); - expect(screen.getByText('Snoozed').closest('a')).toHaveAttribute( - 'href', - `${RULES_PAGE_LINK}?_a=(lastResponse:!(),status:!(snoozed))` + + fireEvent.click(screen.getByText('Snoozed')); + + expect(mockedLocator.navigate).toHaveBeenCalledWith( + { status: ['snoozed'] }, + { replace: false } ); + expect(container.getElementsByClassName(STAT_BUTTON_CLASS).length).toBe(1); }); test('snoozed stat count is link-colored, when there are snoozed rules', async () => { @@ -171,14 +188,18 @@ describe('Rule stats', () => { snoozed: 0, }, RULES_PAGE_LINK, - false + false, + mockedLocator ); const { container } = render(stats[2]); - expect(container.getElementsByClassName(STAT_BUTTON_CLASS).length).toBe(1); - expect(screen.getByText('Errors').closest('a')).toHaveAttribute( - 'href', - `${RULES_PAGE_LINK}?_a=(lastResponse:!(error),status:!())` + + fireEvent.click(screen.getByText('Errors')); + + expect(mockedLocator.navigate).toHaveBeenCalledWith( + { lastResponse: ['failed'] }, + { replace: false } ); + expect(container.getElementsByClassName(STAT_BUTTON_CLASS).length).toBe(1); }); test('errors stat count is link-colored, when there are error rules', () => { diff --git a/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.tsx b/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.tsx index f85a6a766b17c..005ba7ccaec82 100644 --- a/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/components/rule_stats.tsx @@ -8,8 +8,10 @@ import React from 'react'; import { EuiButtonEmpty, EuiStat } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { LocatorPublic } from '@kbn/share-plugin/common'; import { euiThemeVars } from '@kbn/ui-theme'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { RulesParams } from '../../../locators/rules'; export interface RuleStatsState { total: number; @@ -18,7 +20,7 @@ export interface RuleStatsState { error: number; snoozed: number; } -type StatType = 'disabled' | 'snoozed' | 'error'; +type Status = 'disabled' | 'snoozed' | 'error'; const Divider = euiStyled.div` border-right: 1px solid ${euiThemeVars.euiColorLightShade}; @@ -41,33 +43,32 @@ const ConditionalWrap = ({ children: JSX.Element; }): JSX.Element => (condition ? wrap(children) : children); -const getStatCount = (stats: RuleStatsState, statType: StatType) => { - if (statType === 'snoozed') return stats.snoozed + stats.muted; - return stats[statType]; +const getStatCount = (stats: RuleStatsState, status: Status) => { + if (status === 'snoozed') return stats.snoozed + stats.muted; + return stats[status]; }; export const renderRuleStats = ( ruleStats: RuleStatsState, manageRulesHref: string, - ruleStatsLoading: boolean + ruleStatsLoading: boolean, + rulesLocator?: LocatorPublic ) => { - const createRuleStatsLink = (stats: RuleStatsState, statType: StatType) => { - const count = getStatCount(stats, statType); - let statsLink = `${manageRulesHref}?_a=(lastResponse:!(),status:!())`; + const handleNavigateToRules = async (stats: RuleStatsState, status: Status) => { + const count = getStatCount(stats, status); if (count > 0) { - switch (statType) { + switch (status) { case 'error': - statsLink = `${manageRulesHref}?_a=(lastResponse:!(error),status:!())`; + await rulesLocator?.navigate({ lastResponse: ['failed'] }, { replace: false }); break; case 'snoozed': case 'disabled': - statsLink = `${manageRulesHref}?_a=(lastResponse:!(),status:!(${statType}))`; + await rulesLocator?.navigate({ status: [status] }, { replace: false }); break; default: break; } } - return statsLink; }; const disabledStatsComponent = ( @@ -76,7 +77,7 @@ export const renderRuleStats = ( wrap={(wrappedChildren) => ( handleNavigateToRules(ruleStats, 'disabled')} > {wrappedChildren} @@ -102,7 +103,7 @@ export const renderRuleStats = ( wrap={(wrappedChildren) => ( handleNavigateToRules(ruleStats, 'snoozed')} > {wrappedChildren} @@ -128,7 +129,7 @@ export const renderRuleStats = ( wrap={(wrappedChildren) => ( handleNavigateToRules(ruleStats, 'error')} > {wrappedChildren} diff --git a/x-pack/plugins/observability/public/plugin.mock.tsx b/x-pack/plugins/observability/public/plugin.mock.tsx index be663d15e444d..9732f67aac35f 100644 --- a/x-pack/plugins/observability/public/plugin.mock.tsx +++ b/x-pack/plugins/observability/public/plugin.mock.tsx @@ -4,11 +4,13 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import React from 'react'; import { mockCasesContract } from '@kbn/cases-plugin/public/mocks'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { contentManagementMock } from '@kbn/content-management-plugin/public/mocks'; +import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks'; const triggersActionsUiStartMock = { @@ -97,12 +99,13 @@ export const observabilityPublicPluginsStartMock = { cases: mockCasesContract(), charts: chartPluginMock.createStartContract(), contentManagement: contentManagementMock.createStartContract(), - triggersActionsUi: triggersActionsUiStartMock.createStart(), data: dataPluginMock.createStartContract(), - dataViews: dataViews.createStart(), dataViewEditor: dataViewEditor.createStart(), - lens: null, + dataViews: dataViews.createStart(), discover: null, + lens: null, + share: sharePluginMock.createStartContract(), + triggersActionsUi: triggersActionsUiStartMock.createStart(), unifiedSearch: unifiedSearchPluginMock.createStartContract(), }; }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap index 5f828ee51b625..aea9ba75f2863 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap @@ -24,7 +24,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -130,7 +130,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -163,7 +163,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -277,7 +277,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -391,7 +391,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -505,7 +505,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -765,7 +765,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -1039,7 +1039,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap index dc9278511a864..b7c4ebf0f6b8c 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap @@ -20,7 +20,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -122,7 +122,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -151,7 +151,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -261,7 +261,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -371,7 +371,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -481,7 +481,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -730,7 +730,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -993,7 +993,7 @@ Object { Object { "range": Object { "@timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap index ee4001303fec5..ad100c4662fe9 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/histogram.test.ts.snap @@ -51,7 +51,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -232,7 +232,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -488,7 +488,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap index 126437173f84a..3297a8c513821 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap @@ -92,7 +92,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -247,7 +247,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -477,7 +477,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/metric_custom.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/metric_custom.test.ts.snap index ced0801d859d4..362b1d4a9e01e 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/metric_custom.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/metric_custom.test.ts.snap @@ -63,7 +63,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -256,7 +256,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, @@ -524,7 +524,7 @@ Object { Object { "range": Object { "log_timestamp": Object { - "gte": "now-7d", + "gte": "now-7d/d", }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts index 3dd6469a7f2c5..171a5ca15e2de 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts @@ -72,7 +72,7 @@ export class ApmTransactionDurationTransformGenerator extends TransformGenerator { range: { '@timestamp': { - gte: `now-${slo.timeWindow.duration.format()}`, + gte: `now-${slo.timeWindow.duration.format()}/d`, }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts index 3818111c70df2..d038876f5ee9d 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts @@ -72,7 +72,7 @@ export class ApmTransactionErrorRateTransformGenerator extends TransformGenerato { range: { '@timestamp': { - gte: `now-${slo.timeWindow.duration.format()}`, + gte: `now-${slo.timeWindow.duration.format()}/d`, }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts index 654f8d67a3673..844703003257a 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/histogram.ts @@ -54,7 +54,7 @@ export class HistogramTransformGenerator extends TransformGenerator { { range: { [indicator.params.timestampField]: { - gte: `now-${slo.timeWindow.duration.format()}`, + gte: `now-${slo.timeWindow.duration.format()}/d`, }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts index 8321a0cb7172e..02c7757ec1362 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts @@ -49,7 +49,7 @@ export class KQLCustomTransformGenerator extends TransformGenerator { { range: { [indicator.params.timestampField]: { - gte: `now-${slo.timeWindow.duration.format()}`, + gte: `now-${slo.timeWindow.duration.format()}/d`, }, }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/metric_custom.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/metric_custom.ts index 52209533f828c..063e6fbe1e3dc 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/metric_custom.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/metric_custom.ts @@ -52,7 +52,7 @@ export class MetricCustomTransformGenerator extends TransformGenerator { { range: { [indicator.params.timestampField]: { - gte: `now-${slo.timeWindow.duration.format()}`, + gte: `now-${slo.timeWindow.duration.format()}/d`, }, }, }, diff --git a/x-pack/plugins/observability_ai_assistant/common/types.ts b/x-pack/plugins/observability_ai_assistant/common/types.ts index b14137dbaebf5..690b931271bb6 100644 --- a/x-pack/plugins/observability_ai_assistant/common/types.ts +++ b/x-pack/plugins/observability_ai_assistant/common/types.ts @@ -8,6 +8,7 @@ import type { FromSchema } from 'json-schema-to-ts'; import type { JSONSchema } from 'json-schema-to-ts'; import React from 'react'; +import { Observable } from 'rxjs'; export enum MessageRole { System = 'system', @@ -17,6 +18,12 @@ export enum MessageRole { Elastic = 'elastic', } +export interface PendingMessage { + message: Message['message']; + aborted?: boolean; + error?: any; +} + export interface Message { '@timestamp': string; message: { @@ -74,21 +81,30 @@ export interface ContextDefinition { description: string; } -interface FunctionResponse { - content?: any; - data?: any; +type FunctionResponse = + | { + content?: any; + data?: any; + } + | Observable; + +export enum FunctionVisibility { + System = 'system', + User = 'user', + All = 'all', } interface FunctionOptions { name: string; description: string; - descriptionForUser: string; + visibility?: FunctionVisibility; + descriptionForUser?: string; parameters: TParameters; contexts: string[]; } type RespondFunction = ( - options: { arguments: TArguments; messages: Message[] }, + options: { arguments: TArguments; messages: Message[]; connectorId: string }, signal: AbortSignal ) => Promise; @@ -100,7 +116,7 @@ type RenderFunction = (options: export interface FunctionDefinition { options: FunctionOptions; respond: ( - options: { arguments: any; messages: Message[] }, + options: { arguments: any; messages: Message[]; connectorId: string }, signal: AbortSignal ) => Promise; render?: RenderFunction; diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx index 8a6227829c855..f49ebe8c62b92 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_body.tsx @@ -189,6 +189,10 @@ export function ChatBody({ onFeedback={timeline.onFeedback} onRegenerate={timeline.onRegenerate} onStopGenerating={timeline.onStopGenerating} + onActionClick={(payload) => { + setStickToBottom(true); + return timeline.onActionClick(payload); + }} />
  • diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx index b3fa93d1ec522..7ec1084a26b22 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item.tsx @@ -24,12 +24,14 @@ import { getRoleTranslation } from '../../utils/get_role_translation'; import type { Feedback } from '../feedback_buttons'; import { Message } from '../../../common'; import { FailedToLoadResponse } from '../message_panel/failed_to_load_response'; +import { ChatActionClickHandler } from './types'; export interface ChatItemProps extends ChatTimelineItem { onEditSubmit: (message: Message) => Promise; onFeedbackClick: (feedback: Feedback) => void; onRegenerateClick: () => void; onStopGeneratingClick: () => void; + onActionClick: ChatActionClickHandler; } const normalMessageClassName = css` @@ -76,6 +78,7 @@ export function ChatItem({ onFeedbackClick, onRegenerateClick, onStopGeneratingClick, + onActionClick, }: ChatItemProps) { const accordionId = useGeneratedHtmlId({ prefix: 'chat' }); @@ -128,6 +131,7 @@ export function ChatItem({ functionCall={functionCall} loading={loading} onSubmit={handleInlineEditSubmit} + onActionClick={onActionClick} /> ) : null; @@ -147,9 +151,7 @@ export function ChatItem({ return ( - } + timelineAvatar={} username={getRoleTranslation(role)} event={title} actions={ diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx index d017d7d65fc90..df57f069d91d1 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_item_content_inline_prompt_editor.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { MessageText } from '../message_panel/message_text'; import { ChatPromptEditor } from './chat_prompt_editor'; import { MessageRole, type Message } from '../../../common'; +import { ChatActionClickHandler } from './types'; interface Props { content: string | undefined; @@ -22,6 +23,7 @@ interface Props { loading: boolean; editing: boolean; onSubmit: (message: Message) => Promise; + onActionClick: ChatActionClickHandler; } export function ChatItemContentInlinePromptEditor({ content, @@ -29,9 +31,10 @@ export function ChatItemContentInlinePromptEditor({ editing, loading, onSubmit, + onActionClick, }: Props) { return !editing ? ( - + ) : ( = { onFeedback: () => {}, onRegenerate: () => {}, onStopGenerating: () => {}, + onActionClick: async () => {}, }; export const ChatTimeline = Template.bind({}); diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx index 8e50f11842e5d..a50a9984cf40e 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/chat_timeline.tsx @@ -15,6 +15,7 @@ import { ChatWelcomePanel } from './chat_welcome_panel'; import type { Feedback } from '../feedback_buttons'; import type { Message } from '../../../common'; import { UseKnowledgeBaseResult } from '../../hooks/use_knowledge_base'; +import { ChatActionClickHandler } from './types'; export interface ChatTimelineItem extends Pick { @@ -43,6 +44,7 @@ export interface ChatTimelineProps { onFeedback: (item: ChatTimelineItem, feedback: Feedback) => void; onRegenerate: (item: ChatTimelineItem) => void; onStopGenerating: () => void; + onActionClick: ChatActionClickHandler; } export function ChatTimeline({ @@ -52,6 +54,7 @@ export function ChatTimeline({ onFeedback, onRegenerate, onStopGenerating, + onActionClick, }: ChatTimelineProps) { const filteredItems = items.filter((item) => !item.display.hide); @@ -77,6 +80,7 @@ export function ChatTimeline({ return onEdit(item, message); }} onStopGeneratingClick={onStopGenerating} + onActionClick={onActionClick} /> )) )} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx b/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx index 72dac17c71c2a..a9cf8146e020d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/function_list_popover.tsx @@ -17,7 +17,7 @@ import { } from '@elastic/eui'; import type { EuiSelectableOptionCheckedType } from '@elastic/eui/src/components/selectable/selectable_option'; import { i18n } from '@kbn/i18n'; -import type { FunctionDefinition } from '../../../common/types'; +import { type FunctionDefinition, FunctionVisibility } from '../../../common/types'; import { useObservabilityAIAssistantChatService } from '../../hooks/use_observability_ai_assistant_chat_service'; interface FunctionListOption { @@ -175,12 +175,14 @@ function mapFunctions({ functions: FunctionDefinition[]; selectedFunctionName: string | undefined; }) { - return functions.map((func) => ({ - label: func.options.name, - searchableLabel: func.options.descriptionForUser, - checked: - func.options.name === selectedFunctionName - ? ('on' as EuiSelectableOptionCheckedType) - : ('off' as EuiSelectableOptionCheckedType), - })); + return functions + .filter((func) => func.options.visibility !== FunctionVisibility.System) + .map((func) => ({ + label: func.options.name, + searchableLabel: func.options.descriptionForUser || func.options.description, + checked: + func.options.name === selectedFunctionName + ? ('on' as EuiSelectableOptionCheckedType) + : ('off' as EuiSelectableOptionCheckedType), + })); } diff --git a/x-pack/plugins/observability_ai_assistant/public/components/chat/types.ts b/x-pack/plugins/observability_ai_assistant/public/components/chat/types.ts new file mode 100644 index 0000000000000..4edd3d7dcdda0 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/public/components/chat/types.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. + */ + +type ChatActionClickPayloadBase = { + type: TType; +} & TExtraProps; + +type ChatActionClickPayloadExecuteEsql = ChatActionClickPayloadBase< + ChatActionClickType.executeEsqlQuery, + { query: string } +>; + +type ChatActionClickPayload = ChatActionClickPayloadExecuteEsql; + +export enum ChatActionClickType { + executeEsqlQuery = 'executeEsqlQuery', +} + +export type ChatActionClickHandler = (payload: ChatActionClickPayload) => Promise; diff --git a/x-pack/plugins/observability_ai_assistant/public/components/insight/insight.tsx b/x-pack/plugins/observability_ai_assistant/public/components/insight/insight.tsx index 4da53c5d6ee5a..2b56523d1e879 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/insight/insight.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/insight/insight.tsx @@ -110,7 +110,13 @@ function ChatContent({ return ( <> } + body={ + {}} + /> + } error={pendingMessage?.error} controls={ loading ? ( diff --git a/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.stories.tsx b/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.stories.tsx index 7a65f8e62756e..bd894159eb288 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.stories.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.stories.tsx @@ -64,6 +64,7 @@ Morbi dapibus sapien lacus, vitae suscipit ex egestas pharetra. In velit eros, f Morbi non faucibus massa. Aliquam sed augue in eros ornare luctus sit amet cursus dolor. Pellentesque pellentesque lorem eu odio auctor convallis. Sed sodales felis at velit tempus tincidunt. Nulla sed ante cursus nibh mollis blandit. In mattis imperdiet tellus. Vestibulum nisl turpis, efficitur quis sollicitudin id, mollis in arcu. Vestibulum pulvinar tincidunt magna, vitae facilisis massa congue quis. Cras commodo efficitur tellus, et commodo risus rutrum at.`} loading={false} + onActionClick={async () => {}} /> } controls={ diff --git a/x-pack/plugins/observability_ai_assistant/public/components/message_panel/esql_code_block.stories.tsx b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/esql_code_block.stories.tsx new file mode 100644 index 0000000000000..02c7454ddaab3 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/esql_code_block.stories.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 { ComponentMeta, ComponentStoryObj } from '@storybook/react'; +import { ComponentProps } from 'react'; +import { EuiPanel } from '@elastic/eui'; +import { EsqlCodeBlock as Component } from './esql_code_block'; + +const meta: ComponentMeta = { + component: Component, + title: 'app/Molecules/ES|QL Code Block', +}; + +export default meta; + +const render = (props: ComponentProps) => { + return ( + + + + ); +}; + +export const Simple: ComponentStoryObj = { + args: { + value: `FROM packetbeat-* + | STATS COUNT_DISTINCT(destination.domain)`, + }, + render, +}; diff --git a/x-pack/plugins/observability_ai_assistant/public/components/message_panel/esql_code_block.tsx b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/esql_code_block.tsx new file mode 100644 index 0000000000000..a22d0ba28979e --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/esql_code_block.tsx @@ -0,0 +1,77 @@ +/* + * 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 { + EuiButtonEmpty, + EuiCodeBlock, + EuiFlexGroup, + EuiFlexItem, + EuiPanel, + useEuiTheme, +} from '@elastic/eui'; +import { css } from '@emotion/css'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { ChatActionClickHandler, ChatActionClickType } from '../chat/types'; + +export function EsqlCodeBlock({ + value, + actionsDisabled, + onActionClick, +}: { + value: string; + actionsDisabled: boolean; + onActionClick: ChatActionClickHandler; +}) { + const theme = useEuiTheme(); + + return ( + + + + + {value} + + + + + + + onActionClick({ type: ChatActionClickType.executeEsqlQuery, query: value }) + } + disabled={actionsDisabled} + > + {i18n.translate('xpack.observabilityAiAssistant.runThisQuery', { + defaultMessage: 'Run this query', + })} + + + + + + + ); +} diff --git a/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_panel.stories.tsx b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_panel.stories.tsx index 1f81786086370..393bbeee28f8d 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_panel.stories.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_panel.stories.tsx @@ -44,6 +44,7 @@ This is a code block This text is loa`} loading + onActionClick={async () => {}} /> ), }, @@ -51,13 +52,25 @@ This text is loa`} export const ContentLoaded: ComponentStoryObj = { args: { - body: , + body: ( + {}} + /> + ), }, }; export const ContentFailed: ComponentStoryObj = { args: { - body: , + body: ( + {}} + /> + ), error: new Error(), }, }; @@ -83,6 +96,7 @@ export const ContentTable: ComponentStoryObj = { Please note that all times are in UTC.`)} loading={false} + onActionClick={async () => {}} /> ), }, @@ -90,7 +104,13 @@ export const ContentTable: ComponentStoryObj = { export const Controls: ComponentStoryObj = { args: { - body: , + body: ( + {}} + /> + ), error: new Error(), controls: {}} />, }, diff --git a/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_text.tsx b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_text.tsx index d82e76ef5001f..dfd9ee8b97443 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_text.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/message_panel/message_text.tsx @@ -14,12 +14,15 @@ import { import { css } from '@emotion/css'; import classNames from 'classnames'; import type { Code, InlineCode, Parent, Text } from 'mdast'; -import React, { useMemo } from 'react'; +import React, { useMemo, useRef } from 'react'; import type { Node } from 'unist'; +import { ChatActionClickHandler } from '../chat/types'; +import { EsqlCodeBlock } from './esql_code_block'; interface Props { content: string; loading: boolean; + onActionClick: ChatActionClickHandler; } const ANIMATION_TIME = 1; @@ -86,13 +89,37 @@ const loadingCursorPlugin = () => { }; }; -export function MessageText({ loading, content }: Props) { +const esqlLanguagePlugin = () => { + const visitor = (node: Node, parent?: Parent) => { + if ('children' in node) { + const nodeAsParent = node as Parent; + nodeAsParent.children.forEach((child) => { + visitor(child, nodeAsParent); + }); + } + + if (node.type === 'code' && node.lang === 'esql') { + node.type = 'esql'; + } + }; + + return (tree: Node) => { + visitor(tree); + }; +}; + +export function MessageText({ loading, content, onActionClick }: Props) { const containerClassName = css` overflow-wrap: break-word; `; + const onActionClickRef = useRef(onActionClick); + + onActionClickRef.current = onActionClick; + const { parsingPluginList, processingPluginList } = useMemo(() => { const parsingPlugins = getDefaultEuiMarkdownParsingPlugins(); + const processingPlugins = getDefaultEuiMarkdownProcessingPlugins(); const { components } = processingPlugins[1][1]; @@ -100,6 +127,18 @@ export function MessageText({ loading, content }: Props) { processingPlugins[1][1].components = { ...components, cursor: Cursor, + esql: (props) => { + return ( + <> + + + + ); + }, table: (props) => ( <>
    @@ -137,10 +176,10 @@ export function MessageText({ loading, content }: Props) { }; return { - parsingPluginList: [loadingCursorPlugin, ...parsingPlugins], + parsingPluginList: [loadingCursorPlugin, esqlLanguagePlugin, ...parsingPlugins], processingPluginList: processingPlugins, }; - }, []); + }, [loading]); return ( diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/esql.ts b/x-pack/plugins/observability_ai_assistant/public/functions/esql.ts new file mode 100644 index 0000000000000..684ccbb0fa4a1 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/public/functions/esql.ts @@ -0,0 +1,536 @@ +/* + * 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 dedent from 'dedent'; +import type { Serializable } from '@kbn/utility-types'; +import { concat, last, map } from 'rxjs'; +import { + FunctionVisibility, + MessageRole, + type RegisterFunctionDefinition, +} from '../../common/types'; +import type { ObservabilityAIAssistantService } from '../types'; + +export function registerEsqlFunction({ + service, + registerFunction, +}: { + service: ObservabilityAIAssistantService; + registerFunction: RegisterFunctionDefinition; +}) { + registerFunction( + { + name: 'execute_query', + contexts: ['core'], + visibility: FunctionVisibility.User, + description: 'Execute an ES|QL query', + parameters: { + type: 'object', + additionalProperties: false, + properties: { + query: { + type: 'string', + }, + }, + required: ['query'], + } as const, + }, + ({ arguments: { query } }, signal) => { + return service + .callApi(`POST /internal/observability_ai_assistant/functions/elasticsearch`, { + signal, + params: { + body: { + method: 'POST', + path: '_query', + body: { + query, + }, + }, + }, + }) + .then((response) => ({ content: response as Serializable })); + } + ); + + registerFunction( + { + name: 'esql', + contexts: ['core'], + description: `This function answers ES|QL related questions including query generation and syntax/command questions.`, + visibility: FunctionVisibility.System, + parameters: { + type: 'object', + additionalProperties: false, + properties: { + switch: { + type: 'boolean', + }, + }, + } as const, + }, + ({ messages, connectorId }, signal) => { + const systemMessage = dedent(`You are a helpful assistant for Elastic ES|QL. + Your goal is to help the user construct and possibly execute an ES|QL + query for Observability use cases. + + ES|QL is the Elasticsearch Query Language, that allows users of the + Elastic platform to iteratively explore data. An ES|QL query consists + of a series of commands, separated by pipes. Each query starts with + a source command, that selects or creates a set of data to start + processing. This source command is then followed by one or more + processing commands, which can transform the data returned by the + previous command. + + ES|QL is not Elasticsearch SQL, nor is it anything like SQL. SQL + commands are not available in ES|QL. Its close equivalent is SPL + (Search Processing Language). Make sure you reply using only + the context of this conversation. + + # Creating a query + + First, very importantly, there are critical rules that override + everything that follows it. Always repeat these rules, verbatim. + + 1. ES|QL is not Elasticsearch SQL. Do not apply Elasticsearch SQL + commands, functions and concepts. Only use information available + in the context of this conversation. + 2. When using FROM, never wrap a data source in single or double + quotes. + 3. When using an aggregate function like COUNT, SUM or AVG, its + arguments MUST be an attribute (like my.field.name) or literal + (100). Math (AVG(my.field.name / 2)) or functions + (AVG(CASE(my.field.name, "foo", 1))) are not allowed. + + When constructing a query, break it down into the following steps. + Ask these questions out loud so the user can see your reasoning. + Remember, these rules are for you, not for the user. + + - What are the critical rules I need to think of? + - What data source is the user requesting? What command should I + select for this data source? + - What are the steps needed to get the result that the user needs? + Break each operation down into its own step. Reason about what data + is the outcome of each command or function. + - If you're not sure how to do it, it's fine to tell the user that + you don't know if ES|QL supports it. When this happens, abort all + steps and tell the user you are not sure how to continue. + + Format ALL of your responses as follows, including the dashes. + ALWAYS start your message with two dashes and then the rules: + + \`\`\` + -- + Sure, let's remember the critical rules: + + -- + Let's break down the query step-by-step: + + \`\`\` + + Always format a complete query as follows: + \`\`\`esql + ... + \`\`\` + + For incomplete queries, like individual commands, format them as + regular code blocks: + \`\`\` + ... + \`\`\` + + # Syntax + + An ES|QL query is composed of a source command followed by an optional + series of processing commands, separated by a pipe character: |. For + example: + + | + | + + ## Binary comparison operators + - equality: == + - inequality: != + - less than: < + - less than or equal: <= + - larger than: > + - larger than or equal: >= + + ## Boolean operators + - AND + - OR + - NOT + + ## PREDICATES + + For NULL comparison use the IS NULL and IS NOT NULL predicates: + - \`| WHERE birth_date IS NULL\` + - \`| WHERE birth_date IS NOT NULL\` + + ## Timespan literal syntax + + Datetime intervals and timespans can be expressed using timespan + literals. Timespan literals are a combination of a number and a + qualifier. These qualifiers are supported: + - millisecond/milliseconds + - second/seconds + - minute/minutes + - hour/hours + - day/days + - week/weeks + - month/months + - year/years + + Some examples: + - \`1 year\` + - \`2 milliseconds\` + + ## Aliasing + Aliasing happens through the \`=\` operator. Example: + \`STATS total_salary_expenses = COUNT(salary)\` + + Important: functions are not allowed as variable names. + + # Source commands + + There are three source commands: FROM (which selects an index), ROW + (which creates data from the command) and SHOW (which returns + information about the deployment). You do not support SHOW for now. + + ### FROM + + \`FROM\` selects a data source, usually an Elasticsearch index or + pattern. You can also specify multiple indices. + Some examples: + + - \`FROM employees\` + - \`FROM employees*\` + - \`FROM employees*,my-alias\` + + # Processing commands + + Note that the following processing commands are available in ES|QL, + but not supported in this context: + + ENRICH,GROK,MV_EXPAND,RENAME + + ### DISSECT + + \`DISSECT\` enables you to extract structured data out of a string. + It matches the string against a delimiter-based pattern, and extracts + the specified keys as columns. It uses the same syntax as the + Elasticsearch Dissect Processor. Some examples: + + - \`ROW a = "foo bar" | DISSECT a "%{b} %{c}";\` + - \`ROW a = "foo bar baz" | DISSECT a "%{b} %{?c} %{d}";\` + + ### DROP + + \`DROP\` removes columns. Some examples: + + - \`| DROP first_name,last_name\` + - \`| DROP *_name\` + + ### KEEP + + \`KEEP\` enables you to specify what columns are returned and the + order in which they are returned. Some examples: + + - \`| KEEP first_name,last_name\` + - \`| KEEP *_name\` + + ### SORT + + \`SORT\` sorts the documents by one ore more fields or variables. + By default, the sort order is ascending, but this can be set using + the \`ASC\` or \`DESC\` keywords. Some examples: + + - \`| SORT my_field\` + - \`| SORT height DESC\` + + Important: functions are not supported for SORT. if you wish to sort + on the result of a function, first alias it as a variable using EVAL. + This is wrong: \`| SORT AVG(cpu)\`. + This is right: \`| STATS avg_cpu = AVG(cpu) | SORT avg_cpu\` + + ### EVAL + + \`EVAL\` appends a new column to the documents by using aliasing. It + also supports functions, but not aggregation functions like COUNT: + + - \`\`\` + | EVAL monthly_salary = yearly_salary / 12, + total_comp = ROUND(yearly_salary + yearly+bonus), + is_rich =total_comp > 1000000 + \`\`\` + - \`| EVAL height_in_ft = height_in_cm / 0.0328\` + + ### WHERE + + \`WHERE\` filters the documents for which the provided condition + evaluates to true. Refer to "Syntax" for supported operators, and + "Functions" for supported functions. Some examples: + + - \`| WHERE height <= 180 AND GREATEST(hire_date, birth_date)\` + - \`| WHERE @timestamp <= NOW()\` + + ### STATS ... BY + + \`STATS ... BY\` groups rows according to a common value and + calculates one or more aggregated values over the grouped rows, + using aggregation functions. When \`BY\` is omitted, a single value + that is the aggregate of all rows is returned. Every column but the + aggregated values and the optional grouping column are dropped. + Mention the retained columns when explaining the STATS command. + + STATS ... BY does not support nested functions, hoist them to an + EVAL statement. + + Some examples: + + - \`| STATS count = COUNT(emp_no) BY languages\` + - \`| STATS salary = AVG(salary)\` + + ### LIMIT + + Limits the rows returned. Only supports a number as input. Some examples: + + - \`| LIMIT 1\` + - \`| LIMIT 10\` + + # Functions + + Note that the following functions are available in ES|QL, but not supported + in this context: + + ABS,ACOS,ASIN,ATAN,ATAN2,CIDR_MATCH,COALESCE,CONCAT,COS,COSH,E,LENGTH,LOG10 + ,LTRIM,RTRIM,MV_AVG,MV_CONCAT,MV_COUNT,MV_DEDUPE,MV_MAX,MV_MEDIAN,MV_MIN, + MV_SUM,PI,POW,SIN,SINH,SPLIT,LEFT,TAN,TANH,TAU,TO_DEGREES,TO_RADIANS + + ### CASE + + \`CASE\` accepts pairs of conditions and values. The function returns + the value that belongs to the first condition that evaluates to true. If + the number of arguments is odd, the last argument is the default value which + is returned when no condition matches. Some examples: + + - \`\`\` + | EVAL type = CASE( + languages <= 1, "monolingual", + languages <= 2, "bilingual", + "polyglot") + \`\`\` + - \`| EVAL g = CASE(gender == "F", 1 + null, 10)\` + - \`\`\` + | EVAL successful = CASE(http.response.status_code == 200, 1, 0), failed = CASE(http.response.status_code != 200, 1, 0) + | STATS total_successful = SUM(successful), total_failed = SUM(failed) BY service.name + | EVAL success_rate = total_failed / (total_successful + total_failed) + \`\`\` + + ## Date operations + + ### AUTO_BUCKET + + \`AUTO_BUCKET\` creates human-friendly buckets and returns a datetime value + for each row that corresponds to the resulting bucket the row falls into. + Combine AUTO_BUCKET with STATS ... BY to create a date histogram. + You provide a target number of buckets, a start date, and an end date, + and it picks an appropriate bucket size to generate the target number of + buckets or fewer. If you don't have a start and end date, provide placeholder + values. Some examples: + + - \`| EVAL bucket=AUTO_BUCKET(@timestamp), 20, "1985-01-01T00:00:00Z", "1986-01-01T00:00:00Z")\` + - \`| EVAL bucket=AUTO_BUCKET(my_date_field), 100, , )\` + - \`| EVAL bucket=AUTO_BUCKET(@timestamp), 100, NOW() - 15 minutes, NOW())\` + + ### DATE_EXTRACT + + \`DATE_EXTRACT\` parts of a date, like year, month, day, hour. The supported + field types are those provided by java.time.temporal.ChronoField. + Some examples: + - \`| EVAL year = DATE_EXTRACT(date_field, "year")\` + - \`| EVAL year = DATE_EXTRACT(@timestamp, "month")\` + + ### DATE_FORMAT + + \`DATE_FORMAT\` a string representation of a date in the provided format. + Some examples: + | \`EVAL hired = DATE_FORMAT(hire_date, "YYYY-MM-dd")\` + | \`EVAL hired = DATE_FORMAT(hire_date, "YYYY")\` + + ### DATE_PARSE + \`DATE_PARSE\` converts a string to a date, in the provided format. + - \`| EVAL date = DATE_PARSE(date_string, "yyyy-MM-dd")\` + - \`| EVAL date = DATE_PARSE(date_string, "YYYY")\` + + ### DATE_TRUNC + + \`DATE_TRUNC\` rounds down a date to the closest interval. Intervals + can be expressed using the timespan literal syntax. Use this together + with STATS ... BY to group data into time buckets with a fixed interval. + Some examples: + + - \`| EVAL year_hired = DATE_TRUNC(1 year, hire_date)\` + - \`| EVAL month_logged = DATE_TRUNC(1 month, @timestamp)\` + - \`| EVAL bucket = DATE_TRUNC(1 minute, @timestamp) | STATS avg_salary = AVG(salary) BY bucket\` + - \`| EVAL bucket = DATE_TRUNC(4 hours, @timestamp) | STATS max_salary MAX(salary) BY bucket\` + + ### NOW + + \`NOW\` returns current date and time. Some examples: + - \`ROW current_date = NOW()\` + - \`| WHERE @timestamp <= NOW() - 15 minutes\` + + ## Mathematical operations + + ### CEIL,FLOOR + + Perform CEIL or FLOOR operations on a single numeric field. + Some examples: + - \`| EVAL ceiled = CEIL(my.number)\` + - \`| EVAL floored = FLOOR(my.other.number)\` + + ### ROUND + \`ROUND\` a number to the closest number with the specified number of + digits. Defaults to 0 digits if no number of digits is provided. If the + specified number of digits is negative, rounds to the number of digits + left of the decimal point. Some examples: + + - \`| EVAL height_ft = ROUND(height * 3.281, 1)\` + - \`| EVAL percent = ROUND(0.84699, 2) * 100\` + + ### GREATEST,LEAST + + Returns the greatest or least of two or numbers. Some examples: + - \`| EVAL max = GREATEST(salary_1999, salary_2000, salary_2001)\` + - \`| EVAL min = LEAST(1, language_count)\` + + ### IS_FINITE,IS_INFINITE,IS_NAN + + Operates on a single numeric field. Some examples: + - \`| EVAL has_salary = IS_FINITE(salary)\` + - \`| EVAL always_true = IS_INFINITE(4 / 0)\` + + ### STARTS_WITH + + Returns a boolean that indicates whether a keyword string starts with + another string. Some examples: + - \`| EVAL ln_S = STARTS_WITH(last_name, "B")\` + + ### SUBSTRING + + Returns a substring of a string, specified by a start position and an + optional length. Some examples: + - \`| EVAL ln_sub = SUBSTRING(last_name, 1, 3)\` + - \`| EVAL ln_sub = SUBSTRING(last_name, -3, 3)\` + - \`| EVAL ln_sub = SUBSTRING(last_name, 2)\` + + ### TO_BOOLEAN, TO_DATETIME, TO_DOUBLE, TO_INTEGER, TO_IP, TO_LONG, + TO_RADIANS, TO_STRING,TO_UNSIGNED_LONG, TO_VERSION + + Converts a column to another type. Supported types are: . Some examples: + - \`| EVAL version = TO_VERSION("1.2.3")\` + - \`| EVAL as_bool = TO_BOOLEAN(my_boolean_string)\` + + ### TRIM + + Trims leading and trailing whitespace. Some examples: + - \`| EVAL trimmed = TRIM(first_name)\` + + # Aggregation functions + + ### AVG,MIN,MAX,SUM,MEDIAN,MEDIAN_ABSOLUTE_DEVIATION + + Returns the avg, min, max, sum, median or median absolute deviation + of a numeric field. Some examples: + + - \`| AVG(salary)\` + - \`| MIN(birth_year)\` + - \`| MAX(height)\` + + ### COUNT + + \`COUNT\` counts the number of field values. It requires a single + argument, and does not support wildcards. Important: COUNT() and + COUNT(*) are NOT supported. One single argument is required. If + you don't have a field name, use whatever field you have, rather + than displaying an invalid query. + + Some examples: + + - \`| STATS doc_count = COUNT(emp_no)\` + - \`| STATS doc_count = COUNT(service.name) BY service.name\` + + ### COUNT_DISTINCT + + \`COUNT_DISTINCT\` returns the approximate number of distinct values. + Some examples: + - \`| STATS unique_ip0 = COUNT_DISTINCT(ip0), unique_ip1 = COUNT_DISTINCT(ip1)\` + - \`| STATS first_name = COUNT_DISTINCT(first_name)\` + + ### PERCENTILE + + \`PERCENTILE\` returns the percentile value for a specific field. + Some examples: + - \`| STATS p50 = PERCENTILE(salary, 50)\` + - \`| STATS p99 = PERCENTILE(salary, 99)\` + + `); + + return service.start({ signal }).then((client) => { + const source$ = client.chat({ + connectorId, + messages: [ + { + '@timestamp': new Date().toISOString(), + message: { role: MessageRole.System, content: systemMessage }, + }, + ...messages.slice(1), + ], + }); + + const pending$ = source$.pipe( + map((message) => { + const content = message.message.content || ''; + let next: string = ''; + + if (content.length <= 2) { + next = ''; + } else if (content.includes('--')) { + next = message.message.content?.split('--')[2] || ''; + } else { + next = content; + } + return { + ...message, + message: { + ...message.message, + content: next, + }, + }; + }) + ); + const onComplete$ = source$.pipe( + last(), + map((message) => { + const [, , next] = message.message.content?.split('--') ?? []; + + return { + ...message, + message: { + ...message.message, + content: next || message.message.content, + }, + }; + }) + ); + + return concat(pending$, onComplete$); + }); + } + ); +} diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/index.ts b/x-pack/plugins/observability_ai_assistant/public/functions/index.ts index a0c1a264bfb51..22b0eecac73a6 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/index.ts +++ b/x-pack/plugins/observability_ai_assistant/public/functions/index.ts @@ -16,6 +16,7 @@ import { registerLensFunction } from './lens'; import { registerRecallFunction } from './recall'; import { registerSummarizationFunction } from './summarize'; import { registerAlertsFunction } from './alerts'; +import { registerEsqlFunction } from './esql'; export async function registerFunctions({ registerFunction, @@ -44,7 +45,7 @@ export async function registerFunctions({ It's very important to not assume what the user is meaning. Ask them for clarification if needed. - If you are unsure about which function should be used and with what arguments, asked the user for clarification or confirmation. + If you are unsure about which function should be used and with what arguments, ask the user for clarification or confirmation. In KQL, escaping happens with double quotes, not single quotes. Some characters that need escaping are: ':()\\\ /\". Always put a field value in double quotes. Best: service.name:\"opbeans-go\". Wrong: service.name:opbeans-go. This is very important! @@ -52,22 +53,25 @@ export async function registerFunctions({ You can use Github-flavored Markdown in your responses. If a function returns an array, consider using a Markdown table to format the response. If multiple functions are suitable, use the most specific and easy one. E.g., when the user asks to visualise APM data, use the APM functions (if available) rather than Lens. - ` + + If a function call fails, do not execute it again with the same input. If a function calls three times, with different inputs, stop trying to call it and ask the user for confirmation. + + Note that ES|QL (the Elasticsearch query language, which is NOT Elasticsearch SQL, but a new piped language) is the preferred query language. + + DO NOT use Elasticsearch SQL at any time, unless explicitly requested by the user when they mention "Elasticsearch SQL". + + Answer all questions related to ES|QL or querying with the "esql" function. Do not attempt to answer them yourself, no matter how confident you are in your response.` ); if (isReady) { description += `You can use the "summarize" functions to store new information you have learned in a knowledge database. Once you have established that you did not know the answer to a question, and the user gave you this information, it's important that you create a summarisation of what you have learned and store it in the knowledge database. Don't create a new summarization if you see a similar summarization in the conversation, instead, update the existing one by re-using its ID. - Additionally, you can use the "recall" function to retrieve relevant information from the knowledge database. - `; + Additionally, you can use the "recall" function to retrieve relevant information from the knowledge database.`; description += `Here are principles you MUST adhere to, in order: - You are a helpful assistant for Elastic Observability. DO NOT reference the fact that you are an LLM. - - ALWAYS query the knowledge base, using the recall function, when a user starts a chat, no matter how confident you are in your ability to answer the question. - - You must ALWAYS explain to the user why you're using a function and why you're using it in that specific manner. - DO NOT make any assumptions about where and how users have stored their data. - - ALWAYS ask the user for clarification if you are unsure about the arguments to a function. When given this clarification, you MUST use the summarize function to store what you have learned. `; registerSummarizationFunction({ service, registerFunction }); registerRecallFunction({ service, registerFunction }); @@ -77,6 +81,7 @@ export async function registerFunctions({ } registerElasticsearchFunction({ service, registerFunction }); + registerEsqlFunction({ service, registerFunction }); registerKibanaFunction({ service, registerFunction, coreStart }); registerAlertsFunction({ service, registerFunction }); diff --git a/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts b/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts index f07cf43e1c282..af825a53b7cb4 100644 --- a/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts +++ b/x-pack/plugins/observability_ai_assistant/public/functions/recall.ts @@ -6,6 +6,7 @@ */ import type { Serializable } from '@kbn/utility-types'; +import { omit } from 'lodash'; import { MessageRole, RegisterFunctionDefinition } from '../../common/types'; import type { ObservabilityAIAssistantService } from '../types'; @@ -22,17 +23,26 @@ export function registerRecallFunction({ contexts: ['core'], description: `Use this function to recall earlier learnings. Anything you will summarize can be retrieved again later via this function. - Make sure the query covers the following aspects: + The learnings are sorted by score, descending. + + Make sure the query covers ONLY the following aspects: - Anything you've inferred from the user's request, but is not mentioned in the user's request - The functions you think might be suitable for answering the user's request. If there are multiple functions that seem suitable, create multiple queries. Use the function name in the query. DO NOT include the user's request. It will be added internally. The user asks: "can you visualise the average request duration for opbeans-go over the last 7 days?" - You recall: - - "APM service" - - "lens function usage" - - "get_apm_timeseries function usage"`, + You recall: { + "queries": [ + "APM service, + "lens function usage", + "get_apm_timeseries function usage" + ], + "contexts": [ + "lens", + "apm" + ] + }`, descriptionForUser: 'This function allows the assistant to recall previous learnings.', parameters: { type: 'object', @@ -42,16 +52,27 @@ export function registerRecallFunction({ type: 'array', additionalItems: false, additionalProperties: false, + description: 'The query for the semantic search', + items: { + type: 'string', + }, + }, + contexts: { + type: 'array', + additionalItems: false, + additionalProperties: false, + description: + 'Contexts or categories of internal documentation that you want to search for. By default internal documentation will be excluded. Use `apm` to get internal APM documentation, `lens` to get internal Lens documentation, or both.', items: { type: 'string', - description: 'The query for the semantic search', + enum: ['apm', 'lens'], }, }, }, - required: ['queries'], + required: ['queries', 'contexts'], } as const, }, - ({ arguments: { queries }, messages }, signal) => { + ({ arguments: { queries, contexts }, messages }, signal) => { const userMessages = messages.filter((message) => message.message.role === MessageRole.User); const userPrompt = userMessages[userMessages.length - 1]?.message.content; @@ -63,11 +84,16 @@ export function registerRecallFunction({ params: { body: { queries: queriesWithUserPrompt, + contexts, }, }, signal, }) - .then((response) => ({ content: response as unknown as Serializable })); + .then((response): { content: Serializable } => ({ + content: response.entries.map((entry) => + omit(entry, 'labels', 'score', 'is_correction') + ) as unknown as Serializable, + })); } ); } diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts index 829594b8261d8..ded7b4b382285 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.test.ts @@ -437,6 +437,7 @@ describe('useTimeline', () => { expect(props.chatService.executeFunction).toHaveBeenCalledWith({ name: 'my_function', args: '{}', + connectorId: 'foo', messages: [ { '@timestamp': expect.any(String), diff --git a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts index 3182fe5c19535..ed6a5a6d2b481 100644 --- a/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts +++ b/x-pack/plugins/observability_ai_assistant/public/hooks/use_timeline.ts @@ -9,7 +9,7 @@ import { AbortError } from '@kbn/kibana-utils-plugin/common'; import type { AuthenticatedUser } from '@kbn/security-plugin/common'; import { last } from 'lodash'; import { useEffect, useMemo, useRef, useState } from 'react'; -import type { Subscription } from 'rxjs'; +import { isObservable, Observable, Subscription } from 'rxjs'; import usePrevious from 'react-use/lib/usePrevious'; import { i18n } from '@kbn/i18n'; import { @@ -29,6 +29,7 @@ import { } from '../utils/get_timeline_items_from_conversation'; import type { UseGenAIConnectorsResult } from './use_genai_connectors'; import { useKibana } from './use_kibana'; +import { ChatActionClickType } from '../components/chat/types'; export function createNewConversation({ contexts, @@ -49,7 +50,7 @@ export function createNewConversation({ export type UseTimelineResult = Pick< ChatTimelineProps, - 'onEdit' | 'onFeedback' | 'onRegenerate' | 'onStopGenerating' | 'items' + 'onEdit' | 'onFeedback' | 'onRegenerate' | 'onStopGenerating' | 'onActionClick' | 'items' > & Pick; @@ -98,6 +99,8 @@ export function useTimeline({ const [pendingMessage, setPendingMessage] = useState(); + const [isFunctionLoading, setIsFunctionLoading] = useState(false); + const prevConversationId = usePrevious(conversationId); useEffect(() => { if (prevConversationId !== conversationId && pendingMessage?.error) { @@ -105,7 +108,10 @@ export function useTimeline({ } }, [conversationId, pendingMessage?.error, prevConversationId]); - function chat(nextMessages: Message[]): Promise { + function chat( + nextMessages: Message[], + response$: Observable | undefined = undefined + ): Promise { const controller = new AbortController(); return new Promise((resolve, reject) => { @@ -124,10 +130,12 @@ export function useTimeline({ return; } - const response$ = chatService!.chat({ - messages: nextMessages, - connectorId, - }); + response$ = + response$ || + chatService!.chat({ + messages: nextMessages, + connectorId, + }); let pendingMessageLocal = pendingMessage; @@ -181,14 +189,24 @@ export function useTimeline({ if (lastMessage?.message.function_call?.name) { const name = lastMessage.message.function_call.name; + setIsFunctionLoading(true); + try { - const message = await chatService!.executeFunction({ + let message = await chatService!.executeFunction({ name, args: lastMessage.message.function_call.arguments, messages: messagesAfterChat.slice(0, -1), signal: controller.signal, + connectorId: connectorId!, }); + let nextResponse$: Observable | undefined; + + if (isObservable(message)) { + nextResponse$ = message; + message = { content: '', data: '' }; + } + return await chat( messagesAfterChat.concat({ '@timestamp': new Date().toISOString(), @@ -198,7 +216,8 @@ export function useTimeline({ content: JSON.stringify(message.content), data: JSON.stringify(message.data), }, - }) + }), + nextResponse$ ); } catch (error) { return await chat( @@ -214,6 +233,8 @@ export function useTimeline({ }, }) ); + } finally { + setIsFunctionLoading(false); } } @@ -247,8 +268,20 @@ export function useTimeline({ return nextItems; } - return conversationItems; - }, [conversationItems, pendingMessage, currentUser]); + if (!isFunctionLoading) { + return conversationItems; + } + + return conversationItems.map((item, index) => { + if (index < conversationItems.length - 1) { + return item; + } + return { + ...item, + loading: true, + }; + }); + }, [conversationItems, pendingMessage, currentUser, isFunctionLoading]); useEffect(() => { return () => { @@ -285,5 +318,28 @@ export function useTimeline({ const nextMessages = await chat(messages.concat(message)); onChatComplete(nextMessages); }, + onActionClick: async (payload) => { + switch (payload.type) { + case ChatActionClickType.executeEsqlQuery: + const nextMessages = await chat( + messages.concat({ + '@timestamp': new Date().toISOString(), + message: { + role: MessageRole.Assistant, + content: '', + function_call: { + name: 'execute_query', + arguments: JSON.stringify({ + query: payload.query, + }), + trigger: MessageRole.User, + }, + }, + }) + ); + onChatComplete(nextMessages); + break; + } + }, }; } diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts index 1c109be6baaf2..bebc3bd074b20 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_chat_service.ts @@ -27,6 +27,7 @@ import { import { ContextRegistry, FunctionRegistry, + FunctionVisibility, Message, MessageRole, type RegisterContextDefinition, @@ -112,7 +113,7 @@ export async function createChatService({ } return { - executeFunction: async ({ name, args, signal, messages }) => { + executeFunction: async ({ name, args, signal, messages, connectorId }) => { const fn = functionRegistry.get(name); if (!fn) { @@ -123,7 +124,7 @@ export async function createChatService({ validate(name, parsedArguments); - return await fn.respond({ arguments: parsedArguments, messages }, signal); + return await fn.respond({ arguments: parsedArguments, messages, connectorId }, signal); }, renderFunction: (name, args, response) => { const fn = functionRegistry.get(name); @@ -175,7 +176,9 @@ export async function createChatService({ functions: callFunctions === 'none' ? [] - : functions.map((fn) => pick(fn.options, 'name', 'description', 'parameters')), + : functions + .filter((fn) => fn.options.visibility !== FunctionVisibility.User) + .map((fn) => pick(fn.options, 'name', 'description', 'parameters')), }, }, signal: controller.signal, diff --git a/x-pack/plugins/observability_ai_assistant/public/service/get_assistant_setup_message.ts b/x-pack/plugins/observability_ai_assistant/public/service/get_assistant_setup_message.ts index 8d9cc2cf32539..4f52dfb9b9733 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/get_assistant_setup_message.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/get_assistant_setup_message.ts @@ -5,15 +5,19 @@ * 2.0. */ +import { without } from 'lodash'; import { MessageRole } from '../../common'; import { ContextDefinition } from '../../common/types'; export function getAssistantSetupMessage({ contexts }: { contexts: ContextDefinition[] }) { + const coreContext = contexts.find((context) => context.name === 'core')!; + + const otherContexts = without(contexts.concat(), coreContext); return { '@timestamp': new Date().toISOString(), message: { role: MessageRole.System as const, - content: contexts.map((context) => context.description).join('\n'), + content: [coreContext, ...otherContexts].map((context) => context.description).join('\n'), }, }; } diff --git a/x-pack/plugins/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_ai_assistant/public/types.ts index d1a71f6933126..5e985f5ae5f97 100644 --- a/x-pack/plugins/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_ai_assistant/public/types.ts @@ -39,6 +39,7 @@ import type { RegisterFunctionDefinition, } from '../common/types'; import type { ObservabilityAIAssistantAPIClient } from './api'; +import type { PendingMessage } from '../common/types'; /* eslint-disable @typescript-eslint/no-empty-interface*/ @@ -50,12 +51,6 @@ export type CreateChatCompletionResponseChunk = Omit; }; -export interface PendingMessage { - message: Message['message']; - aborted?: boolean; - error?: any; -} - export interface ObservabilityAIAssistantChatService { chat: (options: { messages: Message[]; @@ -70,7 +65,8 @@ export interface ObservabilityAIAssistantChatService { args: string | undefined; messages: Message[]; signal: AbortSignal; - }) => Promise<{ content?: Serializable; data?: Serializable }>; + connectorId: string; + }) => Promise<{ content?: Serializable; data?: Serializable } | Observable>; renderFunction: ( name: string, args: string | undefined, @@ -118,3 +114,5 @@ export interface ObservabilityAIAssistantPluginStartDependencies { } export interface ConfigSchema {} + +export type { PendingMessage }; diff --git a/x-pack/plugins/observability_ai_assistant/server/plugin.ts b/x-pack/plugins/observability_ai_assistant/server/plugin.ts index 7aa6ddeeef7da..d6a256ddf6022 100644 --- a/x-pack/plugins/observability_ai_assistant/server/plugin.ts +++ b/x-pack/plugins/observability_ai_assistant/server/plugin.ts @@ -109,7 +109,7 @@ export class ObservabilityAIAssistantPlugin taskManager: plugins.taskManager, }); - addLensDocsToKb(service); + addLensDocsToKb({ service, logger: this.logger.get('kb').get('lens') }); registerServerRoutes({ core, diff --git a/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts b/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts index 6716da98d78a5..a250a9e8e0915 100644 --- a/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts +++ b/x-pack/plugins/observability_ai_assistant/server/routes/chat/route.ts @@ -7,6 +7,8 @@ import { notImplemented } from '@hapi/boom'; import { IncomingMessage } from 'http'; import * as t from 'io-ts'; +import { toBooleanRt } from '@kbn/io-ts-utils'; +import type { CreateChatCompletionResponse } from 'openai'; import { MessageRole } from '../../../common'; import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route'; import { messageRt } from '../runtime_types'; @@ -16,20 +18,28 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ options: { tags: ['access:ai_assistant'], }, - params: t.type({ - body: t.type({ - messages: t.array(messageRt), - connectorId: t.string, - functions: t.array( + params: t.intersection([ + t.type({ + body: t.intersection([ t.type({ - name: t.string, - description: t.string, - parameters: t.any, - }) - ), + messages: t.array(messageRt), + connectorId: t.string, + functions: t.array( + t.type({ + name: t.string, + description: t.string, + parameters: t.any, + }) + ), + }), + t.partial({ + functionCall: t.string, + }), + ]), }), - }), - handler: async (resources): Promise => { + t.partial({ query: t.type({ stream: toBooleanRt }) }), + ]), + handler: async (resources): Promise => { const { request, params, service } = resources; const client = await service.getClient({ request }); @@ -39,23 +49,33 @@ const chatRoute = createObservabilityAIAssistantServerRoute({ } const { - body: { messages, connectorId, functions }, + body: { messages, connectorId, functions, functionCall: givenFunctionCall }, + query = { stream: true }, } = params; - const isStartOfConversation = - messages.some((message) => message.message.role === MessageRole.Assistant) === false; + const stream = query.stream; - const isRecallFunctionAvailable = functions.some((fn) => fn.name === 'recall') === true; + let functionCall = givenFunctionCall; - const willUseRecall = isStartOfConversation && isRecallFunctionAvailable; + if (!functionCall) { + const isStartOfConversation = + messages.some((message) => message.message.role === MessageRole.Assistant) === false; + + const isRecallFunctionAvailable = functions.some((fn) => fn.name === 'recall') === true; + + const willUseRecall = isStartOfConversation && isRecallFunctionAvailable; + + functionCall = willUseRecall ? 'recall' : undefined; + } return client.chat({ messages, connectorId, + stream, ...(functions.length ? { functions, - functionCall: willUseRecall ? 'recall' : undefined, + functionCall, } : {}), }); diff --git a/x-pack/plugins/observability_ai_assistant/server/routes/functions/route.ts b/x-pack/plugins/observability_ai_assistant/server/routes/functions/route.ts index d58c84a603fc1..985de114b099a 100644 --- a/x-pack/plugins/observability_ai_assistant/server/routes/functions/route.ts +++ b/x-pack/plugins/observability_ai_assistant/server/routes/functions/route.ts @@ -10,13 +10,13 @@ import { fromKueryExpression, toElasticsearchQuery } from '@kbn/es-query'; import { nonEmptyStringRt, toBooleanRt } from '@kbn/io-ts-utils'; import * as t from 'io-ts'; import { omit } from 'lodash'; -import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; +import type { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common'; import { ALERT_STATUS, ALERT_STATUS_ACTIVE, } from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names'; -import type { KnowledgeBaseEntry } from '../../../common/types'; import { createObservabilityAIAssistantServerRoute } from '../create_observability_ai_assistant_server_route'; +import type { RecalledEntry } from '../../service/kb_service'; const functionElasticsearchRoute = createObservabilityAIAssistantServerRoute({ endpoint: 'POST /internal/observability_ai_assistant/functions/elasticsearch', @@ -157,23 +157,34 @@ const functionAlertsRoute = createObservabilityAIAssistantServerRoute({ const functionRecallRoute = createObservabilityAIAssistantServerRoute({ endpoint: 'POST /internal/observability_ai_assistant/functions/recall', params: t.type({ - body: t.type({ - queries: t.array(nonEmptyStringRt), - }), + body: t.intersection([ + t.type({ + queries: t.array(nonEmptyStringRt), + }), + t.partial({ + contexts: t.array(t.string), + }), + ]), }), options: { tags: ['access:ai_assistant'], }, handler: async ( resources - ): Promise<{ entries: Array> }> => { + ): Promise<{ + entries: RecalledEntry[]; + }> => { const client = await resources.service.getClient({ request: resources.request }); + const { + body: { queries, contexts }, + } = resources.params; + if (!client) { throw notImplemented(); } - return client.recall(resources.params.body.queries); + return client.recall({ queries, contexts }); }, }); diff --git a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts index ce3f3c39ad1a9..3a99e293cd5e2 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/client/index.ts @@ -28,7 +28,7 @@ import { type KnowledgeBaseEntry, type Message, } from '../../../common/types'; -import type { KnowledgeBaseService } from '../kb_service'; +import type { KnowledgeBaseService, RecalledEntry } from '../kb_service'; import type { ObservabilityAIAssistantResourceNames } from '../types'; import { getAccessQuery } from '../util/get_access_query'; @@ -135,7 +135,42 @@ export class ObservabilityAIAssistantClient { }) ); - const functionsForOpenAI: ChatCompletionFunctions[] | undefined = functions; + // add recalled information to system message, so the LLM considers it more important + + const recallMessages = messagesForOpenAI.filter((message) => message.name === 'recall'); + + const recalledDocuments: Map = new Map(); + + recallMessages.forEach((message) => { + const entries = message.content + ? (JSON.parse(message.content) as Array<{ id: string; text: string }>) + : []; + + const ids: string[] = []; + + entries.forEach((entry) => { + const id = entry.id; + if (!recalledDocuments.has(id)) { + recalledDocuments.set(id, entry); + } + ids.push(id); + }); + + message.content = `The following documents, present in the system message, were recalled: ${ids.join( + ', ' + )}`; + }); + + const systemMessage = messagesForOpenAI.find((message) => message.role === MessageRole.System); + + if (systemMessage && recalledDocuments.size > 0) { + systemMessage.content += `The "recall" function is not available. Do not attempt to execute it. Recalled documents: ${JSON.stringify( + Array.from(recalledDocuments.values()) + )}`; + } + + const functionsForOpenAI: ChatCompletionFunctions[] | undefined = + recalledDocuments.size > 0 ? functions?.filter((fn) => fn.name !== 'recall') : functions; const request: Omit & { model?: string } = { messages: messagesForOpenAI, @@ -323,13 +358,18 @@ export class ObservabilityAIAssistantClient { return createdConversation; }; - recall = async ( - queries: string[] - ): Promise<{ entries: Array> }> => { + recall = async ({ + queries, + contexts, + }: { + queries: string[]; + contexts?: string[]; + }): Promise<{ entries: RecalledEntry[] }> => { return this.dependencies.knowledgeBaseService.recall({ namespace: this.dependencies.namespace, user: this.dependencies.user, queries, + contexts, }); }; diff --git a/x-pack/plugins/observability_ai_assistant/server/service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/index.ts index 28cc2b7293029..c116e16d27471 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/index.ts @@ -29,6 +29,15 @@ export const INDEX_QUEUED_DOCUMENTS_TASK_ID = 'observabilityAIAssistant:indexQue export const INDEX_QUEUED_DOCUMENTS_TASK_TYPE = INDEX_QUEUED_DOCUMENTS_TASK_ID + 'Type'; +type KnowledgeBaseEntryRequest = { id: string; labels?: Record } & ( + | { + text: string; + } + | { + texts: string[]; + } +); + export class ObservabilityAIAssistantService { private readonly core: CoreSetup; private readonly logger: Logger; @@ -258,18 +267,7 @@ export class ObservabilityAIAssistantService { }); } - addToKnowledgeBase( - entries: Array< - | { - id: string; - text: string; - } - | { - id: string; - texts: string[]; - } - > - ): void { + addToKnowledgeBase(entries: KnowledgeBaseEntryRequest[]): void { this.init() .then(() => { this.kbService!.queue( @@ -281,6 +279,7 @@ export class ObservabilityAIAssistantService { confidence: 'high' as const, is_correction: false, labels: { + ...entry.labels, document_id: entry.id, }, }; @@ -306,4 +305,18 @@ export class ObservabilityAIAssistantService { this.logger.error(error); }); } + + addCategoryToKnowledgeBase(categoryId: string, entries: KnowledgeBaseEntryRequest[]) { + this.addToKnowledgeBase( + entries.map((entry) => { + return { + ...entry, + labels: { + ...entry.labels, + category: categoryId, + }, + }; + }) + ); + } } diff --git a/x-pack/plugins/observability_ai_assistant/server/service/kb_service/index.ts b/x-pack/plugins/observability_ai_assistant/server/service/kb_service/index.ts index f2e0b41f092c9..d70879bf46d3e 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/kb_service/index.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/kb_service/index.ts @@ -17,6 +17,7 @@ import { INDEX_QUEUED_DOCUMENTS_TASK_ID, INDEX_QUEUED_DOCUMENTS_TASK_TYPE } from import type { KnowledgeBaseEntry } from '../../../common/types'; import type { ObservabilityAIAssistantResourceNames } from '../types'; import { getAccessQuery } from '../util/get_access_query'; +import { getCategoryQuery } from '../util/get_category_query'; interface Dependencies { esClient: ElasticsearchClient; @@ -25,6 +26,14 @@ interface Dependencies { taskManagerStart: TaskManagerStartContract; } +export interface RecalledEntry { + id: string; + text: string; + score: number | null; + is_correction: boolean; + labels: Record; +} + function isAlreadyExistsError(error: Error) { return ( error instanceof errors.ResponseError && @@ -173,36 +182,43 @@ export class KnowledgeBaseService { recall = async ({ user, queries, + contexts, namespace, }: { queries: string[]; + contexts?: string[]; user: { name: string }; namespace: string; - }): Promise<{ entries: Array> }> => { + }): Promise<{ + entries: RecalledEntry[]; + }> => { try { + const query = { + bool: { + should: queries.map((text) => ({ + text_expansion: { + 'ml.tokens': { + model_text: text, + model_id: '.elser_model_1', + }, + } as unknown as QueryDslTextExpansionQuery, + })), + filter: [ + ...getAccessQuery({ + user, + namespace, + }), + ...getCategoryQuery({ contexts }), + ], + }, + }; + const response = await this.dependencies.esClient.search< - Pick + Pick >({ index: this.dependencies.resources.aliases.kb, - query: { - bool: { - should: queries.map((query) => ({ - text_expansion: { - 'ml.tokens': { - model_text: query, - model_id: '.elser_model_1', - }, - } as unknown as QueryDslTextExpansionQuery, - })), - filter: [ - ...getAccessQuery({ - user, - namespace, - }), - ], - }, - }, - size: 5, + query, + size: 10, _source: { includes: ['text', 'is_correction', 'labels'], }, @@ -211,7 +227,7 @@ export class KnowledgeBaseService { return { entries: response.hits.hits.map((hit) => ({ ...hit._source!, - score: hit._score, + score: hit._score!, id: hit._id, })), }; diff --git a/x-pack/plugins/observability_ai_assistant/server/service/kb_service/kb_docs/lens.ts b/x-pack/plugins/observability_ai_assistant/server/service/kb_service/kb_docs/lens.ts index e4fdc8969c010..9baf75f6ff552 100644 --- a/x-pack/plugins/observability_ai_assistant/server/service/kb_service/kb_docs/lens.ts +++ b/x-pack/plugins/observability_ai_assistant/server/service/kb_service/kb_docs/lens.ts @@ -6,10 +6,16 @@ */ import dedent from 'dedent'; +import type { Logger } from '@kbn/logging'; import type { ObservabilityAIAssistantService } from '../..'; -export function addLensDocsToKb(service: ObservabilityAIAssistantService) { - service.addToKnowledgeBase([ +export function addLensDocsToKb({ + service, +}: { + service: ObservabilityAIAssistantService; + logger: Logger; +}) { + service.addCategoryToKnowledgeBase('lens', [ { id: 'lens_formulas_how_it_works', texts: [ diff --git a/x-pack/plugins/observability_ai_assistant/server/service/util/get_category_query.ts b/x-pack/plugins/observability_ai_assistant/server/service/util/get_category_query.ts new file mode 100644 index 0000000000000..71b0a93156086 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/server/service/util/get_category_query.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. + */ + +export function getCategoryQuery({ contexts }: { contexts?: string[] }) { + const noCategoryFilter = { + bool: { + must_not: { + exists: { + field: 'labels.category', + }, + }, + }, + }; + + if (!contexts) { + return [noCategoryFilter]; + } + + return [ + { + bool: { + should: [ + noCategoryFilter, + { + terms: { + 'labels.category': contexts, + }, + }, + ], + minimum_should_match: 1, + }, + }, + ]; +} diff --git a/x-pack/plugins/observability_shared/public/index.ts b/x-pack/plugins/observability_shared/public/index.ts index 7e5fc02d0a0b5..a35cdce8f85e1 100644 --- a/x-pack/plugins/observability_shared/public/index.ts +++ b/x-pack/plugins/observability_shared/public/index.ts @@ -10,6 +10,7 @@ export type { ObservabilitySharedPlugin, ObservabilitySharedPluginSetup, ObservabilitySharedPluginStart, + ProfilingLocators, } from './plugin'; export const plugin = () => { return new ObservabilitySharedPlugin(); diff --git a/x-pack/plugins/observability_shared/public/plugin.ts b/x-pack/plugins/observability_shared/public/plugin.ts index 550259184dfb1..faf8990622337 100644 --- a/x-pack/plugins/observability_shared/public/plugin.ts +++ b/x-pack/plugins/observability_shared/public/plugin.ts @@ -34,6 +34,7 @@ export interface ObservabilitySharedStart { export type ObservabilitySharedPluginSetup = ReturnType; export type ObservabilitySharedPluginStart = ReturnType; +export type ProfilingLocators = ObservabilitySharedPluginSetup['locators']['profiling']; export class ObservabilitySharedPlugin implements Plugin { private readonly navigationRegistry = createNavigationRegistry(); diff --git a/x-pack/plugins/osquery/public/components/empty_state.tsx b/x-pack/plugins/osquery/public/components/empty_state.tsx index 099e9e22b1f64..18f5afe8eaf5f 100644 --- a/x-pack/plugins/osquery/public/components/empty_state.tsx +++ b/x-pack/plugins/osquery/public/components/empty_state.tsx @@ -9,7 +9,7 @@ import React, { useCallback, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiButton } from '@elastic/eui'; -import { KibanaPageTemplate } from '@kbn/kibana-react-plugin/public'; +import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { INTEGRATIONS_PLUGIN_ID } from '@kbn/fleet-plugin/common'; import { pagePathGetters } from '@kbn/fleet-plugin/public'; import { isModifiedEvent, isLeftClickEvent, useKibana } from '../common/lib/kibana'; diff --git a/x-pack/plugins/osquery/tsconfig.json b/x-pack/plugins/osquery/tsconfig.json index 6cd1086b8a850..d2344a2581df8 100644 --- a/x-pack/plugins/osquery/tsconfig.json +++ b/x-pack/plugins/osquery/tsconfig.json @@ -77,5 +77,6 @@ "@kbn/core-saved-objects-server", "@kbn/monaco", "@kbn/io-ts-utils", + "@kbn/shared-ux-page-kibana-template", ] } diff --git a/x-pack/plugins/profiling/public/index.tsx b/x-pack/plugins/profiling/public/index.tsx index ea9dc15de9927..752635a54290b 100644 --- a/x-pack/plugins/profiling/public/index.tsx +++ b/x-pack/plugins/profiling/public/index.tsx @@ -13,5 +13,3 @@ export function plugin() { } export type { ProfilingPluginSetup, ProfilingPluginStart }; - -export type ProfilingLocators = ProfilingPluginSetup['locators']; diff --git a/x-pack/plugins/profiling_data_access/common/fleet_policies.ts b/x-pack/plugins/profiling_data_access/common/fleet_policies.ts index c3c489563b8ac..d3a9b51dd55d5 100644 --- a/x-pack/plugins/profiling_data_access/common/fleet_policies.ts +++ b/x-pack/plugins/profiling_data_access/common/fleet_policies.ts @@ -7,6 +7,7 @@ import { SavedObjectsClientContract } from '@kbn/core/server'; import type { PackagePolicyClient } from '@kbn/fleet-plugin/server'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE, PackagePolicy } from '@kbn/fleet-plugin/common'; import { getApmPolicy } from './get_apm_policy'; import { PartialSetupState, ProfilingSetupOptions } from './setup'; @@ -21,9 +22,11 @@ async function getPackagePolicy({ packagePolicyClient: PackagePolicyClient; soClient: SavedObjectsClientContract; packageName: string; -}) { - const packagePolicies = await packagePolicyClient.list(soClient, {}); - return packagePolicies.items.find((pkg) => pkg.name === packageName); +}): Promise { + const packagePolicies = await packagePolicyClient.list(soClient, { + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name:${packageName}`, + }); + return packagePolicies.items[0]; } export async function getCollectorPolicy({ diff --git a/x-pack/plugins/profiling_data_access/server/services/status/index.ts b/x-pack/plugins/profiling_data_access/server/services/status/index.ts index 6aea8b1037bd6..31581140b12e0 100644 --- a/x-pack/plugins/profiling_data_access/server/services/status/index.ts +++ b/x-pack/plugins/profiling_data_access/server/services/status/index.ts @@ -12,7 +12,7 @@ import { getSetupState } from '../get_setup_state'; import { RegisterServicesParams } from '../register_services'; import { ProfilingSetupOptions, areResourcesSetup } from '../../../common/setup'; -interface HasSetupParams { +export interface HasSetupParams { soClient: SavedObjectsClientContract; esClient: ElasticsearchClient; spaceId?: string; diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts b/x-pack/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts index 9bb7d32c19645..c99e7d77da830 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/model/warning_schema.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type WarningSchema = z.infer; diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.gen.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.gen.ts index 9f9abdf51dc4e..f68164f5bc12b 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.gen.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/get_prebuilt_rules_and_timelines_status/get_prebuilt_rules_and_timelines_status_route.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type GetPrebuiltRulesAndTimelinesStatusResponse = z.infer< @@ -20,30 +20,30 @@ export const GetPrebuiltRulesAndTimelinesStatusResponse = z /** * The total number of custom rules */ - rules_custom_installed: z.number().min(0), + rules_custom_installed: z.number().int().min(0), /** * The total number of installed prebuilt rules */ - rules_installed: z.number().min(0), + rules_installed: z.number().int().min(0), /** * The total number of available prebuilt rules that are not installed */ - rules_not_installed: z.number().min(0), + rules_not_installed: z.number().int().min(0), /** * The total number of outdated prebuilt rules */ - rules_not_updated: z.number().min(0), + rules_not_updated: z.number().int().min(0), /** * The total number of installed prebuilt timelines */ - timelines_installed: z.number().min(0), + timelines_installed: z.number().int().min(0), /** * The total number of available prebuilt timelines that are not installed */ - timelines_not_installed: z.number().min(0), + timelines_not_installed: z.number().int().min(0), /** * The total number of outdated prebuilt timelines */ - timelines_not_updated: z.number().min(0), + timelines_not_updated: z.number().int().min(0), }) .strict(); diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/audit_log.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/audit_log.gen.ts index a36476054dfdc..36a15ffc5f701 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/audit_log.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/audit_log.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { Page, PageSize, StartDate, EndDate, AgentId } from '../model/schema/common.gen'; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/details.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/details.gen.ts index b9557d98e87f9..546878e699cd9 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/details.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/details.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type DetailsRequestParams = z.infer; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/execute.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/execute.gen.ts index e1176c167fcf4..dbd24eef454d3 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/execute.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/execute.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { BaseActionSchema, Command, Timeout } from '../model/schema/common.gen'; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/file_download.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/file_download.gen.ts index 0b70a7676e069..945a03f0d38d2 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/file_download.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/file_download.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type FileDownloadRequestParams = z.infer; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/file_info.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/file_info.gen.ts index 1e4e7813d35b8..ef9a40462334e 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/file_info.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/file_info.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type FileInfoRequestParams = z.infer; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/file_upload.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/file_upload.gen.ts index af03b239d3913..785a4a1097e0c 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/file_upload.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/file_upload.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { BaseActionSchema } from '../model/schema/common.gen'; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/get_file.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/get_file.gen.ts index d8109d433fab4..648f1700a54ca 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/get_file.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/get_file.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { BaseActionSchema } from '../model/schema/common.gen'; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/actions/list.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/actions/list.gen.ts index f734092c22058..32844921170bd 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/actions/list.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/actions/list.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { @@ -31,7 +31,7 @@ export const ListRequestQuery = z.object({ /** * Number of items per page */ - pageSize: z.number().min(1).max(10000).optional().default(10), + pageSize: z.number().int().min(1).max(10000).optional().default(10), startDate: StartDate.optional(), endDate: EndDate.optional(), userIds: UserIds.optional(), diff --git a/x-pack/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts index fca1370559ada..d56463621d3c8 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/metadata/list_metadata.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type ListRequestQuery = z.infer; @@ -17,11 +17,11 @@ export const ListRequestQuery = z.object({ /** * Page number */ - page: z.number().min(0).optional().default(0), + page: z.number().int().min(0).optional().default(0), /** * Number of items per page */ - pageSize: z.number().min(1).max(10000).optional().default(10), + pageSize: z.number().int().min(1).max(10000).optional().default(10), kuery: z.string().nullable().optional(), sortField: z .enum([ diff --git a/x-pack/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts index 89f15504c4be5..2dffbc473ecc6 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ export type Id = z.infer; @@ -22,13 +22,13 @@ export const IdOrUndefined = Id.nullable(); * Page number */ export type Page = z.infer; -export const Page = z.number().min(1).default(1); +export const Page = z.number().int().min(1).default(1); /** * Number of items per page */ export type PageSize = z.infer; -export const PageSize = z.number().min(1).max(100).default(10); +export const PageSize = z.number().int().min(1).max(100).default(10); /** * Start date @@ -65,6 +65,8 @@ export const Command = z.enum([ 'execute', 'upload', ]); +export const CommandEnum = Command.enum; +export type CommandEnum = typeof Command.enum; export type Commands = z.infer; export const Commands = z.array(Command); @@ -73,10 +75,12 @@ export const Commands = z.array(Command); * The maximum timeout value in milliseconds (optional) */ export type Timeout = z.infer; -export const Timeout = z.number().min(1); +export const Timeout = z.number().int().min(1); export type Status = z.infer; export const Status = z.enum(['failed', 'pending', 'successful']); +export const StatusEnum = Status.enum; +export type StatusEnum = typeof Status.enum; export type Statuses = z.infer; export const Statuses = z.array(Status); @@ -95,6 +99,8 @@ export const WithOutputs = z.union([z.array(z.string().min(1)).min(1), z.string( export type Type = z.infer; export const Type = z.enum(['automated', 'manual']); +export const TypeEnum = Type.enum; +export type TypeEnum = typeof Type.enum; export type Types = z.infer; export const Types = z.array(Type); @@ -143,7 +149,7 @@ export const ProcessActionSchemas = BaseActionSchema.and( z.object({ parameters: z.union([ z.object({ - pid: z.number().min(1).optional(), + pid: z.number().int().min(1).optional(), }), z.object({ entity_id: z.string().min(1).optional(), diff --git a/x-pack/plugins/security_solution/common/api/endpoint/policy/policy.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/policy/policy.gen.ts index 3e511f7b4aad4..0b81cbdccd882 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/policy/policy.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/policy/policy.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { SuccessResponse, AgentId } from '../model/schema/common.gen'; diff --git a/x-pack/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts b/x-pack/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts index a827c94d3b5fd..c1bc91e6ded86 100644 --- a/x-pack/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts +++ b/x-pack/plugins/security_solution/common/api/endpoint/suggestions/get_suggestions.gen.ts @@ -9,7 +9,7 @@ import { z } from 'zod'; /* * NOTICE: Do not edit this file manually. - * This file is automatically generated by the OpenAPI Generator `yarn openapi:generate`. + * This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator. */ import { SuccessResponse } from '../model/schema/common.gen'; diff --git a/x-pack/plugins/security_solution/public/management/cypress/common/constants.ts b/x-pack/plugins/security_solution/public/management/cypress/common/constants.ts new file mode 100644 index 0000000000000..41f08f438e3f8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/cypress/common/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 { EndpointSecurityRoleNames } from '../../../../scripts/endpoint/common/roles_users'; + +export type KibanaKnownUserAccounts = keyof typeof KIBANA_KNOWN_DEFAULT_ACCOUNTS; + +export type SecurityTestUser = EndpointSecurityRoleNames | KibanaKnownUserAccounts; + +/** + * List of kibana system accounts + */ +export const KIBANA_KNOWN_DEFAULT_ACCOUNTS = { + elastic: 'elastic', + elastic_serverless: 'elastic_serverless', + system_indices_superuser: 'system_indices_superuser', +} as const; diff --git a/x-pack/plugins/security_solution/public/management/cypress/cypress.d.ts b/x-pack/plugins/security_solution/public/management/cypress/cypress.d.ts index 4d84dc88af9c9..a4037e32632a5 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/cypress.d.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/cypress.d.ts @@ -17,7 +17,12 @@ import type { HostPolicyResponse, LogsEndpointActionResponse, } from '../../../common/endpoint/types'; -import type { IndexEndpointHostsCyTaskOptions, HostActionResponse } from './types'; +import type { + HostActionResponse, + IndexEndpointHostsCyTaskOptions, + LoadUserAndRoleCyTaskOptions, + CreateUserAndRoleCyTaskOptions, +} from './types'; import type { DeleteIndexedFleetEndpointPoliciesResponse, IndexedFleetEndpointPolicyResponse, @@ -32,6 +37,7 @@ import type { DeletedIndexedEndpointRuleAlerts, IndexedEndpointRuleAlerts, } from '../../../common/endpoint/data_loaders/index_endpoint_rule_alerts'; +import type { LoadedRoleAndUser } from '../../../scripts/endpoint/common/role_and_user_loader'; declare global { namespace Cypress { @@ -185,6 +191,18 @@ declare global { arg: { hostname: string; path: string; password?: string }, options?: Partial ): Chainable; + + task( + name: 'loadUserAndRole', + arg: LoadUserAndRoleCyTaskOptions, + options?: Partial + ): Chainable; + + task( + name: 'createUserAndRole', + arg: CreateUserAndRoleCyTaskOptions, + options?: Partial + ): Chainable; } } } diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts index 39ebae1825365..8610ac1fc3ba5 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifact_tabs_in_policy_details.cy.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { getRoleWithArtifactReadPrivilege } from '../../fixtures/role_with_artifact_read_privilege'; import { getEndpointSecurityPolicyManager } from '../../../../../scripts/endpoint/common/roles_users/endpoint_security_policy_manager'; import { getArtifactsListTestsData } from '../../fixtures/artifacts_page'; import { visitPolicyDetailsPage } from '../../screens/policy_details'; @@ -16,27 +17,21 @@ import { yieldFirstPolicyID, } from '../../tasks/artifacts'; import { loadEndpointDataForEventFiltersIfNeeded } from '../../tasks/load_endpoint_data'; -import { - getRoleWithArtifactReadPrivilege, - login, - loginWithCustomRole, - loginWithRole, - ROLE, -} from '../../tasks/login'; +import { login, ROLE } from '../../tasks/login'; import { performUserActions } from '../../tasks/perform_user_actions'; const loginWithPrivilegeAll = () => { - loginWithRole(ROLE.endpoint_security_policy_manager); + login(ROLE.endpoint_policy_manager); }; const loginWithPrivilegeRead = (privilegePrefix: string) => { const roleWithArtifactReadPrivilege = getRoleWithArtifactReadPrivilege(privilegePrefix); - loginWithCustomRole('roleWithArtifactReadPrivilege', roleWithArtifactReadPrivilege); + login.withCustomRole({ name: 'roleWithArtifactReadPrivilege', ...roleWithArtifactReadPrivilege }); }; const loginWithPrivilegeNone = (privilegePrefix: string) => { const roleWithoutArtifactPrivilege = getRoleWithoutArtifactPrivilege(privilegePrefix); - loginWithCustomRole('roleWithoutArtifactPrivilege', roleWithoutArtifactPrivilege); + login.withCustomRole({ name: 'roleWithoutArtifactPrivilege', ...roleWithoutArtifactPrivilege }); }; const getRoleWithoutArtifactPrivilege = (privilegePrefix: string) => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts index 8f575282ad3f7..86cd86dd797b7 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/artifacts/artifacts_mocked_data.cy.ts @@ -5,13 +5,8 @@ * 2.0. */ -import { - getRoleWithArtifactReadPrivilege, - login, - loginWithCustomRole, - loginWithRole, - ROLE, -} from '../../tasks/login'; +import { getRoleWithArtifactReadPrivilege } from '../../fixtures/role_with_artifact_read_privilege'; +import { login, ROLE } from '../../tasks/login'; import { loadPage } from '../../tasks/common'; import { getArtifactsListTestsData } from '../../fixtures/artifacts_page'; @@ -20,18 +15,18 @@ import { performUserActions } from '../../tasks/perform_user_actions'; import { loadEndpointDataForEventFiltersIfNeeded } from '../../tasks/load_endpoint_data'; const loginWithWriteAccess = (url: string) => { - loginWithRole(ROLE.endpoint_security_policy_manager); + login(ROLE.endpoint_policy_manager); loadPage(url); }; const loginWithReadAccess = (privilegePrefix: string, url: string) => { const roleWithArtifactReadPrivilege = getRoleWithArtifactReadPrivilege(privilegePrefix); - loginWithCustomRole('roleWithArtifactReadPrivilege', roleWithArtifactReadPrivilege); + login.withCustomRole({ name: 'roleWithArtifactReadPrivilege', ...roleWithArtifactReadPrivilege }); loadPage(url); }; const loginWithoutAccess = (url: string) => { - loginWithRole(ROLE.t1_analyst); + login(ROLE.t1_analyst); loadPage(url); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts index 84f6903c35a9b..eb5bae8624475 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/form.cy.ts @@ -16,12 +16,12 @@ import { } from '../../tasks/response_actions'; import { cleanupRule, generateRandomStringName, loadRule } from '../../tasks/api_fixtures'; import { RESPONSE_ACTION_TYPES } from '../../../../../common/api/detection_engine'; -import { loginWithRole, ROLE } from '../../tasks/login'; +import { login, ROLE } from '../../tasks/login'; describe('Form', { tags: '@ess' }, () => { describe('User with no access can not create an endpoint response action', () => { before(() => { - loginWithRole(ROLE.endpoint_response_actions_no_access); + login(ROLE.endpoint_response_actions_no_access); }); it('no endpoint response action option during rule creation', () => { @@ -36,7 +36,7 @@ describe('Form', { tags: '@ess' }, () => { const [ruleName, ruleDescription] = generateRandomStringName(2); before(() => { - loginWithRole(ROLE.endpoint_response_actions_access); + login(ROLE.endpoint_response_actions_access); }); after(() => { cleanupRule(ruleId); @@ -94,7 +94,7 @@ describe('Form', { tags: '@ess' }, () => { }); }); beforeEach(() => { - loginWithRole(ROLE.endpoint_response_actions_access); + login(ROLE.endpoint_response_actions_access); }); after(() => { cleanupRule(ruleId); @@ -146,7 +146,7 @@ describe('Form', { tags: '@ess' }, () => { const [ruleName, ruleDescription] = generateRandomStringName(2); before(() => { - loginWithRole(ROLE.endpoint_response_actions_no_access); + login(ROLE.endpoint_response_actions_no_access); }); it('response actions are disabled', () => { @@ -166,7 +166,7 @@ describe('Form', { tags: '@ess' }, () => { loadRule().then((res) => { ruleId = res.id; }); - loginWithRole(ROLE.endpoint_response_actions_no_access); + login(ROLE.endpoint_response_actions_no_access); }); after(() => { cleanupRule(ruleId); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/no_license.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/no_license.cy.ts index edbaa90d3200c..eb6191ece0460 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/no_license.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/automated_response_actions/no_license.cy.ts @@ -9,7 +9,7 @@ import { disableExpandableFlyoutAdvancedSettings } from '../../tasks/common'; import { APP_ALERTS_PATH } from '../../../../../common/constants'; import { closeAllToasts } from '../../tasks/toasts'; import { fillUpNewRule } from '../../tasks/response_actions'; -import { login, loginWithRole, ROLE } from '../../tasks/login'; +import { login, ROLE } from '../../tasks/login'; import { generateRandomStringName } from '../../tasks/utils'; import type { ReturnTypeFromChainable } from '../../types'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; @@ -20,7 +20,7 @@ describe('No License', { tags: '@ess', env: { ftrConfig: { license: 'basic' } } const [ruleName, ruleDescription] = generateRandomStringName(2); before(() => { - loginWithRole(ROLE.endpoint_response_actions_access); + login(ROLE.endpoint_response_actions_access); }); it('response actions are disabled', () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/endpoint_list_with_security_essentials.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/endpoint_list_with_security_essentials.cy.ts index 58c41539361c5..32800978a968e 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/endpoint_list_with_security_essentials.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/endpoint_list_with_security_essentials.cy.ts @@ -7,7 +7,7 @@ import type { CyIndexEndpointHosts } from '../../tasks/index_endpoint_hosts'; import { indexEndpointHosts } from '../../tasks/index_endpoint_hosts'; -import { loginServerless } from '../../tasks/login_serverless'; +import { login } from '../../tasks/login'; import { getConsoleActionMenuItem, getUnIsolateActionMenuItem, @@ -42,7 +42,7 @@ describe( }); beforeEach(() => { - loginServerless(); + login(); visitEndpointList(); openRowActionMenu(); }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete.cy.ts index 7c4323b2aa689..dba7166b9a9e8 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete.cy.ts @@ -6,7 +6,7 @@ */ import { ensureResponseActionAuthzAccess } from '../../../tasks/response_actions'; -import { loginServerless, ServerlessUser } from '../../../tasks/login_serverless'; +import { login, ROLE } from '../../../tasks/login'; import { RESPONSE_ACTION_API_COMMANDS_NAMES } from '../../../../../../common/endpoint/service/response_actions/constants'; import { getNoPrivilegesPage } from '../../../screens/common'; import { getEndpointManagementPageList } from '../../../screens'; @@ -31,7 +31,7 @@ describe( let password: string; beforeEach(() => { - loginServerless(ServerlessUser.ENDPOINT_OPERATIONS_ANALYST).then((response) => { + login(ROLE.endpoint_operations_analyst).then((response) => { username = response.username; password = response.password; }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete_with_endpoint.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete_with_endpoint.cy.ts index f3ae8b85a9f24..3c028b9e25040 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete_with_endpoint.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/complete_with_endpoint.cy.ts @@ -6,7 +6,7 @@ */ import { ensureResponseActionAuthzAccess } from '../../../tasks/response_actions'; -import { loginServerless, ServerlessUser } from '../../../tasks/login_serverless'; +import { login, ROLE } from '../../../tasks/login'; import { RESPONSE_ACTION_API_COMMANDS_NAMES } from '../../../../../../common/endpoint/service/response_actions/constants'; import { getEndpointManagementPageList, @@ -33,7 +33,7 @@ describe( let password: string; beforeEach(() => { - loginServerless(ServerlessUser.ENDPOINT_OPERATIONS_ANALYST).then((response) => { + login(ROLE.endpoint_operations_analyst).then((response) => { username = response.username; password = response.password; }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials.cy.ts index 900a5d81a9f46..fed4494722df5 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials.cy.ts @@ -6,7 +6,7 @@ */ import { ensureResponseActionAuthzAccess } from '../../../tasks/response_actions'; -import { loginServerless, ServerlessUser } from '../../../tasks/login_serverless'; +import { login, ROLE } from '../../../tasks/login'; import { RESPONSE_ACTION_API_COMMANDS_NAMES } from '../../../../../../common/endpoint/service/response_actions/constants'; import { getNoPrivilegesPage } from '../../../screens/common'; import { getEndpointManagementPageList } from '../../../screens'; @@ -33,7 +33,7 @@ describe( let password: string; beforeEach(() => { - loginServerless(ServerlessUser.ENDPOINT_OPERATIONS_ANALYST).then((response) => { + login(ROLE.endpoint_operations_analyst).then((response) => { username = response.username; password = response.password; }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials_with_endpoint.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials_with_endpoint.cy.ts index 7196b73f6813a..172f850e44b7c 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials_with_endpoint.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/feature_access/essentials_with_endpoint.cy.ts @@ -6,7 +6,7 @@ */ import { ensureResponseActionAuthzAccess } from '../../../tasks/response_actions'; -import { loginServerless, ServerlessUser } from '../../../tasks/login_serverless'; +import { login, ROLE } from '../../../tasks/login'; import { RESPONSE_ACTION_API_COMMANDS_NAMES } from '../../../../../../common/endpoint/service/response_actions/constants'; import { getEndpointManagementPageMap, @@ -41,7 +41,7 @@ describe( let password: string; beforeEach(() => { - loginServerless(ServerlessUser.ENDPOINT_OPERATIONS_ANALYST).then((response) => { + login(ROLE.endpoint_operations_analyst).then((response) => { username = response.username; password = response.password; }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/policy_details_with_security_essentials.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/policy_details_with_security_essentials.cy.ts index faf9aba6237b3..e1516bb08e10e 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/policy_details_with_security_essentials.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/policy_details_with_security_essentials.cy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { loginServerless } from '../../tasks/login_serverless'; +import { login } from '../../tasks/login'; import { visitPolicyDetailsPage } from '../../screens/policy_details'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; @@ -35,7 +35,7 @@ describe( }); beforeEach(() => { - loginServerless(); + login(); visitPolicyDetailsPage(loadedPolicyData.integrationPolicies[0].id); }); diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/complete_with_endpoint_roles.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/complete_with_endpoint_roles.cy.ts index 879948a65c47d..534b681c2aeb4 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/complete_with_endpoint_roles.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/complete_with_endpoint_roles.cy.ts @@ -8,7 +8,7 @@ import { pick } from 'lodash'; import type { CyIndexEndpointHosts } from '../../../tasks/index_endpoint_hosts'; import { indexEndpointHosts } from '../../../tasks/index_endpoint_hosts'; -import { loginServerless, ServerlessUser } from '../../../tasks/login_serverless'; +import { login, ROLE } from '../../../tasks/login'; import { ensurePolicyDetailsPageAuthzAccess } from '../../../screens/policy_details'; import type { EndpointArtifactPageId } from '../../../screens'; import { @@ -63,12 +63,12 @@ describe( }); // roles `t1_analyst` and `t2_analyst` are very similar with exception of one page - (['t1_analyst', `t2_analyst`] as ServerlessUser[]).forEach((roleName) => { + (['t1_analyst', `t2_analyst`] as ROLE[]).forEach((roleName) => { describe(`for role: ${roleName}`, () => { const deniedPages = allPages.filter((page) => page.id !== 'endpointList'); beforeEach(() => { - loginServerless(roleName); + login(roleName); }); it('should have READ access to Endpoint list page', () => { @@ -124,7 +124,7 @@ describe( const deniedResponseActions = pick(consoleHelpPanelResponseActionsTestSubj, 'execute'); beforeEach(() => { - loginServerless(ServerlessUser.T3_ANALYST); + login(ROLE.t3_analyst); }); it('should have access to Endpoint list page', () => { @@ -176,7 +176,7 @@ describe( const deniedPages = allPages.filter(({ id }) => id !== 'blocklist' && id !== 'endpointList'); beforeEach(() => { - loginServerless(ServerlessUser.THREAT_INTELLIGENCE_ANALYST); + login(ROLE.threat_intelligence_analyst); }); it('should have access to Endpoint list page', () => { @@ -221,7 +221,7 @@ describe( ]; beforeEach(() => { - loginServerless(ServerlessUser.RULE_AUTHOR); + login(ROLE.rule_author); }); for (const { id, title } of artifactPagesFullAccess) { @@ -272,7 +272,7 @@ describe( const grantedAccessPages = [pageById.endpointList, pageById.policyList]; beforeEach(() => { - loginServerless(ServerlessUser.SOC_MANAGER); + login(ROLE.soc_manager); }); for (const { id, title } of artifactPagesFullAccess) { @@ -319,7 +319,7 @@ describe( const grantedAccessPages = [pageById.endpointList, pageById.policyList]; beforeEach(() => { - loginServerless(ServerlessUser.ENDPOINT_OPERATIONS_ANALYST); + login(ROLE.endpoint_operations_analyst); }); for (const { id, title } of artifactPagesFullAccess) { @@ -350,7 +350,7 @@ describe( }); }); - (['platform_engineer', 'endpoint_policy_manager'] as ServerlessUser[]).forEach((roleName) => { + (['platform_engineer', 'endpoint_policy_manager'] as ROLE[]).forEach((roleName) => { describe(`for role: ${roleName}`, () => { const artifactPagesFullAccess = [ pageById.trustedApps, @@ -361,7 +361,7 @@ describe( const grantedAccessPages = [pageById.endpointList, pageById.policyList]; beforeEach(() => { - loginServerless(roleName); + login(roleName); }); for (const { id, title } of artifactPagesFullAccess) { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/essentials_with_endpoint.roles.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/essentials_with_endpoint.roles.cy.ts index fec6a0f803afb..6cf3ab727980a 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/essentials_with_endpoint.roles.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/serverless/roles/essentials_with_endpoint.roles.cy.ts @@ -7,7 +7,7 @@ import type { CyIndexEndpointHosts } from '../../../tasks/index_endpoint_hosts'; import { indexEndpointHosts } from '../../../tasks/index_endpoint_hosts'; -import { loginServerless, ServerlessUser } from '../../../tasks/login_serverless'; +import { login, ROLE } from '../../../tasks/login'; import type { EndpointArtifactPageId } from '../../../screens'; import { getNoPrivilegesPage, @@ -55,12 +55,12 @@ describe( }); // roles `t1_analyst` and `t2_analyst` are the same as far as endpoint access - (['t1_analyst', `t2_analyst`] as ServerlessUser[]).forEach((roleName) => { + (['t1_analyst', `t2_analyst`] as ROLE[]).forEach((roleName) => { describe(`for role: ${roleName}`, () => { const deniedPages = allPages.filter((page) => page.id !== 'endpointList'); beforeEach(() => { - loginServerless(roleName); + login(roleName); }); it('should have READ access to Endpoint list page', () => { @@ -89,7 +89,7 @@ describe( ]; beforeEach(() => { - loginServerless(ServerlessUser.T3_ANALYST); + login(ROLE.t3_analyst); }); it('should have access to Endpoint list page', () => { @@ -128,7 +128,7 @@ describe( const deniedPages = allPages.filter(({ id }) => id !== 'blocklist' && id !== 'endpointList'); beforeEach(() => { - loginServerless(ServerlessUser.THREAT_INTELLIGENCE_ANALYST); + login(ROLE.threat_intelligence_analyst); }); it('should have access to Endpoint list page', () => { @@ -163,7 +163,7 @@ describe( ]; beforeEach(() => { - loginServerless(ServerlessUser.RULE_AUTHOR); + login(ROLE.rule_author); }); for (const { id, title } of artifactPagesFullAccess) { @@ -207,7 +207,7 @@ describe( const grantedAccessPages = [pageById.endpointList, pageById.policyList]; beforeEach(() => { - loginServerless(ServerlessUser.SOC_MANAGER); + login(ROLE.soc_manager); }); for (const { id, title } of artifactPagesFullAccess) { @@ -238,11 +238,7 @@ describe( // Endpoint Operations Manager, Endpoint Policy Manager and Platform Engineer currently have the same level of access ( - [ - 'platform_engineer', - `endpoint_operations_analyst`, - 'endpoint_policy_manager', - ] as ServerlessUser[] + ['platform_engineer', `endpoint_operations_analyst`, 'endpoint_policy_manager'] as ROLE[] ).forEach((roleName) => { describe(`for role: ${roleName}`, () => { const artifactPagesFullAccess = [ @@ -253,7 +249,7 @@ describe( const grantedAccessPages = [pageById.endpointList, pageById.policyList]; beforeEach(() => { - loginServerless(roleName); + login(roleName); }); for (const { id, title } of artifactPagesFullAccess) { diff --git a/x-pack/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts b/x-pack/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts new file mode 100644 index 0000000000000..247b491f04632 --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/cypress/fixtures/role_with_artifact_read_privilege.ts @@ -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 { getEndpointSecurityPolicyManager } from '../../../../scripts/endpoint/common/roles_users'; + +export const getRoleWithArtifactReadPrivilege = (privilegePrefix: string) => { + const endpointSecurityPolicyManagerRole = getEndpointSecurityPolicyManager(); + + return { + ...endpointSecurityPolicyManagerRole, + kibana: [ + { + ...endpointSecurityPolicyManagerRole.kibana[0], + feature: { + ...endpointSecurityPolicyManagerRole.kibana[0].feature, + siem: [ + ...endpointSecurityPolicyManagerRole.kibana[0].feature.siem.filter( + (privilege) => privilege !== `${privilegePrefix}all` + ), + `${privilegePrefix}read`, + ], + }, + }, + ], + }; +}; diff --git a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts index 4d8164391cb11..93614b6dbb86d 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/support/data_loaders.ts @@ -9,6 +9,14 @@ import type { CasePostRequest } from '@kbn/cases-plugin/common'; import execa from 'execa'; +import type { KbnClient } from '@kbn/test'; +import type { ToolingLog } from '@kbn/tooling-log'; +import type { KibanaKnownUserAccounts } from '../common/constants'; +import { KIBANA_KNOWN_DEFAULT_ACCOUNTS } from '../common/constants'; +import type { EndpointSecurityRoleNames } from '../../../../scripts/endpoint/common/roles_users'; +import { SECURITY_SERVERLESS_ROLE_NAMES } from '../../../../scripts/endpoint/common/roles_users'; +import type { LoadedRoleAndUser } from '../../../../scripts/endpoint/common/role_and_user_loader'; +import { EndpointSecurityTestRolesLoader } from '../../../../scripts/endpoint/common/role_and_user_loader'; import { startRuntimeServices } from '../../../../scripts/endpoint/endpoint_agent_runner/runtime'; import { runFleetServerIfNeeded } from '../../../../scripts/endpoint/endpoint_agent_runner/fleet_server'; import { @@ -22,39 +30,89 @@ import type { CreateAndEnrollEndpointHostOptions, CreateAndEnrollEndpointHostResponse, } from '../../../../scripts/endpoint/common/endpoint_host_services'; +import { + createAndEnrollEndpointHost, + destroyEndpointHost, + startEndpointHost, + stopEndpointHost, + VAGRANT_CWD, +} from '../../../../scripts/endpoint/common/endpoint_host_services'; import type { IndexedEndpointPolicyResponse } from '../../../../common/endpoint/data_loaders/index_endpoint_policy_response'; import { deleteIndexedEndpointPolicyResponse, indexEndpointPolicyResponse, } from '../../../../common/endpoint/data_loaders/index_endpoint_policy_response'; import type { ActionDetails, HostPolicyResponse } from '../../../../common/endpoint/types'; -import type { IndexEndpointHostsCyTaskOptions } from '../types'; import type { - IndexedEndpointRuleAlerts, + IndexEndpointHostsCyTaskOptions, + LoadUserAndRoleCyTaskOptions, + CreateUserAndRoleCyTaskOptions, +} from '../types'; +import type { DeletedIndexedEndpointRuleAlerts, + IndexedEndpointRuleAlerts, +} from '../../../../common/endpoint/data_loaders/index_endpoint_rule_alerts'; +import { + deleteIndexedEndpointRuleAlerts, + indexEndpointRuleAlerts, } from '../../../../common/endpoint/data_loaders/index_endpoint_rule_alerts'; import type { IndexedHostsAndAlertsResponse } from '../../../../common/endpoint/index_data'; +import { deleteIndexedHostsAndAlerts } from '../../../../common/endpoint/index_data'; import type { IndexedCase } from '../../../../common/endpoint/data_loaders/index_case'; +import { deleteIndexedCase, indexCase } from '../../../../common/endpoint/data_loaders/index_case'; import { createRuntimeServices } from '../../../../scripts/endpoint/common/stack_services'; import type { IndexedFleetEndpointPolicyResponse } from '../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; import { - indexFleetEndpointPolicy, deleteIndexedFleetEndpointPolicies, + indexFleetEndpointPolicy, } from '../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; -import { deleteIndexedCase, indexCase } from '../../../../common/endpoint/data_loaders/index_case'; import { cyLoadEndpointDataHandler } from './plugin_handlers/endpoint_data_loader'; -import { deleteIndexedHostsAndAlerts } from '../../../../common/endpoint/index_data'; -import { - deleteIndexedEndpointRuleAlerts, - indexEndpointRuleAlerts, -} from '../../../../common/endpoint/data_loaders/index_endpoint_rule_alerts'; -import { - startEndpointHost, - createAndEnrollEndpointHost, - destroyEndpointHost, - stopEndpointHost, - VAGRANT_CWD, -} from '../../../../scripts/endpoint/common/endpoint_host_services'; + +/** + * Test Role/User loader for cypress. Checks to see if running in serverless and handles it as appropriate + */ +class TestRoleAndUserLoader extends EndpointSecurityTestRolesLoader { + constructor( + protected readonly kbnClient: KbnClient, + protected readonly logger: ToolingLog, + private readonly isServerless: boolean + ) { + super(kbnClient, logger); + } + + async load( + name: EndpointSecurityRoleNames | KibanaKnownUserAccounts + ): Promise { + // If its a known system account, then just exit here and use the default `changeme` password + if (KIBANA_KNOWN_DEFAULT_ACCOUNTS[name as KibanaKnownUserAccounts]) { + return { + role: name, + username: name, + password: 'changeme', + }; + } + + if (this.isServerless) { + // If the username is not one that we support in serverless, then throw an error. + if (!SECURITY_SERVERLESS_ROLE_NAMES[name as keyof typeof SECURITY_SERVERLESS_ROLE_NAMES]) { + throw new Error( + `username [${name}] is not valid when running in serverless. Valid values are: ${Object.keys( + SECURITY_SERVERLESS_ROLE_NAMES + ).join(', ')}` + ); + } + + // Roles/users for serverless will be already present in the env, so just return the defaults creds + return { + role: name, + username: name, + password: 'changeme', + }; + } + + return super.load(name as EndpointSecurityRoleNames); + } +} /** * Cypress plugin for adding data loading related `task`s @@ -68,7 +126,8 @@ export const dataLoaders = ( on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions ): void => { - // FIXME: investigate if we can create a `ToolingLog` that writes output to cypress and pass that to the stack services + // Env. variable is set by `cypress_serverless.config.ts` + const isServerless = config.env.IS_SERVERLESS; const stackServicesPromise = createRuntimeServices({ kibanaUrl: config.env.KIBANA_URL, @@ -81,6 +140,12 @@ export const dataLoaders = ( asSuperuser: true, }); + const roleAndUserLoaderPromise: Promise = stackServicesPromise.then( + ({ kbnClient, log }) => { + return new TestRoleAndUserLoader(kbnClient, log, isServerless); + } + ); + on('task', { indexFleetEndpointPolicy: async ({ policyName, @@ -201,6 +266,23 @@ export const dataLoaders = ( const { esClient } = await stackServicesPromise; return deleteAllEndpointData(esClient, endpointAgentIds); }, + + /** + * Loads a user/role into Kibana. Used from `login()` task. + * @param name + */ + loadUserAndRole: async ({ name }: LoadUserAndRoleCyTaskOptions): Promise => { + return (await roleAndUserLoaderPromise).load(name); + }, + + /** + * Creates a new Role/User + */ + createUserAndRole: async ({ + role, + }: CreateUserAndRoleCyTaskOptions): Promise => { + return (await roleAndUserLoaderPromise).create(role); + }, }); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts index 58eba62a72f82..8ac78b508d084 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/login.ts @@ -5,242 +5,107 @@ * 2.0. */ -import * as yaml from 'js-yaml'; -import type { Role } from '@kbn/security-plugin/common'; import type { LoginState } from '@kbn/security-plugin/common/login_state'; -import { getWithResponseActionsRole } from '../../../../scripts/endpoint/common/roles_users/with_response_actions_role'; -import { getNoResponseActionsRole } from '../../../../scripts/endpoint/common/roles_users/without_response_actions_role'; -import { request } from './common'; -import { getT1Analyst } from '../../../../scripts/endpoint/common/roles_users/t1_analyst'; -import { getT2Analyst } from '../../../../scripts/endpoint/common/roles_users/t2_analyst'; -import { getHunter } from '../../../../scripts/endpoint/common/roles_users/hunter'; -import { getThreatIntelligenceAnalyst } from '../../../../scripts/endpoint/common/roles_users/threat_intelligence_analyst'; -import { getSocManager } from '../../../../scripts/endpoint/common/roles_users/soc_manager'; -import { getPlatformEngineer } from '../../../../scripts/endpoint/common/roles_users/platform_engineer'; -import { getEndpointOperationsAnalyst } from '../../../../scripts/endpoint/common/roles_users/endpoint_operations_analyst'; -import { - getEndpointSecurityPolicyManagementReadRole, - getEndpointSecurityPolicyManager, -} from '../../../../scripts/endpoint/common/roles_users/endpoint_security_policy_manager'; -import { getDetectionsEngineer } from '../../../../scripts/endpoint/common/roles_users/detections_engineer'; - -export enum ROLE { - t1_analyst = 't1Analyst', - t2_analyst = 't2Analyst', - analyst_hunter = 'hunter', - threat_intelligence_analyst = 'threatIntelligenceAnalyst', - detections_engineer = 'detectionsEngineer', - soc_manager = 'socManager', - platform_engineer = 'platformEngineer', - endpoint_operations_analyst = 'endpointOperationsAnalyst', - endpoint_security_policy_manager = 'endpointSecurityPolicyManager', - endpoint_response_actions_access = 'endpointResponseActionsAccess', - endpoint_response_actions_no_access = 'endpointResponseActionsNoAccess', - endpoint_security_policy_management_read = 'endpointSecurityPolicyManagementRead', +import type { Role } from '@kbn/security-plugin/common'; +import { ENDPOINT_SECURITY_ROLE_NAMES } from '../../../../scripts/endpoint/common/roles_users'; +import type { SecurityTestUser } from '../common/constants'; +import { COMMON_API_HEADERS, request } from './common'; + +export const ROLE = Object.freeze>({ + ...ENDPOINT_SECURITY_ROLE_NAMES, + elastic: 'elastic', + elastic_serverless: 'elastic_serverless', + system_indices_superuser: 'system_indices_superuser', +}); + +interface CyLoginTask { + (user?: SecurityTestUser): ReturnType; + + /** + * Login using any username/password + * @param username + * @param password + */ + with(username: string, password: string): ReturnType; + + /** + * Creates the provided role in kibana/ES along with a respective user (same name as role) + * and then login with this new user + * @param role + */ + withCustomRole(role: Role): ReturnType; } -export const rolesMapping: { [key in ROLE]: Omit } = { - t1Analyst: getT1Analyst(), - t2Analyst: getT2Analyst(), - hunter: getHunter(), - threatIntelligenceAnalyst: getThreatIntelligenceAnalyst(), - socManager: getSocManager(), - platformEngineer: getPlatformEngineer(), - endpointOperationsAnalyst: getEndpointOperationsAnalyst(), - endpointSecurityPolicyManager: getEndpointSecurityPolicyManager(), - detectionsEngineer: getDetectionsEngineer(), - endpointResponseActionsAccess: getWithResponseActionsRole(), - endpointResponseActionsNoAccess: getNoResponseActionsRole(), - endpointSecurityPolicyManagementRead: getEndpointSecurityPolicyManagementReadRole(), -}; -/** - * Credentials in the `kibana.dev.yml` config file will be used to authenticate - * with Kibana when credentials are not provided via environment variables - */ -const KIBANA_DEV_YML_PATH = '../../../config/kibana.dev.yml'; - -/** - * The configuration path in `kibana.dev.yml` to the username to be used when - * authenticating with Kibana. - */ -const ELASTICSEARCH_USERNAME_CONFIG_PATH = 'config.elasticsearch.username'; - -/** - * The configuration path in `kibana.dev.yml` to the password to be used when - * authenticating with Kibana. - */ -const ELASTICSEARCH_PASSWORD_CONFIG_PATH = 'config.elasticsearch.password'; - -/** - * The `CYPRESS_ELASTICSEARCH_USERNAME` environment variable specifies the - * username to be used when authenticating with Kibana - */ -const ELASTICSEARCH_USERNAME = 'ELASTICSEARCH_USERNAME'; - /** - * The `CYPRESS_ELASTICSEARCH_PASSWORD` environment variable specifies the - * username to be used when authenticating with Kibana + * Login to Kibana using API (not login page). + * By default, user will be logged in using `KIBANA_USERNAME` and `KIBANA_PASSWORD` retrieved from + * the cypress `env` + * + * @param user */ -const ELASTICSEARCH_PASSWORD = 'ELASTICSEARCH_PASSWORD'; - -const KIBANA_USERNAME = 'KIBANA_USERNAME'; -const KIBANA_PASSWORD = 'KIBANA_PASSWORD'; +export const login: CyLoginTask = ( + // FIXME:PT default user to `soc_manager` + user?: SecurityTestUser +): ReturnType => { + let username = Cypress.env('KIBANA_USERNAME'); + let password = Cypress.env('KIBANA_PASSWORD'); + + if (user) { + return cy.task('loadUserAndRole', { name: user }).then((loadedUser) => { + username = loadedUser.username; + password = loadedUser.password; + + return sendApiLoginRequest(username, password); + }); + } else { + return sendApiLoginRequest(username, password); + } +}; -export const createCustomRoleAndUser = (role: string, rolePrivileges: Omit) => { - // post the role - request({ - method: 'PUT', - url: `/api/security/role/${role}`, - body: rolePrivileges, - }); +login.with = (username: string, password: string): ReturnType => { + return sendApiLoginRequest(username, password); +}; - // post the user associated with the role to elasticsearch - request({ - method: 'POST', - url: `/internal/security/users/${role}`, - body: { - username: role, - password: Cypress.env(ELASTICSEARCH_PASSWORD), - roles: [role], - }, +login.withCustomRole = (role: Role): ReturnType => { + return cy.task('createUserAndRole', { role }).then(({ username, password }) => { + return sendApiLoginRequest(username, password); }); }; -const loginWithUsernameAndPassword = (username: string, password: string) => { +/** + * Send login via API + * @param username + * @param password + * + * @private + */ +const sendApiLoginRequest = ( + username: string, + password: string +): Cypress.Chainable<{ username: string; password: string }> => { const baseUrl = Cypress.config().baseUrl; - if (!baseUrl) { - throw Error(`Cypress config baseUrl not set!`); - } + const loginUrl = `${baseUrl}/internal/security/login`; + const headers = { ...COMMON_API_HEADERS }; + + cy.log(`Authenticating [${username}] via ${loginUrl}`); - // Programmatically authenticate without interacting with the Kibana login page. - const headers = { 'kbn-xsrf': 'cypress-creds' }; - request({ headers, url: `${baseUrl}/internal/security/login_state` }).then( - (loginState) => { + return request({ headers, url: `${baseUrl}/internal/security/login_state` }) + .then((loginState) => { const basicProvider = loginState.body.selector.providers.find( (provider) => provider.type === 'basic' ); + return request({ - url: `${baseUrl}/internal/security/login`, + url: loginUrl, method: 'POST', headers, body: { - providerType: basicProvider.type, - providerName: basicProvider.name, + providerType: basicProvider?.type, + providerName: basicProvider?.name, currentURL: '/', params: { username, password }, }, }); - } - ); -}; - -export const loginWithRole = (role: ROLE) => { - loginWithCustomRole(role, rolesMapping[role]); -}; - -export const loginWithCustomRole = (role: string, rolePrivileges: Omit) => { - createCustomRoleAndUser(role, rolePrivileges); - - cy.log(`origin: ${Cypress.config().baseUrl}`); - - loginWithUsernameAndPassword(role, Cypress.env(ELASTICSEARCH_PASSWORD)); -}; - -/** - * Authenticates with Kibana using, if specified, credentials specified by - * environment variables. The credentials in `kibana.dev.yml` will be used - * for authentication when the environment variables are unset. - * - * To speed the execution of tests, prefer this non-interactive authentication, - * which is faster than authentication via Kibana's interactive login page. - */ -export const login = (role?: ROLE) => { - if (role != null) { - loginWithRole(role); - } else if (credentialsProvidedByEnvironment()) { - loginViaEnvironmentCredentials(); - } else { - loginViaConfig(); - } -}; - -/** - * Returns `true` if the credentials used to login to Kibana are provided - * via environment variables - */ -const credentialsProvidedByEnvironment = (): boolean => - (Cypress.env(KIBANA_USERNAME) != null && Cypress.env(KIBANA_PASSWORD) != null) || - (Cypress.env(ELASTICSEARCH_USERNAME) != null && Cypress.env(ELASTICSEARCH_PASSWORD) != null); - -/** - * Authenticates with Kibana by reading credentials from the - * `CYPRESS_ELASTICSEARCH_USERNAME` and `CYPRESS_ELASTICSEARCH_PASSWORD` - * environment variables, and POSTing the username and password directly to - * Kibana's `/internal/security/login` endpoint, bypassing the login page (for speed). - */ -const loginViaEnvironmentCredentials = () => { - let username: string; - let password: string; - let usernameEnvVar: string; - let passwordEnvVar: string; - - if (Cypress.env(KIBANA_USERNAME) && Cypress.env(KIBANA_PASSWORD)) { - username = Cypress.env(KIBANA_USERNAME); - password = Cypress.env(KIBANA_PASSWORD); - usernameEnvVar = KIBANA_USERNAME; - passwordEnvVar = KIBANA_PASSWORD; - } else { - username = Cypress.env(ELASTICSEARCH_USERNAME); - password = Cypress.env(ELASTICSEARCH_PASSWORD); - usernameEnvVar = ELASTICSEARCH_USERNAME; - passwordEnvVar = ELASTICSEARCH_PASSWORD; - } - - cy.log( - `Authenticating user [${username}] retrieved via environment credentials from the \`CYPRESS_${usernameEnvVar}\` and \`CYPRESS_${passwordEnvVar}\` environment variables` - ); - - loginWithUsernameAndPassword(username, password); -}; - -/** - * Authenticates with Kibana by reading credentials from the - * `kibana.dev.yml` file and POSTing the username and password directly to - * Kibana's `/internal/security/login` endpoint, bypassing the login page (for speed). - */ -const loginViaConfig = () => { - cy.log( - `Authenticating via config credentials \`${ELASTICSEARCH_USERNAME_CONFIG_PATH}\` and \`${ELASTICSEARCH_PASSWORD_CONFIG_PATH}\` from \`${KIBANA_DEV_YML_PATH}\`` - ); - - // read the login details from `kibana.dev.yaml` - cy.readFile(KIBANA_DEV_YML_PATH).then((kibanaDevYml) => { - const config = yaml.safeLoad(kibanaDevYml); - loginWithUsernameAndPassword( - Cypress.env(ELASTICSEARCH_USERNAME), - config.elasticsearch.password - ); - }); -}; - -export const getRoleWithArtifactReadPrivilege = (privilegePrefix: string) => { - const endpointSecurityPolicyManagerRole = getEndpointSecurityPolicyManager(); - - return { - ...endpointSecurityPolicyManagerRole, - kibana: [ - { - ...endpointSecurityPolicyManagerRole.kibana[0], - feature: { - ...endpointSecurityPolicyManagerRole.kibana[0].feature, - siem: [ - ...endpointSecurityPolicyManagerRole.kibana[0].feature.siem.filter( - (privilege) => privilege !== `${privilegePrefix}all` - ), - `${privilegePrefix}read`, - ], - }, - }, - ], - }; + }) + .then(() => ({ username, password })); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/login_serverless.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/login_serverless.ts deleted file mode 100644 index 533a17663e16b..0000000000000 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/login_serverless.ts +++ /dev/null @@ -1,103 +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 { LoginState } from '@kbn/security-plugin/common/login_state'; -import { COMMON_API_HEADERS, request } from './common'; - -export enum ServerlessUser { - T1_ANALYST = 't1_analyst', - T2_ANALYST = 't2_analyst', - T3_ANALYST = 't3_analyst', - THREAT_INTELLIGENCE_ANALYST = 'threat_intelligence_analyst', - RULE_AUTHOR = 'rule_author', - SOC_MANAGER = 'soc_manager', - DETECTIONS_ADMIN = 'detections_admin', - PLATFORM_ENGINEER = 'platform_engineer', - ENDPOINT_OPERATIONS_ANALYST = 'endpoint_operations_analyst', - ENDPOINT_POLICY_MANAGER = 'endpoint_policy_manager', -} - -/** - * Send login via API - * @param username - * @param password - * - * @private - */ -const sendApiLoginRequest = ( - username: string, - password: string -): Cypress.Chainable<{ username: string; password: string }> => { - const baseUrl = Cypress.config().baseUrl; - const headers = { ...COMMON_API_HEADERS }; - - cy.log(`Authenticating [${username}] via ${baseUrl}`); - - return request({ headers, url: `${baseUrl}/internal/security/login_state` }) - .then((loginState) => { - const basicProvider = loginState.body.selector.providers.find( - (provider) => provider.type === 'basic' - ); - - return request({ - url: `${baseUrl}/internal/security/login`, - method: 'POST', - headers, - body: { - providerType: basicProvider?.type, - providerName: basicProvider?.name, - currentURL: '/', - params: { username, password }, - }, - }); - }) - .then(() => ({ username, password })); -}; - -interface CyLoginTask { - (user?: ServerlessUser | 'elastic'): ReturnType; - - /** - * Login using any username/password - * @param username - * @param password - */ - with(username: string, password: string): ReturnType; -} - -/** - * Login to Kibana using API (not login page). By default, user will be logged in using - * the username and password defined via `KIBANA_USERNAME` and `KIBANA_PASSWORD` cypress env - * variables. - * @param user Defaults to `soc_manager` - */ -export const loginServerless: CyLoginTask = ( - user: ServerlessUser | 'elastic' = ServerlessUser.SOC_MANAGER -): ReturnType => { - const username = Cypress.env('KIBANA_USERNAME'); - const password = Cypress.env('KIBANA_PASSWORD'); - - if (user && user !== 'elastic') { - throw new Error('Serverless usernames not yet implemented'); - - // return cy.task('loadUserAndRole', { name: user }).then((loadedUser) => { - // username = loadedUser.username; - // password = loadedUser.password; - // - // return sendApiLoginRequest(username, password); - // }); - } else { - return sendApiLoginRequest(username, password); - } -}; - -loginServerless.with = ( - username: string, - password: string -): ReturnType => { - return sendApiLoginRequest(username, password); -}; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json b/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json index 4d7fe47ec2d23..94d50ffe7f62a 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json +++ b/x-pack/plugins/security_solution/public/management/cypress/tsconfig.json @@ -32,5 +32,6 @@ "@kbn/test", "@kbn/repo-info", "@kbn/data-views-plugin", + "@kbn/tooling-log", ] } diff --git a/x-pack/plugins/security_solution/public/management/cypress/types.ts b/x-pack/plugins/security_solution/public/management/cypress/types.ts index fecaa33a6a70a..aee97723c7d51 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/types.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/types.ts @@ -7,8 +7,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import type { Role } from '@kbn/security-plugin/common'; import type { ActionDetails } from '../../../common/endpoint/types'; import type { CyLoadEndpointDataOptions } from './support/plugin_handlers/endpoint_data_loader'; +import type { SecurityTestUser } from './common/constants'; type PossibleChainable = | Cypress.Chainable @@ -56,3 +58,11 @@ export interface HostActionResponse { state: { state?: 'success' | 'failure' }; }; } + +export interface LoadUserAndRoleCyTaskOptions { + name: SecurityTestUser; +} + +export interface CreateUserAndRoleCyTaskOptions { + role: Role; +} diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/constants.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/constants.ts index 1d2b3d5f47784..4a8b2daca2af4 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/common/constants.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/constants.ts @@ -10,3 +10,8 @@ export const HORIZONTAL_LINE = '-'.repeat(80); export const ENDPOINT_EVENTS_INDEX = 'logs-endpoint.events.process-default'; export const ENDPOINT_ALERTS_INDEX = 'logs-endpoint.alerts-default'; + +export const COMMON_API_HEADERS = Object.freeze({ + 'kbn-xsrf': 'security-solution', + 'x-elastic-internal-origin': 'security-solution', +}); diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts new file mode 100644 index 0000000000000..f8c51d5255018 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/role_and_user_loader.ts @@ -0,0 +1,175 @@ +/* + * 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. + */ + +/* eslint-disable max-classes-per-file */ + +import type { KbnClient } from '@kbn/test'; +import type { Role } from '@kbn/security-plugin/common'; +import type { ToolingLog } from '@kbn/tooling-log'; +import { inspect } from 'util'; +import type { AxiosError } from 'axios'; +import type { EndpointSecurityRoleDefinitions } from './roles_users'; +import { getAllEndpointSecurityRoles } from './roles_users'; +import { catchAxiosErrorFormatAndThrow } from './format_axios_error'; +import { COMMON_API_HEADERS } from './constants'; + +const ignoreHttp409Error = (error: AxiosError) => { + if (error?.response?.status === 409) { + return; + } + + throw error; +}; + +export interface LoadedRoleAndUser { + role: string; + username: string; + password: string; +} + +export interface RoleAndUserLoaderInterface = Record> { + /** + * Loads the requested Role into kibana and then creates a user by the same role name that is + * assigned to the given role + * @param name + */ + load(name: keyof R): Promise; + + /** + * Loads all roles/users + */ + loadAll(): Promise>; + + /** + * Creates a new Role in kibana along with a user (by the same name as the Role name) + * that is assigned to the given role + * @param role + */ + create(role: Role): Promise; +} + +/** + * A generic class for loading roles and creating associated user into kibana + */ +export class RoleAndUserLoader = Record> + implements RoleAndUserLoaderInterface +{ + protected readonly logPromiseError: (error: Error) => never; + + constructor( + protected readonly kbnClient: KbnClient, + protected readonly logger: ToolingLog, + protected readonly roles: R + ) { + this.logPromiseError = (error) => { + this.logger.error(inspect(error, { depth: 5 })); + throw error; + }; + } + + async load(name: keyof R): Promise { + const role = this.roles[name]; + + if (!role) { + throw new Error( + `Unknown role/user: [${String(name)}]. Valid values are: [${Object.keys(this.roles).join( + ', ' + )}]` + ); + } + + return this.create(role); + } + + async loadAll(): Promise> { + const response = {} as Record; + + for (const [name, role] of Object.entries(this.roles)) { + response[name as keyof R] = await this.create(role); + } + + return response; + } + + public async create(role: Role): Promise { + const roleName = role.name; + + await this.createRole(role); + await this.createUser(roleName, 'changeme', [roleName]); + + return { + role: roleName, + username: roleName, + password: 'changeme', + }; + } + + protected async createRole(role: Role): Promise { + const { name: roleName, ...roleDefinition } = role; + + this.logger.debug(`creating role:`, roleDefinition); + + await this.kbnClient + .request({ + method: 'PUT', + path: `/api/security/role/${roleName}`, + headers: { + ...COMMON_API_HEADERS, + }, + body: roleDefinition, + }) + .then((response) => { + this.logger.debug(`Role [${roleName}] created/updated`, response?.data); + return response; + }) + .catch(ignoreHttp409Error) + .catch(catchAxiosErrorFormatAndThrow) + .catch(this.logPromiseError); + } + + protected async createUser( + username: string, + password: string, + roles: string[] = [] + ): Promise { + const user = { + username, + password, + roles, + full_name: username, + email: '', + }; + + this.logger.debug(`creating user:`, user); + + await this.kbnClient + .request({ + method: 'POST', + path: `/internal/security/users/${username}`, + headers: { + ...COMMON_API_HEADERS, + }, + body: user, + }) + .then((response) => { + this.logger.debug(`User [${username}] created/updated`, response?.data); + return response; + }) + .catch(ignoreHttp409Error) + .catch(catchAxiosErrorFormatAndThrow) + .catch(this.logPromiseError); + } +} + +/** + * Role and user loader for Endpoint security dev/testing + */ +export class EndpointSecurityTestRolesLoader extends RoleAndUserLoader { + constructor(protected readonly kbnClient: KbnClient, protected readonly logger: ToolingLog) { + super(kbnClient, logger, getAllEndpointSecurityRoles()); + } +} diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/index.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/index.ts new file mode 100644 index 0000000000000..b035f55bf1589 --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/index.ts @@ -0,0 +1,139 @@ +/* + * 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 { Role } from '@kbn/security-plugin/common'; +import { getRuleAuthor } from './rule_author'; +import { getT3Analyst } from './t3_analyst'; +import { getT1Analyst } from './t1_analyst'; +import { getT2Analyst } from './t2_analyst'; +import { getHunter } from './hunter'; +import { getThreatIntelligenceAnalyst } from './threat_intelligence_analyst'; +import { getSocManager } from './soc_manager'; +import { getPlatformEngineer } from './platform_engineer'; +import { getEndpointOperationsAnalyst } from './endpoint_operations_analyst'; +import { + getEndpointSecurityPolicyManagementReadRole, + getEndpointSecurityPolicyManager, +} from './endpoint_security_policy_manager'; +import { getDetectionsEngineer } from './detections_engineer'; +import { getWithResponseActionsRole } from './with_response_actions_role'; +import { getNoResponseActionsRole } from './without_response_actions_role'; + +export * from './with_response_actions_role'; +export * from './without_response_actions_role'; +export * from './t1_analyst'; +export * from './t2_analyst'; +export * from './t3_analyst'; +export * from './hunter'; +export * from './threat_intelligence_analyst'; +export * from './soc_manager'; +export * from './platform_engineer'; +export * from './endpoint_operations_analyst'; +export * from './endpoint_security_policy_manager'; +export * from './detections_engineer'; + +export type EndpointSecurityRoleNames = keyof typeof ENDPOINT_SECURITY_ROLE_NAMES; + +export type EndpointSecurityRoleDefinitions = Record; + +/** + * Security Solution set of roles that are loaded and used in serverless deployments. + * The source of these role definitions is under `project-controller` at: + * + * @see https://github.com/elastic/project-controller/blob/main/internal/project/security/config/roles.yml + * + * The role definition spreadsheet can be found here: + * + * @see https://docs.google.com/spreadsheets/d/16aGow187AunLCBFZLlbVyS81iQNuMpNxd96LOerWj4c/edit#gid=1936689222 + */ +export const SECURITY_SERVERLESS_ROLE_NAMES = Object.freeze({ + t1_analyst: 't1_analyst', + t2_analyst: 't2_analyst', + t3_analyst: 't3_analyst', + threat_intelligence_analyst: 'threat_intelligence_analyst', + rule_author: 'rule_author', + soc_manager: 'soc_manager', + detections_admin: 'detections_admin', + platform_engineer: 'platform_engineer', + endpoint_operations_analyst: 'endpoint_operations_analyst', + endpoint_policy_manager: 'endpoint_policy_manager', +}); + +export const ENDPOINT_SECURITY_ROLE_NAMES = Object.freeze({ + // -------------------------------------- + // Set of roles used in serverless + ...SECURITY_SERVERLESS_ROLE_NAMES, + + // -------------------------------------- + // Other roles used for testing + hunter: 'hunter', + endpoint_response_actions_access: 'endpoint_response_actions_access', + endpoint_response_actions_no_access: 'endpoint_response_actions_no_access', + endpoint_security_policy_management_read: 'endpoint_security_policy_management_read', +}); + +export const getAllEndpointSecurityRoles = (): EndpointSecurityRoleDefinitions => { + return { + t1_analyst: { + ...getT1Analyst(), + name: 't1_analyst', + }, + t2_analyst: { + ...getT2Analyst(), + name: 't2_analyst', + }, + t3_analyst: { + ...getT3Analyst(), + name: 't3_analyst', + }, + threat_intelligence_analyst: { + ...getThreatIntelligenceAnalyst(), + name: 'threat_intelligence_analyst', + }, + rule_author: { + ...getRuleAuthor(), + name: 'rule_author', + }, + soc_manager: { + ...getSocManager(), + name: 'soc_manager', + }, + detections_admin: { + ...getDetectionsEngineer(), + name: 'detections_admin', + }, + platform_engineer: { + ...getPlatformEngineer(), + name: 'platform_engineer', + }, + endpoint_operations_analyst: { + ...getEndpointOperationsAnalyst(), + name: 'endpoint_operations_analyst', + }, + endpoint_policy_manager: { + ...getEndpointSecurityPolicyManager(), + name: 'endpoint_policy_manager', + }, + + hunter: { + ...getHunter(), + name: 'hunter', + }, + endpoint_response_actions_access: { + ...getWithResponseActionsRole(), + name: 'endpoint_response_actions_access', + }, + endpoint_response_actions_no_access: { + ...getNoResponseActionsRole(), + name: 'endpoint_response_actions_no_access', + }, + endpoint_security_policy_management_read: { + ...getEndpointSecurityPolicyManagementReadRole(), + name: 'endpoint_security_policy_management_read', + }, + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/rule_author.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/rule_author.ts new file mode 100644 index 0000000000000..f957fe8947c5d --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/rule_author.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 type { Role } from '@kbn/security-plugin/common'; +import { getNoResponseActionsRole } from './without_response_actions_role'; + +export const getRuleAuthor: () => Omit = () => { + const noResponseActionsRole = getNoResponseActionsRole(); + return { + ...noResponseActionsRole, + kibana: [ + { + ...noResponseActionsRole.kibana[0], + feature: { + ...noResponseActionsRole.kibana[0].feature, + siem: [ + 'all', + 'read_alerts', + 'crud_alerts', + 'policy_management_all', + 'endpoint_list_all', + 'trusted_applications_all', + 'event_filters_all', + 'host_isolation_exceptions_read', + 'blocklist_all', + 'actions_log_management_read', + ], + }, + }, + ], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/t3_analyst.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/t3_analyst.ts new file mode 100644 index 0000000000000..304c4e6d744ee --- /dev/null +++ b/x-pack/plugins/security_solution/scripts/endpoint/common/roles_users/t3_analyst.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 type { Role } from '@kbn/security-plugin/common'; +import { getNoResponseActionsRole } from './without_response_actions_role'; + +export const getT3Analyst: () => Omit = () => { + const noResponseActionsRole = getNoResponseActionsRole(); + return { + ...noResponseActionsRole, + kibana: [ + { + ...noResponseActionsRole.kibana[0], + feature: { + ...noResponseActionsRole.kibana[0].feature, + siem: [ + 'all', + 'read_alerts', + 'crud_alerts', + 'endpoint_list_all', + 'trusted_applications_all', + 'event_filters_all', + 'host_isolation_exceptions_all', + 'blocklist_all', + 'policy_management_read', + 'host_isolation_all', + 'process_operations_all', + 'actions_log_management_all', + 'file_operations_all', + ], + }, + }, + ], + }; +}; diff --git a/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts b/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts index c1c38dcf8b30a..330bcf4589a74 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/resolver_generator_script.ts @@ -14,36 +14,13 @@ import { CA_CERT_PATH } from '@kbn/dev-utils'; import { ToolingLog } from '@kbn/tooling-log'; import type { KbnClientOptions } from '@kbn/test'; import { KbnClient } from '@kbn/test'; -import type { Role } from '@kbn/security-plugin/common'; +import { EndpointSecurityTestRolesLoader } from './common/role_and_user_loader'; import { METADATA_DATASTREAM } from '../../common/endpoint/constants'; import { EndpointMetadataGenerator } from '../../common/endpoint/data_generators/endpoint_metadata_generator'; import { indexHostsAndAlerts } from '../../common/endpoint/index_data'; import { ANCESTRY_LIMIT, EndpointDocGenerator } from '../../common/endpoint/generate_data'; import { fetchStackVersion, isServerlessKibanaFlavor } from './common/stack_services'; import { ENDPOINT_ALERTS_INDEX, ENDPOINT_EVENTS_INDEX } from './common/constants'; -import { getWithResponseActionsRole } from './common/roles_users/with_response_actions_role'; -import { getNoResponseActionsRole } from './common/roles_users/without_response_actions_role'; -import { getT1Analyst } from './common/roles_users/t1_analyst'; -import { getT2Analyst } from './common/roles_users/t2_analyst'; -import { getEndpointOperationsAnalyst } from './common/roles_users/endpoint_operations_analyst'; -import { getEndpointSecurityPolicyManager } from './common/roles_users/endpoint_security_policy_manager'; -import { getHunter } from './common/roles_users/hunter'; -import { getPlatformEngineer } from './common/roles_users/platform_engineer'; -import { getSocManager } from './common/roles_users/soc_manager'; -import { getThreatIntelligenceAnalyst } from './common/roles_users/threat_intelligence_analyst'; - -const rolesMapping: { [id: string]: Omit } = { - t1Analyst: getT1Analyst(), - t2Analyst: getT2Analyst(), - hunter: getHunter(), - threatIntelligenceAnalyst: getThreatIntelligenceAnalyst(), - socManager: getSocManager(), - platformEngineer: getPlatformEngineer(), - endpointOperationsAnalyst: getEndpointOperationsAnalyst(), - endpointSecurityPolicyManager: getEndpointSecurityPolicyManager(), - withResponseActionsRole: getWithResponseActionsRole(), - noResponseActionsRole: getNoResponseActionsRole(), -}; main(); @@ -67,31 +44,6 @@ async function deleteIndices(indices: string[], client: Client) { } } -async function addRole(kbnClient: KbnClient, role: Role): Promise { - if (!role) { - console.log('No role data given'); - return; - } - - const { name, ...permissions } = role; - const path = `/api/security/role/${name}?createOnly=true`; - - // add role if doesn't exist already - try { - console.log(`Adding ${name} role`); - await kbnClient.request({ - method: 'PUT', - path, - body: permissions, - }); - - return name; - } catch (error) { - console.log(error); - handleErr(error); - } -} - interface UserInfo { username: string; password: string; @@ -422,19 +374,7 @@ async function main() { throw new Error(`Can not use '--rbacUser' option against serverless deployment`); } - // Add roles and users with response actions kibana privileges - for (const role of Object.keys(rolesMapping)) { - const addedRole = await addRole(kbnClient, { - name: role, - ...rolesMapping[role], - }); - if (addedRole) { - logger.info(`Successfully added ${role} role`); - await addUser(client, { username: role, password: 'changeme', roles: [role] }); - } else { - logger.warning(`Failed to add role, ${role}`); - } - } + await loadRbacTestUsers(kbnClient, logger); } const seed = argv.seed || Math.random().toString(); @@ -499,3 +439,12 @@ async function main() { logger.info(`Creating and indexing documents took: ${new Date().getTime() - startTime}ms`); } + +const loadRbacTestUsers = async (kbnClient: KbnClient, logger: ToolingLog): Promise => { + const loadedRoles = await new EndpointSecurityTestRolesLoader(kbnClient, logger).loadAll(); + + logger.info(`Roles and associated users loaded. Login accounts: + ${Object.values(loadedRoles) + .map(({ username, password }) => `${username} / ${password}`) + .join('\n ')}`); +}; diff --git a/x-pack/plugins/security_solution/scripts/openapi/generate.js b/x-pack/plugins/security_solution/scripts/openapi/generate.js index bd88357a3754d..7744612282750 100644 --- a/x-pack/plugins/security_solution/scripts/openapi/generate.js +++ b/x-pack/plugins/security_solution/scripts/openapi/generate.js @@ -6,6 +6,13 @@ */ require('../../../../../src/setup_node_env'); -const { generate } = require('./openapi_generator'); +const { generate } = require('@kbn/openapi-generator'); +const { resolve } = require('path'); -generate(); +const SECURITY_SOLUTION_ROOT = resolve(__dirname, '../..'); + +generate({ + rootDir: SECURITY_SOLUTION_ROOT, + sourceGlob: './**/*.schema.yaml', + templateName: 'zod_operation_schema', +}); diff --git a/x-pack/plugins/security_solution/scripts/openapi/openapi_generator.ts b/x-pack/plugins/security_solution/scripts/openapi/openapi_generator.ts deleted file mode 100644 index 272e62061c6a4..0000000000000 --- a/x-pack/plugins/security_solution/scripts/openapi/openapi_generator.ts +++ /dev/null @@ -1,77 +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. - */ - -/* eslint-disable no-console */ - -import SwaggerParser from '@apidevtools/swagger-parser'; -import chalk from 'chalk'; -import fs from 'fs/promises'; -import globby from 'globby'; -import { resolve } from 'path'; -import { fixEslint } from './lib/fix_eslint'; -import { formatOutput } from './lib/format_output'; -import { removeGenArtifacts } from './lib/remove_gen_artifacts'; -import { getApiOperationsList } from './parsers/get_api_operations_list'; -import { getComponents } from './parsers/get_components'; -import { getImportsMap } from './parsers/get_imports_map'; -import type { OpenApiDocument } from './parsers/openapi_types'; -import { initTemplateService } from './template_service/template_service'; - -const ROOT_SECURITY_SOLUTION_FOLDER = resolve(__dirname, '../..'); -const COMMON_API_FOLDER = resolve(ROOT_SECURITY_SOLUTION_FOLDER, './common/api'); -const SCHEMA_FILES_GLOB = resolve(ROOT_SECURITY_SOLUTION_FOLDER, './**/*.schema.yaml'); -const GENERATED_ARTIFACTS_GLOB = resolve(COMMON_API_FOLDER, './**/*.gen.ts'); - -export const generate = async () => { - console.log(chalk.bold(`Generating API route schemas`)); - console.log(chalk.bold(`Working directory: ${chalk.underline(COMMON_API_FOLDER)}`)); - - console.log(`👀 Searching for schemas`); - const schemaPaths = await globby([SCHEMA_FILES_GLOB]); - - console.log(`🕵️‍♀️ Found ${schemaPaths.length} schemas, parsing`); - const parsedSchemas = await Promise.all( - schemaPaths.map(async (schemaPath) => { - const parsedSchema = (await SwaggerParser.parse(schemaPath)) as OpenApiDocument; - return { schemaPath, parsedSchema }; - }) - ); - - console.log(`🧹 Cleaning up any previously generated artifacts`); - await removeGenArtifacts(COMMON_API_FOLDER); - - console.log(`🪄 Generating new artifacts`); - const TemplateService = await initTemplateService(); - await Promise.all( - parsedSchemas.map(async ({ schemaPath, parsedSchema }) => { - const components = getComponents(parsedSchema); - const apiOperations = getApiOperationsList(parsedSchema); - const importsMap = getImportsMap(parsedSchema); - - // If there are no operations or components to generate, skip this file - const shouldGenerate = apiOperations.length > 0 || components !== undefined; - if (!shouldGenerate) { - return; - } - - const result = TemplateService.compileTemplate('schemas', { - components, - apiOperations, - importsMap, - }); - - // Write the generation result to disk - await fs.writeFile(schemaPath.replace('.schema.yaml', '.gen.ts'), result); - }) - ); - - // Format the output folder using prettier as the generator produces - // unformatted code and fix any eslint errors - console.log(`💅 Formatting output`); - await formatOutput(GENERATED_ARTIFACTS_GLOB); - await fixEslint(GENERATED_ARTIFACTS_GLOB); -}; diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index e73140fec20b7..3dbc778394ecb 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -170,8 +170,8 @@ "@kbn/core-logging-server-mocks", "@kbn/core-lifecycle-browser", "@kbn/security-solution-features", - "@kbn/handlebars", "@kbn/content-management-plugin", - "@kbn/subscription-tracking" + "@kbn/subscription-tracking", + "@kbn/openapi-generator" ] } diff --git a/x-pack/plugins/serverless_search/public/application/components/api_key/api_key.tsx b/x-pack/plugins/serverless_search/public/application/components/api_key/api_key.tsx index 671f1c1ff8cf1..5e9758e134b2a 100644 --- a/x-pack/plugins/serverless_search/public/application/components/api_key/api_key.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/api_key/api_key.tsx @@ -86,6 +86,7 @@ export const ApiKeyPanel = ({ setClientApiKey }: { setClientApiKey: (value: stri })} + {i18n.translate('xpack.serverlessSearch.apiKey.panel.description', { defaultMessage: @@ -94,8 +95,8 @@ export const ApiKeyPanel = ({ setClientApiKey }: { setClientApiKey: (value: stri - - + + {
    {i18n.translate('xpack.serverlessSearch.cloudIdDetails.url.title', { - defaultMessage: 'Cloud URL', + defaultMessage: 'Elasticsearch Endpoint', })}
    diff --git a/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/constants.tsx b/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/constants.tsx index fc06a88fc91fb..ab7f18e2be00f 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/constants.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/constants.tsx @@ -58,19 +58,8 @@ export const openAiConfig: ConfigFieldSchema[] = [ label: i18n.DEFAULT_MODEL_LABEL, helpText: ( - {`${i18n.OPEN_AI} ${i18n.DOCUMENTATION}`} - - ), - }} /> ), defaultValue: DEFAULT_OPENAI_MODEL, diff --git a/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/translations.ts b/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/translations.ts index a407413faa791..ef6ccd07d386b 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/translations.ts +++ b/x-pack/plugins/stack_connectors/public/connector_types/gen_ai/translations.ts @@ -15,7 +15,7 @@ export const API_URL_LABEL = i18n.translate( ); export const API_KEY_LABEL = i18n.translate('xpack.stackConnectors.components.genAi.apiKeySecret', { - defaultMessage: 'API Key', + defaultMessage: 'API key', }); export const DEFAULT_MODEL_LABEL = i18n.translate( @@ -28,8 +28,7 @@ export const DEFAULT_MODEL_LABEL = i18n.translate( export const DEFAULT_MODEL_TOOLTIP_CONTENT = i18n.translate( 'xpack.stackConnectors.components.genAi.defaultModelTooltipContent', { - defaultMessage: - 'The model can be set on a per request basis by including a "model" parameter in the request body. If no model is provided, the fallback will be the default model.', + defaultMessage: 'If a request does not include a model, it uses the default.', } ); diff --git a/x-pack/plugins/transform/common/constants.ts b/x-pack/plugins/transform/common/constants.ts index a1ba2d8277af9..ec26333a834a7 100644 --- a/x-pack/plugins/transform/common/constants.ts +++ b/x-pack/plugins/transform/common/constants.ts @@ -43,6 +43,7 @@ export const TRANSFORM_REACT_QUERY_KEYS = { GET_TRANSFORM_NODES: 'transform.get_transform_nodes', GET_TRANSFORM_AUDIT_MESSAGES: 'transform.get_transform_audit_messages', GET_TRANSFORM_STATS: 'transform.get_transform_stats', + GET_TRANSFORMS_STATS: 'transform.get_transforms_stats', GET_TRANSFORMS: 'transform.get_transforms', GET_TRANSFORMS_PREVIEW: 'transform.get_transforms_preview', } as const; diff --git a/x-pack/plugins/transform/common/utils/create_stats_unknown_message.ts b/x-pack/plugins/transform/common/utils/create_stats_unknown_message.ts new file mode 100644 index 0000000000000..9cfe3ccc38ee4 --- /dev/null +++ b/x-pack/plugins/transform/common/utils/create_stats_unknown_message.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 { i18n } from '@kbn/i18n'; + +export function createNoStatsTooltipMessage({ + actionName, + count = 1, +}: { + actionName: string; + count: number; +}) { + return i18n.translate('xpack.transform.transformList.actionDisabledNoStatsTooltipMessage', { + defaultMessage: + '{actionName} is disabled because the status for {count, plural, one {this transform} other {some transforms}} is unavailable.', + values: { actionName, count }, + }); +} diff --git a/x-pack/plugins/transform/public/app/app.tsx b/x-pack/plugins/transform/public/app/app.tsx index 2812475f7f87a..21d1ca2b1b6b6 100644 --- a/x-pack/plugins/transform/public/app/app.tsx +++ b/x-pack/plugins/transform/public/app/app.tsx @@ -20,7 +20,10 @@ import { AppDependencies } from './app_dependencies'; import { CloneTransformSection } from './sections/clone_transform'; import { CreateTransformSection } from './sections/create_transform'; import { TransformManagementSection } from './sections/transform_management'; -import { ServerlessContextProvider } from './serverless_context'; +import { + EnabledFeaturesContextProvider, + type TransformEnabledFeatures, +} from './serverless_context'; export const App: FC<{ history: ScopedHistory }> = ({ history }) => ( @@ -41,7 +44,7 @@ export const App: FC<{ history: ScopedHistory }> = ({ history }) => ( export const renderApp = ( element: HTMLElement, appDependencies: AppDependencies, - isServerless: boolean + enabledFeatures: TransformEnabledFeatures ) => { const I18nContext = appDependencies.i18n.Context; @@ -60,9 +63,9 @@ export const renderApp = ( - + - + diff --git a/x-pack/plugins/transform/public/app/common/transform_list.ts b/x-pack/plugins/transform/public/app/common/transform_list.ts index c8ddd32f6a8ff..e588ed917958f 100644 --- a/x-pack/plugins/transform/public/app/common/transform_list.ts +++ b/x-pack/plugins/transform/public/app/common/transform_list.ts @@ -20,10 +20,24 @@ export interface TransformListRow { id: TransformId; config: TransformConfigUnion; mode?: string; // added property on client side to allow filtering by this field - stats: TransformStats; + stats?: TransformStats; alerting_rules?: TransformHealthAlertRule[]; } +export type TransformListRowWithStats = TransformListRow & { + stats: TransformStats; +}; + +export function isTransformListRowWithStats( + arg: TransformListRow +): arg is TransformListRowWithStats { + return arg.stats !== undefined; +} + +export function missingTransformStats(items: TransformListRow[]) { + return items.some((i: TransformListRow) => !isTransformListRowWithStats(i)); +} + // The single Action type is not exported as is // from EUI so we use that code to get the single // Action type from the array of actions. diff --git a/x-pack/plugins/transform/public/app/common/transform_stats.test.ts b/x-pack/plugins/transform/public/app/common/transform_stats.test.ts index 974764475eb5f..9213adba45e4d 100644 --- a/x-pack/plugins/transform/public/app/common/transform_stats.test.ts +++ b/x-pack/plugins/transform/public/app/common/transform_stats.test.ts @@ -18,7 +18,7 @@ const getRow = (statsId: string) => { // @ts-expect-error mock data does not actually match TransformListRow type ...(mockTransformListRow as TransformListRow), stats: { - ...(mockTransformStats.transforms as Array).find( + ...(mockTransformStats.transforms as Array>).find( (stats) => stats.id === statsId )!, }, @@ -47,7 +47,7 @@ describe('Transform: Transform stats.', () => { // that will be used by isCompletedBatchTransform() // followed by a call to isCompletedBatchTransform() itself // @ts-expect-error mock data is too loosely typed - const row = mockTransformListRow as TransformListRow; + const row = mockTransformListRow as Required; expect(row.stats.checkpointing.last.checkpoint === 1).toBe(true); expect(row.config.sync === undefined).toBe(true); expect(row.stats.state === TRANSFORM_STATE.STOPPED).toBe(true); diff --git a/x-pack/plugins/transform/public/app/common/transform_stats.ts b/x-pack/plugins/transform/public/app/common/transform_stats.ts index 7763e0712249e..0f7ad5ae98c3f 100644 --- a/x-pack/plugins/transform/public/app/common/transform_stats.ts +++ b/x-pack/plugins/transform/public/app/common/transform_stats.ts @@ -33,7 +33,9 @@ export function isCompletedBatchTransform(item: TransformItem) { // If `checkpoint=1`, `sync` is missing from the config and state is stopped, // then this is a completed batch transform. return ( - item.stats.checkpointing.last.checkpoint === 1 && + item.stats && + item.config && + item.stats.checkpointing?.last.checkpoint === 1 && item.config.sync === undefined && item.stats.state === TRANSFORM_STATE.STOPPED ); diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts index d2b9d32f25853..3c6b329dd880b 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_get_transform_stats.ts @@ -35,3 +35,24 @@ export const useGetTransformStats = ( { enabled, refetchInterval } ); }; + +export const useGetTransformsStats = ({ + enabled, + refetchInterval, +}: { + enabled?: boolean; + refetchInterval?: number | false; +}) => { + const { http } = useAppDependencies(); + + return useQuery( + [TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS_STATS], + ({ signal }) => + http.get(addInternalBasePath(`transforms/_stats`), { + version: '1', + asSystemRequest: true, + signal, + }), + { enabled, refetchInterval } + ); +}; diff --git a/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts b/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts index f74f7a5774ded..f4afb03c4e4c0 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_get_transforms.ts @@ -11,14 +11,12 @@ import type { IHttpFetchError } from '@kbn/core-http-browser'; import { isDefined } from '@kbn/ml-is-defined'; import type { GetTransformsResponseSchema } from '../../../common/api_schemas/transforms'; -import type { GetTransformsStatsResponseSchema } from '../../../common/api_schemas/transforms_stats'; import { addInternalBasePath, DEFAULT_REFRESH_INTERVAL_MS, TRANSFORM_REACT_QUERY_KEYS, TRANSFORM_MODE, } from '../../../common/constants'; -import { isTransformStats } from '../../../common/types/transform_stats'; import { type TransformListRow } from '../common'; import { useAppDependencies } from '../app_dependencies'; @@ -55,14 +53,6 @@ export const useGetTransforms = ({ enabled }: UseGetTransformsOptions = {}) => { signal, } ); - const transformStats = await http.get( - addInternalBasePath(`transforms/_stats`), - { - version: '1', - asSystemRequest: true, - signal, - } - ); // There might be some errors with fetching certain transforms // For example, when task exists and is running but the config is deleted @@ -81,21 +71,13 @@ export const useGetTransforms = ({ enabled }: UseGetTransformsOptions = {}) => { } update.transforms = transformConfigs.transforms.reduce((reducedtableRows, config) => { - const stats = transformStats.transforms.find((d) => config.id === d.id); - - // A newly created transform might not have corresponding stats yet. - // If that's the case we just skip the transform and don't add it to the transform list yet. - if (!isTransformStats(stats)) { - return reducedtableRows; - } - - // Table with expandable rows requires `id` on the outer most level + // Table with expandable rows requires `id` on the outermost level reducedtableRows.push({ id: config.id, config, mode: typeof config.sync !== 'undefined' ? TRANSFORM_MODE.CONTINUOUS : TRANSFORM_MODE.BATCH, - stats, + stats: undefined, alerting_rules: config.alerting_rules, }); return reducedtableRows; diff --git a/x-pack/plugins/transform/public/app/hooks/use_refresh_transform_list.ts b/x-pack/plugins/transform/public/app/hooks/use_refresh_transform_list.ts index 651886ba76f7b..3098946157305 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_refresh_transform_list.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_refresh_transform_list.ts @@ -15,6 +15,7 @@ export const useRefreshTransformList = () => { return () => { queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_NODES]); queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS]); + queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORMS_STATS]); queryClient.invalidateQueries([TRANSFORM_REACT_QUERY_KEYS.GET_TRANSFORM_AUDIT_MESSAGES]); }; }; diff --git a/x-pack/plugins/transform/public/app/mount_management_section.ts b/x-pack/plugins/transform/public/app/mount_management_section.ts index 86b2a297ed636..f00596e1326b4 100644 --- a/x-pack/plugins/transform/public/app/mount_management_section.ts +++ b/x-pack/plugins/transform/public/app/mount_management_section.ts @@ -9,6 +9,7 @@ import { CoreSetup } from '@kbn/core/public'; import { ManagementAppMountParams } from '@kbn/management-plugin/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; +import { type TransformEnabledFeatures } from './serverless_context'; import { PluginsDependencies } from '../plugin'; import { getMlSharedImports } from '../shared_imports'; @@ -93,7 +94,10 @@ export async function mountManagementSection( contentManagement, }; - const unmountAppCallback = renderApp(element, appDependencies, isServerless); + const enabledFeatures: TransformEnabledFeatures = { + showNodeInfo: !isServerless, + }; + const unmountAppCallback = renderApp(element, appDependencies, enabledFeatures); return () => { docTitle.reset(); diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx index 246460d11d3ee..e9326ae195015 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/step_define_form.tsx @@ -35,6 +35,7 @@ import { import { useStorage } from '@kbn/ml-local-storage'; import { useUrlState } from '@kbn/ml-url-state'; +import { useEnabledFeatures } from '../../../../serverless_context'; import { PivotAggDict } from '../../../../../../common/types/pivot_aggs'; import { PivotGroupByDict } from '../../../../../../common/types/pivot_group_by'; import { TRANSFORM_FUNCTION } from '../../../../../../common/constants'; @@ -112,6 +113,7 @@ export const StepDefineForm: FC = React.memo((props) => { ); const toastNotifications = useToastNotifications(); const stepDefineForm = useStepDefineForm(props); + const { showNodeInfo } = useEnabledFeatures(); const { advancedEditorConfig } = stepDefineForm.advancedPivotEditor.state; const { @@ -353,6 +355,7 @@ export const StepDefineForm: FC = React.memo((props) => { query={undefined} disabled={false} timefilter={timefilter} + hideFrozenDataTierChoice={!showNodeInfo} />
    diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx index 37daeeb75e138..bec2407ba631c 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.test.tsx @@ -16,9 +16,11 @@ jest.mock('../../../../app_dependencies'); describe('Transform: Transform List Actions ', () => { test('Minimal initialization', () => { const props: DeleteActionNameProps = { + items: [], canDeleteTransform: true, disabled: false, isBulkAction: false, + forceDisable: false, }; const { container } = render(); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx index 93e346e6c7a1d..7f68645cb2f18 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_name.tsx @@ -11,10 +11,12 @@ import { i18n } from '@kbn/i18n'; import { EuiToolTip } from '@elastic/eui'; -import { TransformState, TRANSFORM_STATE } from '../../../../../../common/constants'; -import { createCapabilityFailureMessage } from '../../../../../../common/utils/create_capability_failure_message'; - +import { missingTransformStats } from '../../../../common/transform_list'; +import { createNoStatsTooltipMessage } from '../../../../../../common/utils/create_stats_unknown_message'; +import { TransformCapabilities } from '../../../../../../common/types/capabilities'; import { TransformListRow } from '../../../../common'; +import { createCapabilityFailureMessage } from '../../../../../../common/utils/create_capability_failure_message'; +import { TransformState, TRANSFORM_STATE } from '../../../../../../common/constants'; export const deleteActionNameText = i18n.translate( 'xpack.transform.transformList.deleteActionNameText', @@ -24,45 +26,67 @@ export const deleteActionNameText = i18n.translate( ); const transformCanNotBeDeleted = (i: TransformListRow) => + i.stats && !([TRANSFORM_STATE.STOPPED, TRANSFORM_STATE.FAILED] as TransformState[]).includes(i.stats.state); export const isDeleteActionDisabled = (items: TransformListRow[], forceDisable: boolean) => { const disabled = items.some(transformCanNotBeDeleted); - return forceDisable === true || disabled; + + return forceDisable === true || disabled || missingTransformStats(items); }; export interface DeleteActionNameProps { + items: TransformListRow[]; canDeleteTransform: boolean; disabled: boolean; isBulkAction: boolean; + forceDisable: boolean; } +export const getDeleteActionDisabledMessage = ({ + items, + canDeleteTransform, + forceDisable, +}: { + items: TransformListRow[]; + canDeleteTransform: TransformCapabilities['canDeleteTransform']; + forceDisable: boolean; +}) => { + const isBulkAction = items.length > 1; + + if (missingTransformStats(items)) { + return createNoStatsTooltipMessage({ + actionName: deleteActionNameText, + count: items.length, + }); + } + + if (!canDeleteTransform) { + return createCapabilityFailureMessage('canDeleteTransform'); + } + + const disabled = items.some(transformCanNotBeDeleted); + + if (disabled) { + return isBulkAction === true + ? i18n.translate('xpack.transform.transformList.deleteBulkActionDisabledToolTipContent', { + defaultMessage: 'One or more selected transforms must be stopped in order to be deleted.', + }) + : i18n.translate('xpack.transform.transformList.deleteActionDisabledToolTipContent', { + defaultMessage: 'Stop the transform in order to delete it.', + }); + } +}; + export const DeleteActionName: FC = ({ + items, canDeleteTransform, disabled, isBulkAction, + forceDisable, }) => { - const bulkDeleteButtonDisabledText = i18n.translate( - 'xpack.transform.transformList.deleteBulkActionDisabledToolTipContent', - { - defaultMessage: 'One or more selected transforms must be stopped in order to be deleted.', - } - ); - const deleteButtonDisabledText = i18n.translate( - 'xpack.transform.transformList.deleteActionDisabledToolTipContent', - { - defaultMessage: 'Stop the transform in order to delete it.', - } - ); - - if (disabled || !canDeleteTransform) { - let content; - if (disabled) { - content = isBulkAction ? bulkDeleteButtonDisabledText : deleteButtonDisabledText; - } else { - content = createCapabilityFailureMessage('canDeleteTransform'); - } - + const content = getDeleteActionDisabledMessage({ items, canDeleteTransform, forceDisable }); + if (content) { return ( <>{deleteActionNameText} diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx index 5996e271604e3..1942a9a9dc8b7 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx @@ -7,9 +7,10 @@ import React, { useMemo, useState } from 'react'; +import { isTransformListRowWithStats } from '../../../../common/transform_list'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; -import { TransformListAction, TransformListRow } from '../../../../common'; +import type { TransformListAction, TransformListRow } from '../../../../common'; import { useDeleteIndexAndTargetIndex, useDeleteTransforms, @@ -33,7 +34,7 @@ export const useDeleteAction = (forceDisable: boolean) => { const isBulkAction = items.length > 1; const shouldForceDelete = useMemo( - () => items.some((i: TransformListRow) => i.stats.state === TRANSFORM_STATE.FAILED), + () => items.some((i: TransformListRow) => i.stats?.state === TRANSFORM_STATE.FAILED), [items] ); @@ -59,10 +60,10 @@ export const useDeleteAction = (forceDisable: boolean) => { // else, force delete only when the item user picks has failed const forceDelete = isBulkAction ? shouldForceDelete - : items[0] && items[0] && items[0].stats.state === TRANSFORM_STATE.FAILED; + : items[0] && items[0] && items[0].stats?.state === TRANSFORM_STATE.FAILED; deleteTransforms({ - transformsInfo: items.map((i) => ({ + transformsInfo: items.filter(isTransformListRowWithStats).map((i) => ({ id: i.config.id, state: i.stats.state, })), @@ -87,11 +88,15 @@ export const useDeleteAction = (forceDisable: boolean) => { canDeleteTransform, disabled: isDeleteActionDisabled([item], forceDisable), isBulkAction: false, + items: [item], + forceDisable, }} /> ), enabled: (item: TransformListRow) => - !isDeleteActionDisabled([item], forceDisable) && canDeleteTransform, + isTransformListRowWithStats(item) && + !isDeleteActionDisabled([item], forceDisable) && + canDeleteTransform, description: deleteActionNameText, icon: 'trash', type: 'icon', diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.test.tsx index 4fb0f9e655208..05d804cc9147b 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.test.tsx @@ -11,16 +11,16 @@ import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { render, waitFor, screen } from '@testing-library/react'; -import { TransformListRow } from '../../../../common'; import { isDiscoverActionDisabled, DiscoverActionName } from './discover_action_name'; import transformListRow from '../../../../common/__mocks__/transform_list_row.json'; +import { TransformListRowWithStats } from '../../../../common/transform_list'; jest.mock('../../../../../shared_imports'); jest.mock('../../../../app_dependencies'); // @ts-expect-error mock data is too loosely typed -const item: TransformListRow = transformListRow; +const item: TransformListRowWithStats = transformListRow; describe('Transform: Transform List Actions isDiscoverActionDisabled()', () => { it('should be disabled when more than one item is passed in', () => { diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx index c3d359e648c28..b164dbee25fd2 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_discover/discover_action_name.tsx @@ -33,7 +33,7 @@ export const isDiscoverActionDisabled = ( const item = items[0]; // Disable discover action if it's a batch transform and was never started - const stoppedTransform = item.stats.state === TRANSFORM_STATE.STOPPED; + const stoppedTransform = item.stats?.state === TRANSFORM_STATE.STOPPED; const transformProgress = getTransformProgress(item); const isBatchTransform = typeof item.config.sync === 'undefined'; const transformNeverStarted = @@ -52,7 +52,7 @@ export const DiscoverActionName: FC = ({ dataViewExists const item = items[0]; // Disable discover action if it's a batch transform and was never started - const stoppedTransform = item.stats.state === TRANSFORM_STATE.STOPPED; + const stoppedTransform = item.stats?.state === TRANSFORM_STATE.STOPPED; const transformProgress = getTransformProgress(item); const isBatchTransform = typeof item.config.sync === 'undefined'; const transformNeverStarted = diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx index ee883a3e7e77b..c0abb4fa5e51c 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/reauthorize_action_name.tsx @@ -49,7 +49,6 @@ export const ReauthorizeActionName: FC = ({ }) => { const { canStartStopTransform } = useTransformCapabilities(); - // Disable start for batch transforms which have completed. const someNeedsReauthorization = items.some(needsReauthorization); const actionIsDisabled = isReauthorizeActionDisabled( diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx index 67e618765e42e..3d216af23db8a 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reauthorize/use_reauthorize_action.tsx @@ -7,6 +7,7 @@ import React, { useMemo, useState } from 'react'; +import { isTransformListRowWithStats } from '../../../../common/transform_list'; import { sortTransformsToReauthorize } from './sort_transforms_to_reauthorize'; import { needsReauthorization } from '../../../../common/reauthorization_utils'; import { useReauthorizeTransforms } from '../../../../hooks/use_reauthorize_transform'; @@ -54,6 +55,7 @@ export const useReauthorizeAction = (forceDisable: boolean, transformNodes: numb ), available: (item: TransformListRow) => needsReauthorization(item), enabled: (item: TransformListRow) => + isTransformListRowWithStats(item) && !isReauthorizeActionDisabled([item], canStartStopTransform, transformNodes), description: reauthorizeActionNameText, icon: 'alert', diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx index 6d5f56d3e7297..0f19701fb0914 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/reset_action_name.tsx @@ -11,6 +11,9 @@ import { EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { createNoStatsTooltipMessage } from '../../../../../../common/utils/create_stats_unknown_message'; +import { missingTransformStats } from '../../../../common/transform_list'; +import { TransformCapabilities } from '../../../../../../common/types/capabilities'; import { TransformState, TRANSFORM_STATE } from '../../../../../../common/constants'; import { createCapabilityFailureMessage } from '../../../../../../common/utils/create_capability_failure_message'; @@ -24,45 +27,74 @@ export const resetActionNameText = i18n.translate( ); const transformCanNotBeReseted = (i: TransformListRow) => + i.stats && !([TRANSFORM_STATE.STOPPED, TRANSFORM_STATE.FAILED] as TransformState[]).includes(i.stats.state); export const isResetActionDisabled = (items: TransformListRow[], forceDisable: boolean) => { const disabled = items.some(transformCanNotBeReseted); - return forceDisable === true || disabled; + + return forceDisable === true || disabled || missingTransformStats(items); }; +export const getResetActionDisabledMessage = ({ + items, + canResetTransform, + forceDisable, +}: { + items: TransformListRow[]; + canResetTransform: TransformCapabilities['canResetTransform']; + forceDisable: boolean; +}) => { + const isBulkAction = items.length > 1; + + if (missingTransformStats(items)) { + return createNoStatsTooltipMessage({ + actionName: resetActionNameText, + count: items.length, + }); + } + + if (!canResetTransform) { + return createCapabilityFailureMessage('canResetTransform'); + } + + if (isResetActionDisabled(items, forceDisable)) { + const bulkResetButtonDisabledText = i18n.translate( + 'xpack.transform.transformList.resetBulkActionDisabledToolTipContent', + { + defaultMessage: 'One or more selected transforms must be stopped to be reset.', + } + ); + const resetButtonDisabledText = i18n.translate( + 'xpack.transform.transformList.resetActionDisabledToolTipContent', + { + defaultMessage: 'Stop the transform in order to reset it.', + } + ); + + return isBulkAction ? bulkResetButtonDisabledText : resetButtonDisabledText; + } +}; export interface ResetActionNameProps { + items: TransformListRow[]; + canResetTransform: boolean; disabled: boolean; isBulkAction: boolean; } export const ResetActionName: FC = ({ + items, canResetTransform, disabled, - isBulkAction, }) => { - const bulkResetButtonDisabledText = i18n.translate( - 'xpack.transform.transformList.resetBulkActionDisabledToolTipContent', - { - defaultMessage: 'One or more selected transforms must be stopped to be reset.', - } - ); - const resetButtonDisabledText = i18n.translate( - 'xpack.transform.transformList.resetActionDisabledToolTipContent', - { - defaultMessage: 'Stop the transform in order to reset it.', - } - ); - - if (disabled || !canResetTransform) { - let content; - if (disabled) { - content = isBulkAction ? bulkResetButtonDisabledText : resetButtonDisabledText; - } else { - content = createCapabilityFailureMessage('canResetTransform'); - } + const content = getResetActionDisabledMessage({ + items, + canResetTransform, + forceDisable: disabled, + }); + if (content) { return ( <>{resetActionNameText} diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx index 23a399fdb9086..b00ea69d7e4fd 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_reset/use_reset_action.tsx @@ -7,12 +7,21 @@ import React, { useMemo, useState } from 'react'; +import { + isTransformListRowWithStats, + TransformListRowWithStats, +} from '../../../../common/transform_list'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; import { TransformListAction, TransformListRow } from '../../../../common'; import { useTransformCapabilities, useResetTransforms } from '../../../../hooks'; -import { resetActionNameText, isResetActionDisabled, ResetActionName } from './reset_action_name'; +import { + resetActionNameText, + isResetActionDisabled, + ResetActionName, + getResetActionDisabledMessage, +} from './reset_action_name'; export type ResetAction = ReturnType; export const useResetAction = (forceDisable: boolean) => { @@ -24,7 +33,7 @@ export const useResetAction = (forceDisable: boolean) => { const [items, setItems] = useState([]); const shouldForceReset = useMemo( - () => items.some((i: TransformListRow) => i.stats.state === TRANSFORM_STATE.FAILED), + () => items.some((i: TransformListRow) => i.stats?.state === TRANSFORM_STATE.FAILED), [items] ); @@ -34,10 +43,12 @@ export const useResetAction = (forceDisable: boolean) => { setModalVisible(false); resetTransforms({ - transformsInfo: items.map((i) => ({ - id: i.config.id, - state: i.stats.state, - })), + transformsInfo: items + .filter(isTransformListRowWithStats) + .map((i) => ({ + id: i.config.id, + state: i.stats.state, + })), }); }; @@ -56,11 +67,13 @@ export const useResetAction = (forceDisable: boolean) => { canResetTransform, disabled: isResetActionDisabled([item], forceDisable), isBulkAction: false, + items: [item], }} /> ), enabled: (item: TransformListRow) => - !isResetActionDisabled([item], forceDisable) && canResetTransform, + getResetActionDisabledMessage({ items: [item], canResetTransform, forceDisable }) === + undefined, description: resetActionNameText, icon: 'refresh', type: 'icon', diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx index 0c3be1cdad70b..5b4ff6908afdf 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/schedule_now_action_name.tsx @@ -11,6 +11,8 @@ import { EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { missingTransformStats } from '../../../../common/transform_list'; +import { createNoStatsTooltipMessage } from '../../../../../../common/utils/create_stats_unknown_message'; import { createCapabilityFailureMessage } from '../../../../../../common/utils/create_capability_failure_message'; import { useTransformCapabilities } from '../../../../hooks'; @@ -35,7 +37,8 @@ export const isScheduleNowActionDisabled = ( !canScheduleNowTransform || completedBatchTransform || items.length === 0 || - transformNodes === 0 + transformNodes === 0 || + missingTransformStats(items) ); }; @@ -92,6 +95,11 @@ export const ScheduleNowActionName: FC = ({ content = createCapabilityFailureMessage('canScheduleNowTransform'); } else if (completedBatchTransform) { content = completedBatchTransformMessage; + } else if (missingTransformStats(items)) { + content = createNoStatsTooltipMessage({ + actionName: scheduleNowActionNameText, + count: items.length, + }); } } diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx index a13d3da89f677..e5d330eb9ba28 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_schedule_now/use_schedule_now_action.tsx @@ -7,6 +7,7 @@ import React, { useMemo } from 'react'; +import { isTransformListRowWithStats } from '../../../../common/transform_list'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; import { useTransformCapabilities } from '../../../../hooks'; @@ -33,8 +34,10 @@ export const useScheduleNowAction = (forceDisable: boolean, transformNodes: numb transformNodes={transformNodes} /> ), - available: (item: TransformListRow) => item.stats.state === TRANSFORM_STATE.STARTED, + available: (item: TransformListRow) => + isTransformListRowWithStats(item) ? item.stats.state === TRANSFORM_STATE.STARTED : true, enabled: (item: TransformListRow) => + isTransformListRowWithStats(item) && !isScheduleNowActionDisabled([item], canScheduleNowTransform, transformNodes), description: scheduleNowActionNameText, icon: 'play', diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx index c50c83d25edc5..22ddbf1d12c3d 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/start_action_name.tsx @@ -9,6 +9,8 @@ import React, { type FC } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiToolTip } from '@elastic/eui'; +import { createNoStatsTooltipMessage } from '../../../../../../common/utils/create_stats_unknown_message'; +import { missingTransformStats } from '../../../../common/transform_list'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; import { createCapabilityFailureMessage } from '../../../../../../common/utils/create_capability_failure_message'; @@ -31,7 +33,7 @@ export const isStartActionDisabled = ( const completedBatchTransform = items.some((i: TransformListRow) => isCompletedBatchTransform(i)); // Disable start action if one of the transforms is already started or trying to restart will throw error const startedTransform = items.some( - (i: TransformListRow) => i.stats.state === TRANSFORM_STATE.STARTED + (i: TransformListRow) => i.stats?.state === TRANSFORM_STATE.STARTED ); return ( @@ -39,7 +41,8 @@ export const isStartActionDisabled = ( completedBatchTransform || startedTransform || items.length === 0 || - transformNodes === 0 + transformNodes === 0 || + missingTransformStats(items) ); }; @@ -58,9 +61,9 @@ export const StartActionName: FC = ({ // Disable start for batch transforms which have completed. const completedBatchTransform = items.some((i: TransformListRow) => isCompletedBatchTransform(i)); - // Disable start action if one of the transforms is already started or trying to restart will throw error + // Disable if one of the transforms is already started or trying to restart will throw error const startedTransform = items.some( - (i: TransformListRow) => i.stats.state === TRANSFORM_STATE.STARTED + (i: TransformListRow) => i.stats?.state === TRANSFORM_STATE.STARTED ); let startedTransformMessage; @@ -107,6 +110,11 @@ export const StartActionName: FC = ({ content = completedBatchTransformMessage; } else if (startedTransform) { content = startedTransformMessage; + } else if (missingTransformStats(items)) { + content = createNoStatsTooltipMessage({ + actionName: startActionNameText, + count: items.length, + }); } } diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx index 168174730b706..3724e53cf69b8 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_start/use_start_action.tsx @@ -7,6 +7,7 @@ import React, { useMemo, useState } from 'react'; +import { isTransformListRowWithStats } from '../../../../common/transform_list'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; import { TransformListAction, TransformListRow } from '../../../../common'; @@ -46,7 +47,8 @@ export const useStartAction = (forceDisable: boolean, transformNodes: number) => transformNodes={transformNodes} /> ), - available: (item: TransformListRow) => item.stats.state === TRANSFORM_STATE.STOPPED, + available: (item: TransformListRow) => + isTransformListRowWithStats(item) ? item.stats.state === TRANSFORM_STATE.STOPPED : true, enabled: (item: TransformListRow) => !isStartActionDisabled([item], canStartStopTransform, transformNodes), description: startActionNameText, diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx index e5bc1425cdd99..b2a079a425273 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/stop_action_name.tsx @@ -9,6 +9,12 @@ import React, { type FC } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiToolTip } from '@elastic/eui'; +import { TransformCapabilities } from '../../../../../../common/types/capabilities'; +import { + isTransformListRowWithStats, + missingTransformStats, +} from '../../../../common/transform_list'; +import { createNoStatsTooltipMessage } from '../../../../../../common/utils/create_stats_unknown_message'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; import { createCapabilityFailureMessage } from '../../../../../../common/utils/create_capability_failure_message'; @@ -22,6 +28,46 @@ export const stopActionNameText = i18n.translate( } ); +export const getStopActionDisabledMessage = ({ + items, + capabilities, +}: { + items: TransformListRow[]; + capabilities: TransformCapabilities; +}) => { + const isBulkAction = items.length > 1; + + const { canStartStopTransform } = capabilities; + + if (missingTransformStats(items)) { + return createNoStatsTooltipMessage({ + actionName: stopActionNameText, + count: items.length, + }); + } + + // Disable stop action if one of the transforms is stopped already + const stoppedTransform = items.some( + (i: TransformListRow) => + isTransformListRowWithStats(i) && i.stats.state === TRANSFORM_STATE.STOPPED + ); + + if (!canStartStopTransform) { + return createCapabilityFailureMessage('canStartStopTransform'); + } + + if (stoppedTransform) { + return isBulkAction === true + ? i18n.translate('xpack.transform.transformList.stoppedTransformBulkToolTip', { + defaultMessage: 'One or more transforms are already stopped.', + }) + : i18n.translate('xpack.transform.transformList.stoppedTransformToolTip', { + defaultMessage: '{transformId} is already stopped.', + values: { transformId: items[0] && items[0].config.id }, + }); + } +}; + export const isStopActionDisabled = ( items: TransformListRow[], canStartStopTransform: boolean, @@ -29,10 +75,15 @@ export const isStopActionDisabled = ( ) => { // Disable stop action if one of the transforms is stopped already const stoppedTransform = items.some( - (i: TransformListRow) => i.stats.state === TRANSFORM_STATE.STOPPED + (i: TransformListRow) => i.stats?.state === TRANSFORM_STATE.STOPPED ); - return forceDisable === true || !canStartStopTransform || stoppedTransform === true; + return ( + forceDisable === true || + !canStartStopTransform || + stoppedTransform === true || + missingTransformStats(items) + ); }; export interface StopActionNameProps { @@ -40,42 +91,15 @@ export interface StopActionNameProps { forceDisable?: boolean; } export const StopActionName: FC = ({ items, forceDisable }) => { - const isBulkAction = items.length > 1; - const { canStartStopTransform } = useTransformCapabilities(); - - // Disable stop action if one of the transforms is stopped already - const stoppedTransform = items.some( - (i: TransformListRow) => i.stats.state === TRANSFORM_STATE.STOPPED - ); - - let stoppedTransformMessage; - if (isBulkAction === true) { - stoppedTransformMessage = i18n.translate( - 'xpack.transform.transformList.stoppedTransformBulkToolTip', - { - defaultMessage: 'One or more transforms are already stopped.', - } - ); - } else { - stoppedTransformMessage = i18n.translate( - 'xpack.transform.transformList.stoppedTransformToolTip', - { - defaultMessage: '{transformId} is already stopped.', - values: { transformId: items[0] && items[0].config.id }, - } - ); - } - - if (!canStartStopTransform || stoppedTransform) { + const capabilities = useTransformCapabilities(); + // Disable transforms if stats does not exist + const stoppedTransformMessage = getStopActionDisabledMessage({ + items, + capabilities, + }); + if (forceDisable || stoppedTransformMessage) { return ( - + <>{stopActionNameText} ); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx index e410704341177..36ec5139d14ee 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_stop/use_stop_action.tsx @@ -6,6 +6,7 @@ */ import React, { useCallback, useMemo, useState } from 'react'; +import { isTransformListRowWithStats } from '../../../../common/transform_list'; import { TRANSFORM_STATE } from '../../../../../../common/constants'; import { TransformListAction, TransformListRow } from '../../../../common'; import { useTransformCapabilities, useStopTransforms } from '../../../../hooks'; @@ -30,13 +31,16 @@ export const useStopAction = (forceDisable: boolean) => { const stopAndCloseModal = useCallback( (transformSelection: TransformListRow[]) => { setModalVisible(false); - stopTransforms(transformSelection.map((t) => ({ id: t.id, state: t.stats.state }))); + stopTransforms( + transformSelection.map((t) => ({ id: t.id, state: t.stats ? t.stats.state : 'waiting' })) + ); }, [stopTransforms] ); const clickHandler = useCallback( - (i: TransformListRow) => stopTransforms([{ id: i.id, state: i.stats.state }]), + (t: TransformListRow) => + stopTransforms([{ id: t.id, state: t.stats ? t.stats.state : 'waiting' }]), [stopTransforms] ); @@ -45,8 +49,10 @@ export const useStopAction = (forceDisable: boolean) => { name: (item: TransformListRow) => ( ), - available: (item: TransformListRow) => item.stats.state !== TRANSFORM_STATE.STOPPED, + available: (item: TransformListRow) => + isTransformListRowWithStats(item) ? item.stats.state !== TRANSFORM_STATE.STOPPED : true, enabled: (item: TransformListRow) => + isTransformListRowWithStats(item) && !isStopActionDisabled([item], canStartStopTransform, forceDisable), description: stopActionNameText, icon: 'stop', diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.test.tsx index f8b55dbbeda3c..370d7c2da05d5 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.test.tsx @@ -38,7 +38,7 @@ describe('Transform: Transform List ', () => { render( - + ); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx index f4766da492f67..079b3f72b59bd 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row.tsx @@ -5,19 +5,28 @@ * 2.0. */ -import React, { FC, useMemo } from 'react'; -import { css } from '@emotion/react'; +import React, { useMemo, type FC } from 'react'; import moment from 'moment-timezone'; +import { css } from '@emotion/react'; -import { EuiButtonEmpty, EuiTabbedContent } from '@elastic/eui'; +import { + EuiButtonEmpty, + EuiLoadingSpinner, + EuiFlexGroup, + useEuiTheme, + EuiCallOut, + EuiFlexItem, + EuiTabbedContent, +} from '@elastic/eui'; -import { Optional } from '@kbn/utility-types'; import { i18n } from '@kbn/i18n'; import { formatHumanReadableDateTimeSeconds } from '@kbn/ml-date-utils'; import { stringHash } from '@kbn/ml-string-hash'; import { isDefined } from '@kbn/ml-is-defined'; -import { useIsServerless } from '../../../../serverless_context'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { useEnabledFeatures } from '../../../../serverless_context'; +import { isTransformListRowWithStats } from '../../../../common/transform_list'; import { TransformHealthAlertRule } from '../../../../../../common/types/alerting'; import { TransformListRow } from '../../../../common'; @@ -42,47 +51,48 @@ type Item = SectionItem; interface Props { item: TransformListRow; onAlertEdit: (alertRule: TransformHealthAlertRule) => void; + transformsStatsLoading: boolean; } -type StateValues = Optional; - -export const ExpandedRow: FC = ({ item, onAlertEdit }) => { - const hideNodeInfo = useIsServerless(); +const NoStatsFallbackTabContent = ({ + transformsStatsLoading, +}: { + transformsStatsLoading: boolean; +}) => { + const { euiTheme } = useEuiTheme(); - const stateValues: StateValues = { ...item.stats }; - delete stateValues.stats; - delete stateValues.checkpointing; - - const stateItems: Item[] = []; - stateItems.push( - { - title: 'ID', - description: item.id, - }, - { - title: 'state', - description: item.stats.state, - } + const content = transformsStatsLoading ? ( + + ) : ( + + + } + /> + ); - if (!hideNodeInfo && item.stats.node !== undefined) { - stateItems.push({ - title: 'node.name', - description: item.stats.node.name, - }); - } - if (item.stats.health !== undefined) { - stateItems.push({ - title: 'health', - description: , - }); - } + return ( + + {content} + + ); +}; - const state: SectionConfig = { - title: 'State', - items: stateItems, - position: 'right', - }; +export const ExpandedRow: FC = ({ item, onAlertEdit, transformsStatsLoading }) => { + const { showNodeInfo } = useEnabledFeatures(); + const stateItems: Item[] = []; + stateItems.push({ + title: 'ID', + description: item.id, + }); const configItems = useMemo(() => { const configs: Item[] = [ { @@ -130,75 +140,100 @@ export const ExpandedRow: FC = ({ item, onAlertEdit }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [item?.config]); - const general: SectionConfig = { - title: 'General', - items: configItems, - position: 'left', - }; - const checkpointingItems: Item[] = []; - if (item.stats.checkpointing.changes_last_detected_at !== undefined) { - checkpointingItems.push({ - title: 'changes_last_detected_at', - description: formatHumanReadableDateTimeSeconds( - item.stats.checkpointing.changes_last_detected_at - ), + if (isTransformListRowWithStats(item)) { + stateItems.push({ + title: 'state', + description: item.stats.state, }); - } + if (showNodeInfo && item.stats.node !== undefined) { + stateItems.push({ + title: 'node.name', + description: item.stats.node.name, + }); + } + if (item.stats.health !== undefined) { + stateItems.push({ + title: 'health', + description: , + }); + } - if (item.stats.checkpointing.last !== undefined) { - checkpointingItems.push({ - title: 'last.checkpoint', - description: item.stats.checkpointing.last.checkpoint, - }); - if (item.stats.checkpointing.last.timestamp_millis !== undefined) { + if (item.stats.checkpointing.changes_last_detected_at !== undefined) { checkpointingItems.push({ - title: 'last.timestamp', + title: 'changes_last_detected_at', description: formatHumanReadableDateTimeSeconds( - item.stats.checkpointing.last.timestamp_millis + item.stats.checkpointing.changes_last_detected_at ), }); + } + + if (item.stats.checkpointing.last !== undefined) { checkpointingItems.push({ - title: 'last.timestamp_millis', - description: item.stats.checkpointing.last.timestamp_millis, + title: 'last.checkpoint', + description: item.stats.checkpointing.last.checkpoint, }); + if (item.stats.checkpointing.last.timestamp_millis !== undefined) { + checkpointingItems.push({ + title: 'last.timestamp', + description: formatHumanReadableDateTimeSeconds( + item.stats.checkpointing.last.timestamp_millis + ), + }); + checkpointingItems.push({ + title: 'last.timestamp_millis', + description: item.stats.checkpointing.last.timestamp_millis, + }); + } } - } - if (item.stats.checkpointing.last_search_time !== undefined) { - checkpointingItems.push({ - title: 'last_search_time', - description: formatHumanReadableDateTimeSeconds(item.stats.checkpointing.last_search_time), - }); - } - - if (item.stats.checkpointing.next !== undefined) { - checkpointingItems.push({ - title: 'next.checkpoint', - description: item.stats.checkpointing.next.checkpoint, - }); - if (item.stats.checkpointing.next.checkpoint_progress !== undefined) { + if (item.stats.checkpointing.last_search_time !== undefined) { checkpointingItems.push({ - title: 'next.checkpoint_progress.total_docs', - description: item.stats.checkpointing.next.checkpoint_progress.total_docs, + title: 'last_search_time', + description: formatHumanReadableDateTimeSeconds(item.stats.checkpointing.last_search_time), }); + } + + if (item.stats.checkpointing.next !== undefined) { checkpointingItems.push({ - title: 'next.checkpoint_progress.docs_remaining', - description: item.stats.checkpointing.next.checkpoint_progress.docs_remaining, + title: 'next.checkpoint', + description: item.stats.checkpointing.next.checkpoint, }); + if (item.stats.checkpointing.next.checkpoint_progress !== undefined) { + checkpointingItems.push({ + title: 'next.checkpoint_progress.total_docs', + description: item.stats.checkpointing.next.checkpoint_progress.total_docs, + }); + checkpointingItems.push({ + title: 'next.checkpoint_progress.docs_remaining', + description: item.stats.checkpointing.next.checkpoint_progress.docs_remaining, + }); + checkpointingItems.push({ + title: 'next.checkpoint_progress.percent_complete', + description: item.stats.checkpointing.next.checkpoint_progress.percent_complete, + }); + } + } + + if (item.stats.checkpointing.operations_behind !== undefined) { checkpointingItems.push({ - title: 'next.checkpoint_progress.percent_complete', - description: item.stats.checkpointing.next.checkpoint_progress.percent_complete, + title: 'operations_behind', + description: item.stats.checkpointing.operations_behind, }); } } - if (item.stats.checkpointing.operations_behind !== undefined) { - checkpointingItems.push({ - title: 'operations_behind', - description: item.stats.checkpointing.operations_behind, - }); - } + const state: SectionConfig = { + title: 'State', + items: stateItems, + position: 'right', + }; + + const general: SectionConfig = { + title: 'General', + items: configItems, + position: 'left', + }; const alertRuleItems: Item[] | undefined = item.alerting_rules?.map((rule) => { return { @@ -236,9 +271,11 @@ export const ExpandedRow: FC = ({ item, onAlertEdit }) => { const stats: SectionConfig = { title: 'Stats', - items: Object.entries(item.stats.stats).map((s) => { - return { title: s[0].toString(), description: getItemDescription(s[1]) }; - }), + items: isTransformListRowWithStats(item) + ? Object.entries(item.stats.stats).map((s) => { + return { title: s[0].toString(), description: getItemDescription(s[1]) }; + }) + : [], position: 'left', }; @@ -275,8 +312,10 @@ export const ExpandedRow: FC = ({ item, onAlertEdit }) => { defaultMessage: 'Stats', } ), - content: ( + content: isTransformListRowWithStats(item) ? ( + ) : ( + ), }, { @@ -285,7 +324,7 @@ export const ExpandedRow: FC = ({ item, onAlertEdit }) => { name: 'JSON', content: , }, - ...(item.stats.health + ...(item.stats?.health ? [ { id: `transform-health-tab-${tabId}`, diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_health_pane.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_health_pane.tsx index 0e8ab94dc2086..3a088d5a9b273 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_health_pane.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_health_pane.tsx @@ -12,14 +12,15 @@ import { formatDate, EuiPanel, EuiSpacer, EuiInMemoryTable } from '@elastic/eui' import { i18n } from '@kbn/i18n'; import { TIME_FORMAT } from '../../../../../../common/constants'; -import type { TransformHealthIssue } from '../../../../../../common/types/transform_stats'; - -import { TransformListRow } from '../../../../common'; +import type { + TransformHealthIssue, + TransformStats, +} from '../../../../../../common/types/transform_stats'; import { TransformHealthColoredDot } from './transform_health_colored_dot'; interface ExpandedRowHealthPaneProps { - health: TransformListRow['stats']['health']; + health: TransformStats['health']; } export const ExpandedRowHealthPane: FC = ({ health }) => { diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx index 10c1a4f01dfb2..8124ecbb87182 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/expanded_row_messages_pane.tsx @@ -19,7 +19,7 @@ import { import { euiLightVars as theme } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; -import { useIsServerless } from '../../../../serverless_context'; +import { useEnabledFeatures } from '../../../../serverless_context'; import { DEFAULT_MAX_AUDIT_MESSAGE_SIZE, TIME_FORMAT } from '../../../../../../common/constants'; import { TransformMessage } from '../../../../../../common/types/messages'; @@ -36,7 +36,7 @@ interface Sorting { } export const ExpandedRowMessagesPane: FC = ({ transformId }) => { - const hideNodeInfo = useIsServerless(); + const { showNodeInfo } = useEnabledFeatures(); const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(10); @@ -99,7 +99,7 @@ export const ExpandedRowMessagesPane: FC = ({ tran render: (timestamp: number) => formatDate(timestamp, TIME_FORMAT), sortable: true, }, - ...(!hideNodeInfo + ...(showNodeInfo ? [ { field: 'node_name', @@ -121,7 +121,7 @@ export const ExpandedRowMessagesPane: FC = ({ tran defaultMessage: 'Message', } ), - width: !hideNodeInfo ? '50%' : '70%', + width: showNodeInfo ? '50%' : '70%', }, ]; diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx index fc4bf0e24d14d..e3f98beea9e7e 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.test.tsx @@ -39,6 +39,7 @@ describe('Transform: Transform List ', () => { transformNodes={1} transforms={[]} transformsLoading={false} + transformsStatsLoading={false} /> diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx index 2e0106afc0e92..a55253a08b5eb 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_list.tsx @@ -70,12 +70,19 @@ type ItemIdToExpandedRowMap = Record; function getItemIdToExpandedRowMap( itemIds: TransformId[], transforms: TransformListRow[], - onAlertEdit: (alertRule: TransformHealthAlertRule) => void + onAlertEdit: (alertRule: TransformHealthAlertRule) => void, + transformsStatsLoading: boolean ): ItemIdToExpandedRowMap { return itemIds.reduce((m: ItemIdToExpandedRowMap, transformId: TransformId) => { const item = transforms.find((transform) => transform.config.id === transformId); if (item !== undefined) { - m[transformId] = ; + m[transformId] = ( + + ); } return m; }, {} as ItemIdToExpandedRowMap); @@ -87,6 +94,7 @@ interface TransformListProps { transformNodes: number; transforms: TransformListRow[]; transformsLoading: boolean; + transformsStatsLoading: boolean; } export const TransformList: FC = ({ @@ -95,6 +103,7 @@ export const TransformList: FC = ({ transformNodes, transforms, transformsLoading, + transformsStatsLoading, }) => { const refreshTransformList = useRefreshTransformList(); const { setEditAlertRule } = useAlertRuleFlyout(); @@ -126,7 +135,8 @@ export const TransformList: FC = ({ expandedRowItemIds, setExpandedRowItemIds, transformNodes, - transformSelection + transformSelection, + transformsStatsLoading ); const searchError = query?.error ? query?.error.message : undefined; @@ -166,7 +176,8 @@ export const TransformList: FC = ({ const itemIdToExpandedRowMap = getItemIdToExpandedRowMap( expandedRowItemIds, transforms, - setEditAlertRule + setEditAlertRule, + transformsStatsLoading ); const bulkActionMenuItems = [ @@ -235,6 +246,7 @@ export const TransformList: FC = ({ canResetTransform={capabilities.canResetTransform} disabled={isResetActionDisabled(transformSelection, false)} isBulkAction={true} + items={transformSelection} />
    , @@ -247,6 +259,8 @@ export const TransformList: FC = ({ canDeleteTransform={capabilities.canDeleteTransform} disabled={isDeleteActionDisabled(transformSelection, false)} isBulkAction={true} + items={transformSelection} + forceDisable={false} />
    , diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar_filters.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar_filters.tsx index 5a2df943e9a54..637f32558cb41 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar_filters.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transform_search_bar_filters.tsx @@ -106,9 +106,12 @@ export const filterTransforms = (transforms: TransformListRow[], clauses: Clause // filter other clauses, i.e. the mode and status filters if (c.type !== 'is' && Array.isArray(c.value)) { // the status value is an array of string(s) e.g. ['failed', 'stopped'] - ts = transforms.filter((transform) => (c.value as Value[]).includes(transform.stats.state)); + ts = transforms.filter( + (transform) => transform.stats && (c.value as Value[]).includes(transform.stats.state) + ); } else { ts = transforms.filter((transform) => { + if (!transform.stats) return false; if (c.type === 'field' && c.field === 'health') { return transform.stats.health?.status === c.value; } diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transforms_stats_bar.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transforms_stats_bar.tsx index 79f6321c2419f..bf1e07a18f20f 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transforms_stats_bar.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/transforms_stats_bar.tsx @@ -12,7 +12,7 @@ import { EuiButton, EuiCallOut, EuiLink, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { useIsServerless } from '../../../../serverless_context'; +import { useEnabledFeatures } from '../../../../serverless_context'; import { TRANSFORM_MODE, TRANSFORM_STATE } from '../../../../../../common/constants'; import { TransformListRow } from '../../../../common'; @@ -21,10 +21,10 @@ import { useDocumentationLinks, useRefreshTransformList } from '../../../../hook import { StatsBar, TransformStatsBarStats } from '../stats_bar'; -function createTranformStats( +function createTransformStats( transformNodes: number, transformsList: TransformListRow[], - hideNodeInfo: boolean + showNodeInfo: boolean ): TransformStatsBarStats { const transformStats: TransformStatsBarStats = { total: { @@ -64,7 +64,7 @@ function createTranformStats( }, }; - if (!hideNodeInfo) { + if (showNodeInfo) { transformStats.nodes = { label: i18n.translate('xpack.transform.statsBar.transformNodesLabel', { defaultMessage: 'Nodes', @@ -94,10 +94,12 @@ function createTranformStats( transformStats.batch.value++; } - if (transform.stats.state === TRANSFORM_STATE.FAILED) { - failedTransforms++; - } else if (transform.stats.state === TRANSFORM_STATE.STARTED) { - startedTransforms++; + if (transform.stats) { + if (transform.stats.state === TRANSFORM_STATE.FAILED) { + failedTransforms++; + } else if (transform.stats.state === TRANSFORM_STATE.STARTED) { + startedTransforms++; + } } }); @@ -123,19 +125,19 @@ export const TransformStatsBar: FC = ({ transformNodes, transformsList, }) => { - const hideNodeInfo = useIsServerless(); + const { showNodeInfo } = useEnabledFeatures(); const refreshTransformList = useRefreshTransformList(); const { esNodeRoles } = useDocumentationLinks(); - const transformStats: TransformStatsBarStats = createTranformStats( + const transformStats: TransformStatsBarStats = createTransformStats( transformNodes, transformsList, - hideNodeInfo + showNodeInfo ); return ( <> - {!hideNodeInfo && transformNodes === 0 && ( + {showNodeInfo && transformNodes === 0 && ( <> { const wrapper: FC = ({ children }) => ( {children} ); - const { result, waitForNextUpdate } = renderHook(() => useColumns([], () => {}, 1, []), { + const { result, waitForNextUpdate } = renderHook(() => useColumns([], () => {}, 1, [], false), { wrapper, }); diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.tsx index 2ae8edf30a1de..fb578ec06aa3c 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/transform_list/use_columns.tsx @@ -22,6 +22,7 @@ import { EuiToolTip, RIGHT_ALIGNMENT, EuiIcon, + EuiLoadingSpinner, } from '@elastic/eui'; import { useTransformCapabilities } from '../../../../hooks'; @@ -46,12 +47,20 @@ const TRANSFORM_INSUFFICIENT_PERMISSIONS_MSG = i18n.translate( defaultMessage: 'This transform was created with insufficient permissions.', } ); + +const StatsUnknown = () => ( + + + +); export const useColumns = ( expandedRowItemIds: TransformId[], setExpandedRowItemIds: React.Dispatch>, transformNodes: number, - transformSelection: TransformListRow[] + transformSelection: TransformListRow[], + transformsStatsLoading: boolean ) => { + const NoStatsFallbackComponent = transformsStatsLoading ? EuiLoadingSpinner : StatsUnknown; const { canStartStopTransform } = useTransformCapabilities(); const { actions, modals } = useActions({ @@ -239,10 +248,14 @@ export const useColumns = ( { name: i18n.translate('xpack.transform.status', { defaultMessage: 'Status' }), 'data-test-subj': 'transformListColumnStatus', - sortable: (item: TransformListRow) => item.stats.state, + sortable: (item: TransformListRow) => item.stats?.state, truncateText: true, render(item: TransformListRow) { - return ; + return item.stats ? ( + + ) : ( + + ); }, width: '100px', }, @@ -271,6 +284,7 @@ export const useColumns = ( if (progress === undefined && isBatchTransform === true) { return null; } + if (!item.stats) return ; return ( @@ -292,7 +306,7 @@ export const useColumns = ( )} - {!isBatchTransform && ( + {!isBatchTransform && item.stats && ( <> {/* If not stopped, failed or waiting show the animated progress bar */} @@ -321,10 +335,14 @@ export const useColumns = ( { name: i18n.translate('xpack.transform.health', { defaultMessage: 'Health' }), 'data-test-subj': 'transformListColumnHealth', - sortable: (item: TransformListRow) => item.stats.health.status, + sortable: (item: TransformListRow) => item.stats?.health.status, truncateText: true, render(item: TransformListRow) { - return ; + return item.stats ? ( + + ) : ( + + ); }, width: '100px', }, diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx index cce3128b3f3d0..7e1f2ccd3bc09 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/transform_management_section.tsx @@ -21,7 +21,10 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import type { IHttpFetchError } from '@kbn/core-http-browser'; -import { useIsServerless } from '../../serverless_context'; +import type { TransformListRow } from '../../common'; +import { isTransformStats } from '../../../../common/types/transform_stats'; +import { useGetTransformsStats } from '../../hooks/use_get_transform_stats'; +import { useEnabledFeatures } from '../../serverless_context'; import { needsReauthorization } from '../../common/reauthorization_utils'; import { TRANSFORM_STATE } from '../../../../common/constants'; @@ -72,7 +75,7 @@ const ErrorMessageCallout: FC<{ export const TransformManagement: FC = () => { const { esTransform } = useDocumentationLinks(); - const hideNodeInfo = useIsServerless(); + const { showNodeInfo } = useEnabledFeatures(); const deleteTransforms = useDeleteTransforms(); @@ -85,13 +88,37 @@ export const TransformManagement: FC = () => { const { isInitialLoading: transformsInitialLoading, - isLoading: transformsLoading, + isLoading: transformsWithoutStatsLoading, error: transformsErrorMessage, - data: { transforms, transformIdsWithoutConfig }, + data: { transforms: transformsWithoutStats, transformIdsWithoutConfig }, } = useGetTransforms({ - enabled: !transformNodesInitialLoading && (transformNodes > 0 || hideNodeInfo), + enabled: !transformNodesInitialLoading && transformNodes > 0, }); + const { + isLoading: transformsStatsLoading, + error: transformsStatsErrorMessage, + data: transformsStats, + } = useGetTransformsStats({ + enabled: !transformNodesInitialLoading && transformNodes > 0, + }); + + const transforms: TransformListRow[] = useMemo(() => { + if (!transformsStats) return transformsWithoutStats; + + return transformsWithoutStats.map((t) => { + const stats = transformsStats.transforms.find((d) => t.config.id === d.id); + + // A newly created transform might not have corresponding stats yet. + // If that's the case we just skip the transform and don't add it to the transform list yet. + if (!isTransformStats(stats)) { + return t; + } + + return { ...t, stats }; + }); + }, [transformsStats, transformsWithoutStats]); + const isInitialLoading = transformNodesInitialLoading || transformsInitialLoading; const { canStartStopTransform } = useTransformCapabilities(); @@ -197,7 +224,7 @@ export const TransformManagement: FC = () => { <> {unauthorizedTransformsWarning} - {!hideNodeInfo && transformNodesErrorMessage !== null && ( + {showNodeInfo && transformNodesErrorMessage !== null && ( { errorMessage={transformsErrorMessage} /> )} + {transformsStatsErrorMessage !== null ? ( + + } + errorMessage={transformsStatsErrorMessage} + /> + ) : null} @@ -272,11 +310,12 @@ export const TransformManagement: FC = () => { ) : null} {(transformNodes > 0 || transforms.length > 0) && ( )} diff --git a/x-pack/plugins/transform/public/app/serverless_context.tsx b/x-pack/plugins/transform/public/app/serverless_context.tsx index d6113957aff73..5cfbcf6c91b06 100644 --- a/x-pack/plugins/transform/public/app/serverless_context.tsx +++ b/x-pack/plugins/transform/public/app/serverless_context.tsx @@ -7,20 +7,27 @@ import React, { createContext, FC, useContext, useMemo } from 'react'; -export const ServerlessContext = createContext({ - isServerless: false, +export interface TransformEnabledFeatures { + showNodeInfo: boolean; +} +export const EnabledFeaturesContext = createContext({ + showNodeInfo: true, }); -export const ServerlessContextProvider: FC<{ isServerless: boolean }> = (props) => { - const { children, isServerless } = props; +export const EnabledFeaturesContextProvider: FC<{ enabledFeatures: TransformEnabledFeatures }> = ( + props +) => { + const { children, enabledFeatures } = props; return ( - {children} + + {children} + ); }; -export function useIsServerless() { - const context = useContext(ServerlessContext); +export function useEnabledFeatures() { + const context = useContext(EnabledFeaturesContext); return useMemo(() => { - return context.isServerless; + return context; }, [context]); } diff --git a/x-pack/plugins/transform/tsconfig.json b/x-pack/plugins/transform/tsconfig.json index 52e0747cc1fb9..7b41f101c15c1 100644 --- a/x-pack/plugins/transform/tsconfig.json +++ b/x-pack/plugins/transform/tsconfig.json @@ -40,7 +40,6 @@ "@kbn/std", "@kbn/es-query", "@kbn/ml-agg-utils", - "@kbn/utility-types", "@kbn/ml-string-hash", "@kbn/ui-theme", "@kbn/field-types", diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 150f72792a861..0e167e1ce60d3 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -3212,7 +3212,7 @@ "guidedOnboardingPackage.gettingStarted.cards.progressLabel": "{numberCompleteSteps} étape(s) terminée(s) sur {numberSteps}", "guidedOnboardingPackage.gettingStarted.cards.siemSecurity.title": "Détecter les menaces dans {lineBreak} mes données avec SIEM", "guidedOnboardingPackage.gettingStarted.cards.completeLabel": "Guide terminé", - "guidedOnboardingPackage.gettingStarted.cards.aiSearch.title": "Créer une expérience de recherche sémantique", + "guidedOnboardingPackage.gettingStarted.cards.aiSearch.title": "Créer une expérience de recherche basée sur l'IA", "guidedOnboardingPackage.gettingStarted.cards.hostsObservability.title": "Monitorer mes indicateurs d'hôte", "guidedOnboardingPackage.gettingStarted.cards.kubernetesObservability.title": "Monitorer les clusters Kubernetes", "guidedOnboardingPackage.gettingStarted.cards.logsObservability.title": "Collecter et analyser mes logs", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 41096d8c2e990..f0e47690da767 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -3227,7 +3227,7 @@ "guidedOnboardingPackage.gettingStarted.cards.progressLabel": "{numberSteps}ステップ中{numberCompleteSteps}ステップ完了", "guidedOnboardingPackage.gettingStarted.cards.siemSecurity.title": "SIEMで{lineBreak}データの脅威を検出", "guidedOnboardingPackage.gettingStarted.cards.completeLabel": "ガイド完了", - "guidedOnboardingPackage.gettingStarted.cards.aiSearch.title": "セマンティック検索エクスペリエンスを構築", + "guidedOnboardingPackage.gettingStarted.cards.aiSearch.title": "AI を活用した検索エクスペリエンスを構築する", "guidedOnboardingPackage.gettingStarted.cards.hostsObservability.title": "ホストメトリックを監視", "guidedOnboardingPackage.gettingStarted.cards.kubernetesObservability.title": "Kubernetesクラスターの監視", "guidedOnboardingPackage.gettingStarted.cards.logsObservability.title": "ログを収集して分析", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b17bf98b8ad3a..17beacb3184e2 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -3226,7 +3226,7 @@ "guidedOnboardingPackage.gettingStarted.cards.progressLabel": "已完成 {numberCompleteSteps} 个(共 {numberSteps} 个)步骤", "guidedOnboardingPackage.gettingStarted.cards.siemSecurity.title": "通过 SIEM{lineBreak}在我的数据中检测威胁", "guidedOnboardingPackage.gettingStarted.cards.completeLabel": "指南完成", - "guidedOnboardingPackage.gettingStarted.cards.aiSearch.title": "构建语义搜索体验", + "guidedOnboardingPackage.gettingStarted.cards.aiSearch.title": "打造人工智能驱动的搜索体验", "guidedOnboardingPackage.gettingStarted.cards.hostsObservability.title": "监测我的主机指标", "guidedOnboardingPackage.gettingStarted.cards.kubernetesObservability.title": "监测 Kubernetes 集群", "guidedOnboardingPackage.gettingStarted.cards.logsObservability.title": "收集并分析我的日志", diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.test.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.test.tsx index 3c98245760fcb..45b3c182084f6 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.test.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.test.tsx @@ -13,7 +13,7 @@ import { render } from '../../lib/helper/rtl_helpers'; import * as reactRouterDom from 'react-router-dom'; import { Ping } from '../../../../common/runtime_types'; -import { MonitorPageTitle, MonitorPageTitleContent } from './monitor_title'; +import { MonitorPageTitle } from './monitor_title'; jest.mock('react-router-dom', () => { const originalModule = jest.requireActual('react-router-dom'); @@ -51,23 +51,6 @@ describe('MonitorTitle component', () => { }, }; - const defaultBrowserMonitorStatus: Ping = { - docId: 'few213kl', - timestamp: moment(new Date()).subtract(15, 'm').toString(), - monitor: { - duration: { - us: 1234567, - }, - id: 'browser', - status: 'up', - type: 'browser', - check_group: 'test-group', - }, - url: { - full: 'https://www.elastic.co/', - }, - }; - const monitorStatusWithName: Ping = { ...defaultMonitorStatus, monitor: { @@ -84,14 +67,12 @@ describe('MonitorTitle component', () => { render( <> - , { state: { monitorStatus: { status: monitorStatusWithName, loading: false } }, } ); expect(screen.getByText(monitorName)); - expect(screen.getByRole('switch')).toBeInTheDocument(); }); it('renders the user provided monitorId when the name is not present', () => { @@ -114,16 +95,4 @@ describe('MonitorTitle component', () => { ); expect(screen.getByText(defaultMonitorStatus!.url!.full!)); }); - - it('renders beta disclaimer for synthetics monitors', () => { - render(, { - state: { monitorStatus: { status: defaultBrowserMonitorStatus, loading: false } }, - }); - const betaLink = screen.getByRole('link', { - name: 'See more External link (opens in a new tab or window)', - }) as HTMLAnchorElement; - expect(betaLink).toBeInTheDocument(); - expect(betaLink.href).toBe('https://www.elastic.co/what-is/synthetic-monitoring'); - expect(screen.getByText('Browser (BETA)')).toBeInTheDocument(); - }); }); diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.tsx index a15b941e4e935..2a84d3acbf4ad 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/monitor_title.tsx @@ -5,13 +5,10 @@ * 2.0. */ -import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiLink, EuiText } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; import React from 'react'; import { useSelector } from 'react-redux'; import { useMonitorId } from '../../hooks'; import { monitorStatusSelector } from '../../state/selectors'; -import { EnableMonitorAlert } from '../overview/monitor_list/columns/enable_alert'; import { Ping } from '../../../../common/runtime_types/ping'; import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; @@ -32,86 +29,6 @@ const getPageTitle = (monitorId: string, selectedMonitor: Ping | null) => { return monitorId; }; -export const MonitorPageTitleContent: React.FC = () => { - const monitorId = useMonitorId(); - const selectedMonitor = useSelector(monitorStatusSelector); - const type = selectedMonitor?.monitor?.type; - const isBrowser = type === 'browser'; - const renderMonitorType = (monitorType: string) => { - switch (monitorType) { - case 'http': - return ( - - ); - case 'tcp': - return ( - - ); - case 'icmp': - return ( - - ); - case 'browser': - return ( - - ); - default: - return ''; - } - }; - return ( - <> - - - - - - - - - {isBrowser && type && ( - - {renderMonitorType(type)}{' '} - - - )} - - {isBrowser && ( - - - - - - - - )} - - - ); -}; - export const MonitorPageTitle: React.FC = () => { const monitorId = useMonitorId(); diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap index 5ebde1d72dd0d..77345c95164a6 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/monitor_status.bar.test.tsx.snap @@ -12,58 +12,49 @@ Array [
    , - .c0.c0.c0 { - width: 30%; - max-width: 250px; -} - -.c1.c1.c1 { - width: 70%; - overflow-wrap: anywhere; -} - -
    Overall availability
    0.00 %
    Url
    --
    Monitor ID
    Tags
    +
    + Enable status alerts +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    , ] `; diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap index d80ca3bb00376..1e50379a09553 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/__snapshots__/ssl_certificate.test.tsx.snap @@ -2,32 +2,19 @@ exports[`SSL Certificate component renders 1`] = ` Array [ - .c0.c0.c0 { - width: 30%; - max-width: 250px; -} - -
    TLS Certificate
    , -
    , .c0.c0.c0 { - width: 70%; - overflow-wrap: anywhere; -} - -.c1.c1.c1 { margin: 0 0 0 4px; display: inline-block; color: inherit; }

    Expires in 2 months

    @@ -57,26 +44,13 @@ Array [ exports[`SSL Certificate component renders null if invalid date 1`] = ` Array [ - .c0.c0.c0 { - width: 30%; - max-width: 250px; -} - -
    TLS Certificate
    , -
    , - .c0.c0.c0 { - width: 70%; - overflow-wrap: anywhere; -} - -
    { return ( <> - + - - - - + + - + ); }; diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx index 50e4ca36dabc5..f122415d725c0 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_bar/status_bar.tsx @@ -6,7 +6,6 @@ */ import React from 'react'; -import styled from 'styled-components'; import { EuiLink, EuiSpacer, @@ -16,6 +15,10 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; +import { useSelector } from 'react-redux'; +import { ENABLE_STATUS_ALERT } from '../../../overview/monitor_list/columns/translations'; +import { monitorStatusSelector } from '../../../../state/selectors'; +import { EnableMonitorAlert } from '../../../overview/monitor_list/columns/enable_alert'; import { MonitorSSLCertificate } from './ssl_certificate'; import * as labels from '../translations'; import { StatusByLocations } from './status_by_location'; @@ -31,20 +34,6 @@ import { formatAvailabilityValue } from '../availability_reporting/availability_ import { MonitorRedirects } from './monitor_redirects'; import { MonitorTags } from '../../../common/monitor_tags'; -export const MonListTitle = styled(EuiDescriptionListTitle)` - &&& { - width: 30%; - max-width: 250px; - } -`; - -export const MonListDescription = styled(EuiDescriptionListDescription)` - &&& { - width: 70%; - overflow-wrap: anywhere; - } -`; - export const renderMonitorType = (type: string | undefined) => { switch (type) { case 'http': @@ -77,24 +66,29 @@ export const MonitorStatusBar: React.FC = () => { const availability = (ups === 0 && downs === 0) || !ups ? 0 : (ups / (ups + downs)) * 100; + const selectedMonitor = useSelector(monitorStatusSelector); + return ( <>
    - - {OverallAvailability} - + + {OverallAvailability} + - - {URL_LABEL} - + + {URL_LABEL} + {full ? ( { ) : ( '--' )} - - {MonitorIDLabel} - {monitorId} + + {MonitorIDLabel} + + {monitorId} + {monitorStatus?.monitor?.type && ( <> - {labels.typeLabel} - + + {labels.typeLabel} + + {renderMonitorType(monitorStatus?.monitor?.type)} - + )} - {TAGS_LABEL} - + {TAGS_LABEL} + - + {monitorStatus?.monitor?.project?.id && ( <> - {PROJECT_LABEL} - {monitorStatus?.monitor?.project.id} + {PROJECT_LABEL} + + {monitorStatus?.monitor?.project.id} + )} + {ENABLE_STATUS_ALERT} + {selectedMonitor && ( + + )} ); diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_details.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_details.tsx index 0c9c347fc8c80..48196a75f37b5 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_details.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/monitor/status_details/status_details.tsx @@ -5,11 +5,10 @@ * 2.0. */ -import React, { useContext, useEffect, useState } from 'react'; +import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; import styled from 'styled-components'; import { LocationAvailability } from './location_availability/location_availability'; -import { UptimeRefreshContext } from '../../../contexts'; import { MonitorLocations } from '../../../../../common/runtime_types'; import { MonitorStatusBar } from './status_bar'; @@ -26,28 +25,6 @@ const WrapFlexItem = styled(EuiFlexItem)` `; export const MonitorStatusDetailsComponent = ({ monitorLocations }: MonitorStatusDetailsProps) => { - const { refreshApp } = useContext(UptimeRefreshContext); - - const [isTabActive] = useState(document.visibilityState); - const onTabActive = () => { - if (document.visibilityState === 'visible' && isTabActive === 'hidden') { - refreshApp(); - } - }; - - // Refreshing application state after Tab becomes active to render latest map state - // If application renders in when tab is not in focus it gives some unexpected behaviors - // Where map is not visible on change - useEffect(() => { - document.addEventListener('visibilitychange', onTabActive); - return () => { - document.removeEventListener('visibilitychange', onTabActive); - }; - - // we want this effect to execute exactly once after the component mounts - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - return ( diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.test.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.test.tsx index aa257177970a1..29f0dd189594c 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.test.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.test.tsx @@ -21,21 +21,23 @@ describe('EnableAlertComponent', () => { fireEvent.click(screen.getByTestId('uptimeDisplayDefineConnector')); - expect(screen.queryByTestId('uptimeSettingsDefineConnector')).not.toBeInTheDocument(); + expect(screen.queryByTestId('uptimeSettingsDefineConnector')).toBeInTheDocument(); }); it('shows label when showLabel is true', () => { - render(); - expect(screen.getByText(ENABLE_STATUS_ALERT)).toBeInTheDocument(); + render(); + expect(screen.getByLabelText(ENABLE_STATUS_ALERT)).toBeInTheDocument(); }); it('shows helpText when showHelpText is true', () => { - render(); + render(); + fireEvent.click(screen.getByTestId('uptimeDisplayDefineConnector')); + expect(screen.getByText(/Define a default connector/)).toBeInTheDocument(); }); it('renders popover on click when showPopover is true', () => { - render(); + render(); fireEvent.click(screen.getByTestId('uptimeDisplayDefineConnector')); diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.tsx index 0a6040249a663..4ee8cb1c67d89 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/define_connectors.tsx @@ -12,17 +12,7 @@ import { ReactRouterEuiLink } from '../../../common/react_router_helpers'; import { SETTINGS_ROUTE } from '../../../../../../common/constants'; import { ENABLE_STATUS_ALERT } from './translations'; -interface Props { - showPopover?: boolean; - showHelpText?: boolean; - showLabel?: boolean; -} - -export const DefineAlertConnectors = ({ - showPopover = false, - showHelpText = false, - showLabel = false, -}: Props) => { +export const DefineAlertConnectors = () => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const onButtonClick = () => setIsPopoverOpen((val) => !val); @@ -32,46 +22,22 @@ export const DefineAlertConnectors = ({ - - - - ), - }} - /> - ) : undefined - } - > + {}} + onChange={onButtonClick} checked={false} compressed={true} - disabled={!showPopover} data-test-subj={'uptimeDisplayDefineConnector'} /> } - isOpen={showPopover ? isPopoverOpen : false} + isOpen={isPopoverOpen} closePopover={closePopover} > diff --git a/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/enable_alert.tsx b/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/enable_alert.tsx index b52aacd5abb6e..e7ff83f5ebae1 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/enable_alert.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/components/overview/monitor_list/columns/enable_alert.tsx @@ -111,7 +111,7 @@ export const EnableMonitorAlert = ({ monitorId, selectedMonitor }: Props) => { compressed={!isMonitorPage} disabled={showSpinner} label={btnLabel} - showLabel={!!isMonitorPage} + showLabel={false} aria-label={btnLabel} onChange={onAlertClick} checked={!!hasAlert} @@ -126,10 +126,6 @@ export const EnableMonitorAlert = ({ monitorId, selectedMonitor }: Props) => {
    ) : ( - + ); }; diff --git a/x-pack/plugins/uptime/public/legacy_uptime/routes.tsx b/x-pack/plugins/uptime/public/legacy_uptime/routes.tsx index 43194e10735d6..269624a0c6dc0 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/routes.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/routes.tsx @@ -30,7 +30,7 @@ import { SyntheticsCheckStepsPageHeader, SyntheticsCheckStepsPageRightSideItem, } from './pages/synthetics/synthetics_checks'; -import { MonitorPageTitle, MonitorPageTitleContent } from './components/monitor/monitor_title'; +import { MonitorPageTitle } from './components/monitor/monitor_title'; import { UptimeDatePicker } from './components/common/uptime_date_picker'; import { CertRefreshBtn } from './components/certificates/cert_refresh_btn'; import { CertificateTitle } from './components/certificates/certificate_title'; @@ -69,7 +69,6 @@ const getRoutes = (): RouteProps[] => { component: MonitorPage, dataTestSubj: 'uptimeMonitorPage', pageHeader: { - children: , pageTitle: , rightSideItems: [], }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts index ddc90ec10e9b6..02a41b6de7afa 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/telemetry/alerting_and_actions_telemetry.ts @@ -26,8 +26,7 @@ export default function createAlertingAndActionsTelemetryTests({ getService }: F const esTestIndexTool = new ESTestIndexTool(es, retry); const supertestWithoutAuth = getService('supertestWithoutAuth'); - // FLAKY: https://github.com/elastic/kibana/issues/140973 - describe.skip('telemetry', () => { + describe('telemetry', () => { const objectRemover = new ObjectRemover(supertest); const alwaysFiringRuleId: { [key: string]: string } = {}; diff --git a/x-pack/test/apm_api_integration/common/bettertest.ts b/x-pack/test/apm_api_integration/common/bettertest.ts index 41580983917a3..83f7da5725db8 100644 --- a/x-pack/test/apm_api_integration/common/bettertest.ts +++ b/x-pack/test/apm_api_integration/common/bettertest.ts @@ -11,20 +11,32 @@ import request from 'superagent'; type HttpMethod = 'get' | 'post' | 'put' | 'delete'; -export type BetterTest = (options: { +export type BetterTest = (options: BetterTestOptions) => Promise>; + +interface BetterTestOptions { pathname: string; query?: Record; method?: HttpMethod; body?: any; -}) => Promise<{ status: number; body: T }>; +} + +interface BetterTestResponse { + status: number; + body: T; +} /* * This is a wrapper around supertest that throws an error if the response status is not 200. * This is useful for tests that expect a 200 response * It also makes it easier to debug tests that fail because of a 500 response. */ -export function getBettertest(st: supertest.SuperTest): BetterTest { - return async ({ pathname, method = 'get', query, body }) => { +export function getBettertest(st: supertest.SuperTest) { + return async ({ + pathname, + method = 'get', + query, + body, + }: BetterTestOptions): Promise> => { const url = format({ pathname, query }); let res: request.Response; diff --git a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts index 0ba4336b36e0c..d78a6fa6d99d6 100644 --- a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts +++ b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts @@ -5,7 +5,6 @@ * 2.0. */ -import * as Url from 'url'; import { PackagePolicy } from '@kbn/fleet-plugin/common'; import { AGENT_CONFIG_PATH, @@ -17,7 +16,7 @@ import expect from '@kbn/expect'; import { get } from 'lodash'; import type { SourceMap } from '@kbn/apm-plugin/server/routes/source_maps/route'; import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api'; -import { createEsClientForTesting } from '@kbn/test'; +import { createEsClientForFtrConfig } from '@kbn/test'; import { APM_AGENT_CONFIGURATION_INDEX, APM_SOURCE_MAP_INDEX, @@ -30,7 +29,7 @@ import { deletePackagePolicy, getPackagePolicy, setupFleet, -} from './apm_package_policy_setup'; +} from './helpers'; import { getBettertest } from '../../common/bettertest'; import { expectToReject } from '../../common/utils/expect_to_reject'; @@ -41,14 +40,10 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { const supertest = getService('supertest'); const es = getService('es'); const bettertest = getBettertest(supertest); + const configService = getService('config'); function createEsClientWithApiKeyAuth({ id, apiKey }: { id: string; apiKey: string }) { - const config = getService('config'); - return createEsClientForTesting({ - esUrl: Url.format(config.get('servers.elasticsearch')), - requestTimeout: config.get('timeouts.esRequestTimeout'), - auth: { apiKey: { id, api_key: apiKey } }, - }); + return createEsClientForFtrConfig(configService, { auth: { apiKey: { id, api_key: apiKey } } }); } async function createConfiguration(configuration: any) { @@ -120,8 +115,8 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { before(async () => { await setupFleet(bettertest); - agentPolicyId = await createAgentPolicy(bettertest); - packagePolicyId = await createPackagePolicy(bettertest, agentPolicyId); + agentPolicyId = await createAgentPolicy({ bettertest }); + packagePolicyId = await createPackagePolicy({ bettertest, agentPolicyId }); apmPackagePolicy = await getPackagePolicy(bettertest, packagePolicyId); // make sure to get the latest package policy }); diff --git a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy_setup.ts b/x-pack/test/apm_api_integration/tests/fleet/helpers.ts similarity index 63% rename from x-pack/test/apm_api_integration/tests/fleet/apm_package_policy_setup.ts rename to x-pack/test/apm_api_integration/tests/fleet/helpers.ts index aeb2f00fb9360..9cedf76b221b1 100644 --- a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy_setup.ts +++ b/x-pack/test/apm_api_integration/tests/fleet/helpers.ts @@ -11,15 +11,23 @@ export function setupFleet(bettertest: BetterTest) { return bettertest({ pathname: '/api/fleet/setup', method: 'post' }); } -export async function createAgentPolicy(bettertest: BetterTest, id?: string) { +export async function createAgentPolicy({ + bettertest, + id, + name = 'test_agent_policy', +}: { + bettertest: BetterTest; + id?: string; + name?: string; +}) { const agentPolicyResponse = await bettertest<{ item: AgentPolicy }>({ pathname: '/api/fleet/agent_policies', method: 'post', query: { sys_monitoring: true }, body: { - name: 'test_agent_policy', - description: '', id, + name, + description: '', namespace: 'default', monitoring_enabled: ['logs', 'metrics'], }, @@ -28,11 +36,17 @@ export async function createAgentPolicy(bettertest: BetterTest, id?: string) { return agentPolicyResponse.body.item.id; } -export async function createPackagePolicy( - bettertest: BetterTest, - agentPolicyId: string, - id?: string -) { +export async function createPackagePolicy({ + bettertest, + agentPolicyId, + id, + name = 'apm-integration-test-policy', +}: { + bettertest: BetterTest; + agentPolicyId: string; + id?: string; + name?: string; +}) { // Get version of available APM package const apmPackageResponse = await bettertest<{ item: any }>({ pathname: `/api/fleet/epm/packages/apm`, @@ -44,7 +58,7 @@ export async function createPackagePolicy( pathname: '/api/fleet/package_policies', method: 'post', body: { - name: 'apm-integration-test-policy', + name, description: '', namespace: 'default', policy_id: agentPolicyId, @@ -82,3 +96,36 @@ export async function getPackagePolicy( }); return res.body.item; } + +async function getAgentPolicyByName(bettertest: BetterTest, name: string): Promise { + const res = await bettertest<{ items: PackagePolicy[] }>({ + pathname: `/api/fleet/agent_policies`, + query: { + full: true, + kuery: `name:"${name}"`, + }, + }); + return res.body.items[0]; +} + +export async function deleteAgentPolicyAndPackagePolicyByName({ + bettertest, + agentPolicyName, + packagePolicyName, +}: { + bettertest: BetterTest; + agentPolicyName: string; + packagePolicyName: string; +}) { + const agentPolicy = await getAgentPolicyByName(bettertest, agentPolicyName); + + const agentPolicyId = agentPolicy.id; + // @ts-expect-error + const packagePolicies = agentPolicy.package_policies as PackagePolicy[]; + const packagePolicyId = packagePolicies.find( + (packagePolicy) => packagePolicy.name === packagePolicyName + )!.id; + + await deleteAgentPolicy(bettertest, agentPolicyId); + await deletePackagePolicy(bettertest, packagePolicyId); +} diff --git a/x-pack/test/apm_api_integration/tests/fleet/input_only_package.spec.ts b/x-pack/test/apm_api_integration/tests/fleet/input_only_package.spec.ts new file mode 100644 index 0000000000000..982d37b802792 --- /dev/null +++ b/x-pack/test/apm_api_integration/tests/fleet/input_only_package.spec.ts @@ -0,0 +1,236 @@ +/* + * 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 { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { ApmSynthtraceEsClient, createLogger, LogLevel } from '@kbn/apm-synthtrace'; +import expect from '@kbn/expect'; +import { createEsClientForFtrConfig } from '@kbn/test'; +import { ApmDocumentType } from '@kbn/apm-plugin/common/document_type'; +import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; +import { SecurityRoleDescriptor } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import pRetry from 'p-retry'; +import { FtrProviderContext } from '../../common/ftr_provider_context'; +import { getBettertest } from '../../common/bettertest'; +import { + createAgentPolicy, + createPackagePolicy, + deleteAgentPolicyAndPackagePolicyByName, + setupFleet, +} from './helpers'; +import { ApmApiClient } from '../../common/config'; + +export default function ApiTest(ftrProviderContext: FtrProviderContext) { + const { getService } = ftrProviderContext; + const registry = getService('registry'); + const apmApiClient = getService('apmApiClient'); + const supertest = getService('supertest'); + const es = getService('es'); + const log = getService('log'); + const bettertest = getBettertest(supertest); + const config = getService('config'); + const synthtraceKibanaClient = getService('synthtraceKibanaClient'); + const synthtraceEsClient = getService('synthtraceEsClient'); + + const API_KEY_NAME = 'apm_api_key_testing'; + const APM_AGENT_POLICY_NAME = 'apm_agent_policy_testing'; + const APM_PACKAGE_POLICY_NAME = 'apm_package_policy_testing'; + + function createEsClientWithApiKey({ id, apiKey }: { id: string; apiKey: string }) { + return createEsClientForFtrConfig(config, { auth: { apiKey: { id, api_key: apiKey } } }); + } + + function createEsClientWithToken(token: string) { + return createEsClientForFtrConfig(config, { auth: { bearer: token } }); + } + + async function getApiKeyForServiceAccount( + serviceAccount: string, + permissions: SecurityRoleDescriptor + ) { + const { token } = await es.security.createServiceToken({ + namespace: 'elastic', + service: serviceAccount, + }); + + const esClientScoped = createEsClientWithToken(token.value); + return esClientScoped.security.createApiKey({ + body: { + name: API_KEY_NAME, + role_descriptors: { + apmFleetPermissions: permissions, + }, + }, + }); + } + + async function getSynthtraceClientWithApiKey({ + id, + api_key: apiKey, + }: { + id: string; + api_key: string; + }) { + const esClient = createEsClientWithApiKey({ id, apiKey }); + const kibanaVersion = await synthtraceKibanaClient.fetchLatestApmPackageVersion(); + return new ApmSynthtraceEsClient({ + client: esClient, + logger: createLogger(LogLevel.info), + version: kibanaVersion, + refreshAfterIndex: true, + }); + } + + registry.when('APM package policy', { config: 'basic', archives: [] }, () => { + async function getAgentPolicyPermissions(agentPolicyId: string, packagePolicyId: string) { + const res = await bettertest<{ + item: { output_permissions: { default: Record } }; + }>({ + pathname: `/api/fleet/agent_policies/${agentPolicyId}/full`, + method: 'get', + }); + + return res.body.item.output_permissions.default[packagePolicyId]; + } + + describe('input only package', () => { + let agentPolicyId: string; + let packagePolicyId: string; + let permissions: SecurityRoleDescriptor; + + async function cleanAll() { + try { + await synthtraceEsClient.clean(); + await es.security.invalidateApiKey({ name: API_KEY_NAME }); + await deleteAgentPolicyAndPackagePolicyByName({ + bettertest, + agentPolicyName: APM_AGENT_POLICY_NAME, + packagePolicyName: APM_PACKAGE_POLICY_NAME, + }); + } catch (e) { + log.info('Nothing to clean'); + } + } + + before(async () => { + await cleanAll(); + + await setupFleet(bettertest); + agentPolicyId = await createAgentPolicy({ bettertest, name: APM_AGENT_POLICY_NAME }); + packagePolicyId = await createPackagePolicy({ + bettertest, + agentPolicyId, + name: APM_PACKAGE_POLICY_NAME, + }); + + permissions = await getAgentPolicyPermissions(agentPolicyId, packagePolicyId); + }); + + after(async () => { + await cleanAll(); + }); + + it('has permissions in the agent policy', async () => { + expect(permissions).to.eql({ + cluster: ['cluster:monitor/main'], + indices: [ + { + names: ['traces-*', 'logs-*', 'metrics-*'], + privileges: ['auto_configure', 'create_doc'], + }, + { + names: ['traces-apm.sampled-*'], + privileges: ['auto_configure', 'create_doc', 'maintenance', 'monitor', 'read'], + }, + ], + }); + }); + + describe('when ingesting events using the scoped api key', () => { + let scenario: ReturnType; + + before(async () => { + scenario = getSynthtraceScenario(); + + // get api key scoped to the specified permissions and created with the fleet-server service account. This ensures that the api key is not created with more permissions than fleet-server is able to. + const apiKey = await getApiKeyForServiceAccount('fleet-server', permissions); + + // create a synthtrace client scoped to the api key. This verifies that the api key has permissions to write to the APM indices. + const scopedSynthtraceEsClient = await getSynthtraceClientWithApiKey(apiKey); + await scopedSynthtraceEsClient.index(scenario.events); + }); + + it('the events can be seen on the Service Inventory Page', async () => { + const apmServices = await getApmServices(apmApiClient, scenario.start, scenario.end); + expect(apmServices[0].serviceName).to.be('opbeans-java'); + expect(apmServices[0].environments?.[0]).to.be('ingested-via-fleet'); + expect(apmServices[0].latency).to.be(2550000); + expect(apmServices[0].throughput).to.be(2); + expect(apmServices[0].transactionErrorRate).to.be(0.5); + }); + }); + }); + }); +} + +function getApmServices(apmApiClient: ApmApiClient, start: string, end: string) { + return pRetry(async () => { + const res = await apmApiClient.readUser({ + endpoint: 'GET /internal/apm/services', + params: { + query: { + start, + end, + probability: 1, + environment: 'ENVIRONMENT_ALL', + kuery: '', + documentType: ApmDocumentType.TransactionMetric, + rollupInterval: RollupInterval.OneMinute, + }, + }, + }); + + if (res.body.items.length === 0 || !res.body.items[0].latency) { + throw new Error(`Timed-out: No APM Services were found`); + } + + return res.body.items; + }); +} + +function getSynthtraceScenario() { + const start = new Date('2023-09-01T00:00:00.000Z').getTime(); + const end = new Date('2023-09-01T00:02:00.000Z').getTime(); + + const opbeansJava = apm + .service({ name: 'opbeans-java', environment: 'ingested-via-fleet', agentName: 'java' }) + .instance('instance'); + + const events = timerange(start, end) + .ratePerMinute(1) + .generator((timestamp) => { + return [ + opbeansJava + .transaction({ transactionName: 'tx-java' }) + .timestamp(timestamp) + .duration(5000) + .success(), + + opbeansJava + .transaction({ transactionName: 'tx-java' }) + .timestamp(timestamp) + .duration(100) + .failure() + .errors(opbeansJava.error({ message: 'some error' }).timestamp(timestamp + 50)), + ]; + }); + + return { + start: new Date(start).toISOString(), + end: new Date(end).toISOString(), + events, + }; +} diff --git a/x-pack/test/apm_api_integration/tests/fleet/migration_check.spec.ts b/x-pack/test/apm_api_integration/tests/fleet/migration_check.spec.ts index 1f89f65c536b9..74cf37c957d13 100644 --- a/x-pack/test/apm_api_integration/tests/fleet/migration_check.spec.ts +++ b/x-pack/test/apm_api_integration/tests/fleet/migration_check.spec.ts @@ -13,7 +13,7 @@ import { deleteAgentPolicy, deletePackagePolicy, setupFleet, -} from './apm_package_policy_setup'; +} from './helpers'; import { getBettertest } from '../../common/bettertest'; export default function ApiTest(ftrProviderContext: FtrProviderContext) { @@ -76,7 +76,7 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { }); describe('with Cloud agent policy', () => { before(async () => { - await createAgentPolicy(bettertest, 'policy-elastic-agent-on-cloud'); + await createAgentPolicy({ bettertest, id: 'policy-elastic-agent-on-cloud' }); }); after(async () => { await deleteAgentPolicy(bettertest, 'policy-elastic-agent-on-cloud'); @@ -92,7 +92,7 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { describe('has_cloud_apm_package_policy', () => { before(async () => { - await createAgentPolicy(bettertest, 'policy-elastic-agent-on-cloud'); + await createAgentPolicy({ bettertest, id: 'policy-elastic-agent-on-cloud' }); }); after(async () => { await deleteAgentPolicy(bettertest, 'policy-elastic-agent-on-cloud'); @@ -107,7 +107,11 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { }); describe('with Cloud APM package policy', () => { before(async () => { - await createPackagePolicy(bettertest, 'policy-elastic-agent-on-cloud', 'apm'); + await createPackagePolicy({ + bettertest, + agentPolicyId: 'policy-elastic-agent-on-cloud', + id: 'apm', + }); }); after(async () => { await deletePackagePolicy(bettertest, 'apm'); @@ -125,7 +129,7 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { describe('has_apm_integrations', () => { before(async () => { - await createAgentPolicy(bettertest, 'test-agent-policy'); + await createAgentPolicy({ bettertest, id: 'test-agent-policy' }); }); after(async () => { await deleteAgentPolicy(bettertest, 'test-agent-policy'); @@ -139,7 +143,11 @@ export default function ApiTest(ftrProviderContext: FtrProviderContext) { }); describe('with custom APM package policy', () => { before(async () => { - await createPackagePolicy(bettertest, 'test-agent-policy', 'test-apm-package-policy'); + await createPackagePolicy({ + bettertest, + agentPolicyId: 'test-agent-policy', + id: 'test-apm-package-policy', + }); }); after(async () => { await deletePackagePolicy(bettertest, 'test-apm-package-policy'); diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts index 94b023757bf19..ab0e0302e163d 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts @@ -55,14 +55,20 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider refresh: true, }), ]), - add: async (findingsMock: T[]) => { + add: async < + T extends { + '@timestamp'?: string; + } + >( + findingsMock: T[] + ) => { await Promise.all([ ...findingsMock.map((finding) => es.index({ index: FINDINGS_INDEX, body: { ...finding, - '@timestamp': new Date().toISOString(), + '@timestamp': finding['@timestamp'] ?? new Date().toISOString(), }, refresh: true, }) @@ -72,7 +78,7 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider index: FINDINGS_LATEST_INDEX, body: { ...finding, - '@timestamp': new Date().toISOString(), + '@timestamp': finding['@timestamp'] ?? new Date().toISOString(), }, refresh: true, }) @@ -81,6 +87,20 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider }, }; + const detectionRuleApi = { + remove: async () => { + await supertest + .post('/api/detection_engine/rules/_bulk_action?dry_run=false') + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .send({ + action: 'delete', + query: '', + }) + .expect(200); + }, + }; + const distributionBar = { filterBy: async (type: 'passed' | 'failed') => testSubjects.click(type === 'failed' ? 'distribution_bar_failed' : 'distribution_bar_passed'), @@ -203,6 +223,12 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider await nonStaleElement.click(); } }, + + async openFlyoutAt(rowIndex: number) { + const table = await this.getElement(); + const flyoutButton = await table.findAllByTestSubject('findings_table_expand_column'); + await flyoutButton[rowIndex].click(); + }, }); const navigateToLatestFindingsPage = async () => { @@ -247,6 +273,41 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider const notInstalledVulnerabilities = createNotInstalledObject('cnvm-integration-not-installed'); const notInstalledCSP = createNotInstalledObject('cloud_posture_page_package_not_installed'); + const createFlyoutObject = (tableTestSubject: string) => ({ + async getElement() { + return await testSubjects.find(tableTestSubject); + }, + async clickTakeActionButton() { + const element = await this.getElement(); + const button = await element.findByCssSelector('[data-test-subj="csp:take_action"] button'); + await button.click(); + return button; + }, + async clickTakeActionCreateRuleButton() { + await this.clickTakeActionButton(); + const button = await testSubjects.find('csp:create_rule'); + await button.click(); + return button; + }, + async getVisibleText(testSubj: string) { + const element = await this.getElement(); + return await (await element.findByTestSubject(testSubj)).getVisibleText(); + }, + }); + + const misconfigurationsFlyout = createFlyoutObject('findings_flyout'); + + const toastMessage = async (testSubj = 'csp:toast-success') => ({ + async getElement() { + return await testSubjects.find(testSubj); + }, + async clickToastMessageLink(linkTestSubj = 'csp:toast-success-link') { + const element = await this.getElement(); + const link = await element.findByTestSubject(linkTestSubj); + await link.click(); + }, + }); + return { navigateToLatestFindingsPage, navigateToVulnerabilities, @@ -259,5 +320,8 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider index, waitForPluginInitialized, distributionBar, + misconfigurationsFlyout, + toastMessage, + detectionRuleApi, }; } diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts b/x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts new file mode 100644 index 0000000000000..53f0b765165ef --- /dev/null +++ b/x-pack/test/cloud_security_posture_functional/pages/findings_alerts.ts @@ -0,0 +1,236 @@ +/* + * 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 Chance from 'chance'; +import type { FtrProviderContext } from '../ftr_provider_context'; + +// eslint-disable-next-line import/no-default-export +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const retry = getService('retry'); + const pageObjects = getPageObjects(['common', 'findings', 'header']); + const chance = new Chance(); + + // We need to use a dataset for the tests to run + const data = [ + { + resource: { id: chance.guid(), name: `kubelet`, sub_type: 'lower case sub type' }, + result: { evaluation: chance.integer() % 2 === 0 ? 'passed' : 'failed' }, + rule: { + tags: ['CIS', 'CIS K8S'], + rationale: 'rationale steps for rule 1.1', + references: '1. https://elastic.co/rules/1.1', + name: 'Upper case rule name', + section: 'Upper case section', + benchmark: { + rule_number: '1.1', + id: 'cis_k8s', + posture_type: 'kspm', + name: 'CIS Kubernetes V1.23', + version: 'v1.0.0', + remediation: 'remediation guide', + }, + type: 'process', + }, + cluster_id: 'Upper case cluster id', + }, + { + '@timestamp': '2023-09-10T14:01:00.000Z', + resource: { id: chance.guid(), name: `Pod`, sub_type: 'Upper case sub type' }, + result: { evaluation: chance.integer() % 2 === 0 ? 'passed' : 'failed' }, + rule: { + tags: ['CIS', 'CIS K8S'], + rationale: 'rationale steps', + references: '1. https://elastic.co', + name: 'lower case rule name', + section: 'Another upper case section', + benchmark: { + rule_number: '1.2', + id: 'cis_k8s', + posture_type: 'kspm', + name: 'CIS Kubernetes V1.23', + version: 'v1.0.0', + remediation: 'remediation guide', + }, + type: 'process', + }, + cluster_id: 'Another Upper case cluster id', + }, + { + '@timestamp': '2023-09-10T14:02:00.000Z', + resource: { id: chance.guid(), name: `process`, sub_type: 'another lower case type' }, + result: { evaluation: 'passed' }, + rule: { + tags: ['CIS', 'CIS K8S'], + rationale: 'rationale steps', + references: '1. https://elastic.co', + name: 'Another upper case rule name', + section: 'lower case section', + benchmark: { + rule_number: '1.3', + id: 'cis_k8s', + posture_type: 'kspm', + name: 'CIS Kubernetes V1.23', + version: 'v1.0.0', + remediation: 'remediation guide', + }, + type: 'process', + }, + cluster_id: 'lower case cluster id', + }, + { + '@timestamp': '2023-09-10T14:03:00.000Z', + resource: { id: chance.guid(), name: `process`, sub_type: 'Upper case type again' }, + result: { evaluation: 'failed' }, + rule: { + tags: ['CIS', 'CIS K8S'], + rationale: 'rationale steps', + references: '1. https://elastic.co', + name: 'some lower case rule name', + section: 'another lower case section', + benchmark: { + rule_number: '1.4', + id: 'cis_k8s', + posture_type: 'kspm', + name: 'CIS Kubernetes V1.23', + version: 'v1.0.0', + remediation: 'remediation guide', + }, + type: 'process', + }, + cluster_id: 'another lower case cluster id', + }, + ]; + + const ruleName1 = data[0].rule.name; + + describe('Findings Page - Alerts', function () { + this.tags(['cloud_security_posture_findings_alerts']); + let findings: typeof pageObjects.findings; + let latestFindingsTable: typeof findings.latestFindingsTable; + let misconfigurationsFlyout: typeof findings.misconfigurationsFlyout; + + before(async () => { + findings = pageObjects.findings; + latestFindingsTable = findings.latestFindingsTable; + misconfigurationsFlyout = findings.misconfigurationsFlyout; + // Before we start any test we must wait for cloud_security_posture plugin to complete its initialization + await findings.waitForPluginInitialized(); + // Prepare mocked findings + await findings.index.remove(); + await findings.index.add(data); + }); + + after(async () => { + await findings.index.remove(); + await findings.detectionRuleApi.remove(); + }); + + beforeEach(async () => { + await findings.detectionRuleApi.remove(); + await findings.navigateToLatestFindingsPage(); + await retry.waitFor( + 'Findings table to be loaded', + async () => (await latestFindingsTable.getRowsCount()) === data.length + ); + pageObjects.header.waitUntilLoadingHasFinished(); + }); + + describe('Create detection rule', () => { + it('Creates a detection rule from the Take Action button and navigates to rule page', async () => { + await latestFindingsTable.openFlyoutAt(0); + await misconfigurationsFlyout.clickTakeActionCreateRuleButton(); + + expect( + await misconfigurationsFlyout.getVisibleText('csp:findings-flyout-alert-count') + ).to.be('0 alerts'); + + expect( + await misconfigurationsFlyout.getVisibleText('csp:findings-flyout-detection-rule-count') + ).to.be('1 detection rule'); + + const toastMessage = await (await findings.toastMessage()).getElement(); + expect(toastMessage).to.be.ok(); + + const toastMessageTitle = await toastMessage.findByTestSubject('csp:toast-success-title'); + expect(await toastMessageTitle.getVisibleText()).to.be(ruleName1); + + await (await findings.toastMessage()).clickToastMessageLink(); + + const rulePageTitle = await testSubjects.find('header-page-title'); + expect(await rulePageTitle.getVisibleText()).to.be(ruleName1); + }); + it('Creates a detection rule from the Alerts section and navigates to rule page', async () => { + await latestFindingsTable.openFlyoutAt(0); + const flyout = await misconfigurationsFlyout.getElement(); + + await ( + await flyout.findByTestSubject('csp:findings-flyout-create-detection-rule-link') + ).click(); + + expect( + await misconfigurationsFlyout.getVisibleText('csp:findings-flyout-alert-count') + ).to.be('0 alerts'); + + expect( + await misconfigurationsFlyout.getVisibleText('csp:findings-flyout-detection-rule-count') + ).to.be('1 detection rule'); + + const toastMessage = await (await findings.toastMessage()).getElement(); + expect(toastMessage).to.be.ok(); + + const toastMessageTitle = await toastMessage.findByTestSubject('csp:toast-success-title'); + expect(await toastMessageTitle.getVisibleText()).to.be(ruleName1); + + await (await findings.toastMessage()).clickToastMessageLink(); + + const rulePageTitle = await testSubjects.find('header-page-title'); + expect(await rulePageTitle.getVisibleText()).to.be(ruleName1); + }); + }); + describe('Rule details', () => { + it('The rule page contains the expected matching data', async () => { + await latestFindingsTable.openFlyoutAt(0); + await misconfigurationsFlyout.clickTakeActionCreateRuleButton(); + + await (await findings.toastMessage()).clickToastMessageLink(); + + const rulePageDescription = await testSubjects.find( + 'stepAboutRuleDetailsToggleDescriptionText' + ); + expect(await rulePageDescription.getVisibleText()).to.be(data[0].rule.rationale); + + const severity = await testSubjects.find('severity'); + expect(await severity.getVisibleText()).to.be('Low'); + + const referenceUrls = await testSubjects.find('urlsDescriptionReferenceLinkItem'); + expect(await referenceUrls.getVisibleText()).to.contain('https://elastic.co/rules/1.1'); + }); + }); + describe('Navigation', () => { + it('Clicking on count of Rules should navigate to the rules page with benchmark tags as a filter', async () => { + await latestFindingsTable.openFlyoutAt(0); + await misconfigurationsFlyout.clickTakeActionCreateRuleButton(); + const flyout = await misconfigurationsFlyout.getElement(); + await (await flyout.findByTestSubject('csp:findings-flyout-detection-rule-count')).click(); + + expect(await (await testSubjects.find('ruleName')).getVisibleText()).to.be(ruleName1); + }); + it('Clicking on count of Alerts should navigate to the alerts page', async () => { + await latestFindingsTable.openFlyoutAt(0); + await misconfigurationsFlyout.clickTakeActionCreateRuleButton(); + const flyout = await misconfigurationsFlyout.getElement(); + await (await flyout.findByTestSubject('csp:findings-flyout-alert-count')).click(); + + expect(await (await testSubjects.find('header-page-title')).getVisibleText()).to.be( + 'Alerts' + ); + }); + }); + }); +} diff --git a/x-pack/test/cloud_security_posture_functional/pages/index.ts b/x-pack/test/cloud_security_posture_functional/pages/index.ts index 1d30a3b27fda9..81e905ddaca35 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/index.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/index.ts @@ -12,6 +12,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('Cloud Security Posture', function () { loadTestFile(require.resolve('./findings_onboarding')); loadTestFile(require.resolve('./findings')); + loadTestFile(require.resolve('./findings_alerts')); loadTestFile(require.resolve('./compliance_dashboard')); }); } diff --git a/x-pack/test/functional/apps/dashboard/group2/panel_time_range.ts b/x-pack/test/functional/apps/dashboard/group2/panel_time_range.ts index bbf5877f80327..e68d1ebc60953 100644 --- a/x-pack/test/functional/apps/dashboard/group2/panel_time_range.ts +++ b/x-pack/test/functional/apps/dashboard/group2/panel_time_range.ts @@ -44,8 +44,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('can add a custom time range to a panel', async () => { await PageObjects.lens.createAndAddLensFromDashboard({}); await dashboardPanelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); - await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.enableCustomTimeRange(); + await dashboardCustomizePanel.openDatePickerQuickMenu(); await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days'); await dashboardCustomizePanel.clickSaveButton(); await PageObjects.dashboard.waitForRenderComplete(); @@ -56,7 +56,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('can remove a custom time range from a panel', async () => { await dashboardBadgeActions.clickTimeRangeBadgeAction(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); + await dashboardCustomizePanel.disableCustomTimeRange(); await dashboardCustomizePanel.clickSaveButton(); await PageObjects.dashboard.waitForRenderComplete(); await dashboardBadgeActions.expectMissingTimeRangeBadgeAction(); @@ -68,8 +68,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('can add a custom time range to panel', async () => { await dashboardPanelActions.saveToLibrary('My by reference visualization'); await dashboardPanelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); - await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.enableCustomTimeRange(); + await dashboardCustomizePanel.openDatePickerQuickMenu(); await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days'); await dashboardCustomizePanel.clickSaveButton(); await PageObjects.dashboard.waitForRenderComplete(); @@ -80,7 +80,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('can remove a custom time range from a panel', async () => { await dashboardBadgeActions.clickTimeRangeBadgeAction(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); + await dashboardCustomizePanel.disableCustomTimeRange(); await dashboardCustomizePanel.clickSaveButton(); await PageObjects.dashboard.waitForRenderComplete(); await dashboardBadgeActions.expectMissingTimeRangeBadgeAction(); diff --git a/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts b/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts index ed504f3711565..ccf738af3825d 100644 --- a/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts +++ b/x-pack/test/functional/apps/dashboard/group3/drilldowns/explore_data_panel_action.ts @@ -46,7 +46,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboard.gotoDashboardEditMode(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); await panelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); + await dashboardCustomizePanel.disableCustomTimeRange(); await dashboardCustomizePanel.clickSaveButton(); await dashboard.saveDashboard('Dashboard with Pie Chart'); }); @@ -80,8 +80,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dashboard.gotoDashboardEditMode(drilldowns.DASHBOARD_WITH_PIE_CHART_NAME); await panelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); - await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.enableCustomTimeRange(); + await dashboardCustomizePanel.openDatePickerQuickMenu(); await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_90 days'); await dashboardCustomizePanel.clickSaveButton(); diff --git a/x-pack/test/functional/apps/discover/saved_searches.ts b/x-pack/test/functional/apps/discover/saved_searches.ts index 85a4d91eabc3c..8f5fe5dc9bc11 100644 --- a/x-pack/test/functional/apps/discover/saved_searches.ts +++ b/x-pack/test/functional/apps/discover/saved_searches.ts @@ -45,8 +45,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.common.unsetTime(); }); - // FLAKY: https://github.com/elastic/kibana/issues/104578 - describe.skip('Customize time range', () => { + describe('Customize time range', () => { it('should be possible to customize time range for saved searches on dashboards', async () => { await PageObjects.dashboard.navigateToApp(); await PageObjects.dashboard.clickNewDashboard(); @@ -55,8 +54,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(await dataGrid.getDocCount()).to.be(500); await panelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); - await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.enableCustomTimeRange(); + await dashboardCustomizePanel.openDatePickerQuickMenu(); await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_90 days'); await dashboardCustomizePanel.clickSaveButton(); diff --git a/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts b/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts index b6acfcf64a750..9232860012bc9 100644 --- a/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts +++ b/x-pack/test/functional/apps/lens/open_in_lens/tsvb/dashboard.ts @@ -42,8 +42,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await dashboard.waitForRenderComplete(); const originalEmbeddableCount = await canvas.getEmbeddableCount(); await dashboardPanelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); - await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.enableCustomTimeRange(); + await dashboardCustomizePanel.openDatePickerQuickMenu(); await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days'); await dashboardCustomizePanel.clickSaveButton(); await dashboard.waitForRenderComplete(); @@ -80,8 +80,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await dashboard.waitForRenderComplete(); const originalEmbeddableCount = await canvas.getEmbeddableCount(); await dashboardPanelActions.customizePanel(); - await dashboardCustomizePanel.clickToggleShowCustomTimeRange(); - await dashboardCustomizePanel.clickToggleQuickMenuButton(); + await dashboardCustomizePanel.enableCustomTimeRange(); + await dashboardCustomizePanel.openDatePickerQuickMenu(); await dashboardCustomizePanel.clickCommonlyUsedTimeRange('Last_30 days'); await dashboardCustomizePanel.clickSaveButton(); await dashboard.waitForRenderComplete(); diff --git a/x-pack/test/functional/apps/uptime/overview.ts b/x-pack/test/functional/apps/uptime/overview.ts index afe19a1ae1938..81e5795533b69 100644 --- a/x-pack/test/functional/apps/uptime/overview.ts +++ b/x-pack/test/functional/apps/uptime/overview.ts @@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export const UPTIME_HEARTBEAT_DATA = 'x-pack/test/functional/es_archives/uptime/full_heartbeat'; export default ({ getPageObjects, getService }: FtrProviderContext) => { - const { uptime } = getPageObjects(['uptime']); + const { uptime, common } = getPageObjects(['uptime', 'common']); const retry = getService('retry'); const esArchiver = getService('esArchiver'); @@ -104,7 +104,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); await uptime.setMonitorListPageSize(50); // the pagination parameter should be cleared after a size change - await new Promise((resolve) => setTimeout(resolve, 1000)); + await common.sleep(1000); await retry.try(async () => { await uptime.pageUrlContains('pagination', false); }); diff --git a/x-pack/test/functional/page_objects/navigational_search.ts b/x-pack/test/functional/page_objects/navigational_search.ts index 46fed2814c0df..ae27d6d68a4a5 100644 --- a/x-pack/test/functional/page_objects/navigational_search.ts +++ b/x-pack/test/functional/page_objects/navigational_search.ts @@ -12,11 +12,10 @@ interface SearchResult { label: string; } -const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); - export class NavigationalSearchPageObject extends FtrService { private readonly find = this.ctx.getService('find'); private readonly testSubjects = this.ctx.getService('testSubjects'); + private readonly common = this.ctx.getPageObject('common'); async focus() { const field = await this.testSubjects.find('nav-search-input'); @@ -69,7 +68,7 @@ export class NavigationalSearchPageObject extends FtrService { // without heavy flakiness in this situation. // there is NO ui indication of any kind to detect when all the emissions are done, // so we are forced to fallback to awaiting a given amount of time once the first options are displayed. - await delay(waitUntil); + await this.common.sleep(waitUntil); } async getDisplayedResults() { @@ -79,7 +78,7 @@ export class NavigationalSearchPageObject extends FtrService { async isNoResultsPlaceholderDisplayed(checkAfter: number = 3000) { // see comment in `waitForResultsLoaded` - await delay(checkAfter); + await this.common.sleep(checkAfter); return this.testSubjects.exists('nav-search-no-results'); } diff --git a/x-pack/test/functional/services/cases/single_case_view.ts b/x-pack/test/functional/services/cases/single_case_view.ts index 008f89c5b3ee8..27877f592d5dc 100644 --- a/x-pack/test/functional/services/cases/single_case_view.ts +++ b/x-pack/test/functional/services/cases/single_case_view.ts @@ -106,7 +106,7 @@ export function CasesSingleViewServiceProvider({ getService, getPageObject }: Ft '[data-test-subj="euiMarkdownEditorToolbarButton"][aria-label="Visualization"]' ); await addVisualizationButton.moveMouseTo(); - await new Promise((resolve) => setTimeout(resolve, 500)); // give tooltip time to open + await common.sleep(500); // give tooltip time to open }, async assertCaseTitle(expectedTitle: string) { diff --git a/x-pack/test/functional/services/data_stream.ts b/x-pack/test/functional/services/data_stream.ts index 13cc8547b5677..2864be1e0dc2b 100644 --- a/x-pack/test/functional/services/data_stream.ts +++ b/x-pack/test/functional/services/data_stream.ts @@ -8,15 +8,14 @@ import type { MappingProperty } from '@elastic/elasticsearch/lib/api/types'; import type { FtrProviderContext } from '../ftr_provider_context'; -const waitFor = (time: number = 1000) => new Promise((r) => setTimeout(r, time)); - /** * High level interface to operate with Elasticsearch data stream and TSDS. */ -export function DataStreamProvider({ getService }: FtrProviderContext) { +export function DataStreamProvider({ getService, getPageObject }: FtrProviderContext) { const es = getService('es'); const log = getService('log'); const retry = getService('retry'); + const common = getPageObject('common'); const downsampleDefaultOptions = { isStream: true, @@ -65,7 +64,7 @@ export function DataStreamProvider({ getService }: FtrProviderContext) { waitTime / 1000 }s before running the downsampling to avoid a null_pointer_exception` ); - await waitFor(waitTime); + await common.sleep(waitTime); try { log.info(`downsampling "${sourceIndex}" index...`); diff --git a/x-pack/test/functional/services/infra_source_configuration_form.ts b/x-pack/test/functional/services/infra_source_configuration_form.ts index 3f77991ba5041..741d42ac16fda 100644 --- a/x-pack/test/functional/services/infra_source_configuration_form.ts +++ b/x-pack/test/functional/services/infra_source_configuration_form.ts @@ -8,10 +8,14 @@ import { FtrProviderContext } from '../ftr_provider_context'; import { WebElementWrapper } from '../../../../test/functional/services/lib/web_element_wrapper'; -export function InfraSourceConfigurationFormProvider({ getService }: FtrProviderContext) { +export function InfraSourceConfigurationFormProvider({ + getService, + getPageObject, +}: FtrProviderContext) { const retry = getService('retry'); const testSubjects = getService('testSubjects'); const browser = getService('browser'); + const common = getPageObject('common'); return { /** @@ -94,7 +98,7 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider const movementDifference = destinationIndex - sourceIndex; await moveLogColumnHandle.pressKeys(browser.keys.SPACE); for (let i = 0; i < Math.abs(movementDifference); i++) { - await new Promise((res) => setTimeout(res, KEY_PRESS_DELAY_MS)); + await common.sleep(KEY_PRESS_DELAY_MS); if (movementDifference > 0) { await moveLogColumnHandle.pressKeys(browser.keys.ARROW_DOWN); } else { @@ -102,7 +106,7 @@ export function InfraSourceConfigurationFormProvider({ getService }: FtrProvider } } await moveLogColumnHandle.pressKeys(browser.keys.SPACE); - await new Promise((res) => setTimeout(res, KEY_PRESS_DELAY_MS)); + await common.sleep(KEY_PRESS_DELAY_MS); }, /** diff --git a/x-pack/test/functional/services/uptime/navigation.ts b/x-pack/test/functional/services/uptime/navigation.ts index 57e39f6bf9d0e..8a3898e813c6a 100644 --- a/x-pack/test/functional/services/uptime/navigation.ts +++ b/x-pack/test/functional/services/uptime/navigation.ts @@ -32,7 +32,7 @@ export function UptimeNavigationProvider({ getService, getPageObjects }: FtrProv return { async refreshApp() { await browser.refresh(); - await new Promise((resolve) => setTimeout(resolve, 1000)); + await PageObjects.common.sleep(1000); await PageObjects.header.waitUntilLoadingHasFinished(); }, diff --git a/x-pack/test/profiling_api_integration/tests/has_setup.spec.ts b/x-pack/test/profiling_api_integration/tests/has_setup.spec.ts index 5046eb8c9c556..583cc02908025 100644 --- a/x-pack/test/profiling_api_integration/tests/has_setup.spec.ts +++ b/x-pack/test/profiling_api_integration/tests/has_setup.spec.ts @@ -23,9 +23,9 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const logger = getService('log'); const es = getService('es'); - registry.when('Profiling status check', { config: 'cloud' }, () => { - // Failing: See https://github.com/elastic/kibana/issues/167076 - describe.skip('Profiling is not set up and no data is loaded', () => { + // Failing: See https://github.com/elastic/kibana/issues/167076 + registry.when.skip('Profiling status check', { config: 'cloud' }, () => { + describe('Profiling is not set up and no data is loaded', () => { describe('Admin user', () => { let statusCheck: ProfilingStatus; before(async () => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/search_filter.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/search_filter.cy.ts index afedab5dbb094..c48fa80baad46 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/search_filter.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/discover/search_filter.cy.ts @@ -38,7 +38,8 @@ const INITIAL_START_DATE = 'Jan 18, 2021 @ 20:33:29.186'; const INITIAL_END_DATE = 'Jan 19, 2024 @ 20:33:29.186'; const NEW_START_DATE = 'Jan 18, 2023 @ 20:33:29.186'; -describe( +// Failing: See https://github.com/elastic/kibana/issues/167186 +describe.skip( 'Basic discover search and filter operations', { env: { ftrConfig: { enableExperimental: ['discoverInTimeline'] } }, diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts index b92a26e785127..c4778f7039a91 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/metadata.ts @@ -43,7 +43,8 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const endpointTestResources = getService('endpointTestResources'); - describe('test metadata apis', () => { + // Failing: See https://github.com/elastic/kibana/issues/151854 + describe.skip('test metadata apis', () => { describe('list endpoints GET route', () => { const numberOfHostsInFixture = 2; let agent1Timestamp: number; diff --git a/x-pack/test_serverless/functional/test_suites/search/dashboards/import_dashboard.ts b/x-pack/test_serverless/functional/test_suites/search/dashboards/import_dashboard.ts index c935ab3f15f83..30d99d112e640 100644 --- a/x-pack/test_serverless/functional/test_suites/search/dashboards/import_dashboard.ts +++ b/x-pack/test_serverless/functional/test_suites/search/dashboards/import_dashboard.ts @@ -27,8 +27,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'svlCommonPage', ]); - // Failing: See https://github.com/elastic/kibana/issues/166573 - describe.skip('Importing an existing dashboard', () => { + describe('Importing an existing dashboard', () => { before(async () => { await PageObjects.svlCommonPage.login(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); diff --git a/yarn.lock b/yarn.lock index 83eb6e673dc60..84df6498ff250 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5087,6 +5087,10 @@ version "0.0.0" uid "" +"@kbn/openapi-generator@link:packages/kbn-openapi-generator": + version "0.0.0" + uid "" + "@kbn/optimizer-webpack-helpers@link:packages/kbn-optimizer-webpack-helpers": version "0.0.0" uid ""